WAR-based deployment of workflow applications - PoC #2 (using ONAP and SO)
Building SO docker images locally
based on: https://lf-onap.atlassian.net/wiki/display/DW/Building+SO
so] mvn clean install -DskipTests=true -Dmaven.test.skip=true -Dcheckstyle.skip
packages] mvn -DskipTests install -P docker -Dmso.chef.git.url.prefix=ssh://user@gerrit.onap.org:29418 -Dmso.chef.git.branchname=dublin -Dmso.chef.git.url.suffix.chef.repo=so/chef-repo -Dmso.chef.git.url.suffix.chef.config=so/so-config -Ddocker.buildArg.http_proxy=<PROXY> -Ddocker.buildArg.https_proxy=<PROXY>
Accessing Camunda SO Cockpit on lab
(based on: https://lf-onap.atlassian.net/wiki/display/DW/Camunda+custom+workflows)
So port needs to be exposed:
rke-node:~$ kubectl -n onap expose deployment dev-so-so-bpmn-infra --type NodePort --name dev-so-so-bpmn-infra-expose
rke-node:~$ kubectl get services --all-namespaces | grep bpmn-infra
onap dev-so-so-bpmn-infra-expose NodePort 10.43.93.167 <none> 8081:32500/TCP 4m9s
onap so-bpmn-infra ClusterIP 10.43.207.122 <none> 8081/TCP 67d
now using newly exposed port we can access camunda cockpit app on lab. default credentials are admin/admin
General issues
no guaranttes that all required so functionalities / use cases are covered by test -> High risk of breaking features / requirements we are not aware of
Integration of spring boot and camunda is not trivial - issue with settin up proper application context
Building docker image with Camunda running on standalone tomcat
on hold - there is an official camunda docker image that can be used for initial tests
Running SO BPMN infra on standalone camunda
docker run --rm --name camunda -p 8080:8080 -v /home/grabinsk/dev/onap/so/bpmn/mso-infrastructure-bpmn/target/mso-infrastructure-bpmn-1.4.0-SNAPSHOT.war:/camunda/webapps/mso.war:z camunda/camunda-bpm-platform:7.10.0
Changing mso-infrastructure-bpmn into war
Things that needs to be done / seems needed
change packaging to war
set 'failOnMissingWebXml' to false on maven-war-plugin (unless we want to play with adding web.xml)
update groovy verison to 2.4.13 (in onap/so/bpmn/pom.xml)
change tomcat dependency (spring-boot-starter-tomcat) scope to 'provided'
change scope of camunda-engine and camunda-engine-plugin-spin to 'provided' (also in so-bpmn-infrasturcture-common nad so-bpmn-infrastructure-flows)
remove camunda starters dependencies (camunda-bpm-spring-boot-starter-rest, camunda-bpm-spring-boot-starter-webapp)
add camunda-engine-spring dependency
add META-INF/process.xml
processes.xml
<?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>
add camunda config
CamundaConfig.java
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(); } }
configure maven 'unpack' plugin to extract content of jars containing bpmn workflow defnitions (so-bpmn-infrastructure-flows, so-bpmn-building-blocks, MSOCommonBPMN?) and tasks (so-bpmn-tasks) since camunda does not look into libs
fill all properties in application.yaml with values from lab, or some dummy data so (get rid of props related to camunda db access - proper db setup for camunda persistance shall be configured using camunda docker image own properties)
patch file with changes applied on top of dublin release: https://gerrit.onap.org/r/c/so/+/101907
can be build with:
mvn clean install -DskipTests=true -Dmaven.test.skip=true -Dcheckstyle.skip
(2 out of 20 tests in mso-infrastructure-bpmn started to fail - needs checking)
Deploying and testing on Lab
change mso-bpmn-infra deployment ( kubectl edit deployment -n onap dev-so-so-bpmn-infra )
image: camunda/camunda-bpm-platform:7.10.0
containerPort: 8080 #originally it was 8081, but we can not change that in camunda image → we will need to update that in so-bpmn-infra service definition
in "volumeMounts:" add
- mountPath: /camunda/webapps name: webapps
in "volumes:" add
- hostPath: path: /dockerdata-nfs/webapps type: "" name: webapps
livenessProbe section causes that bpmn pod restarts every 10 min (this is for further investigation). Delete the following:
livenessProbe:
failureThreshold: 3
httpGet:
path: /manage/health
port: 8081
scheme: HTTP
initialDelaySeconds: 600
periodSeconds: 60
successThreshold: 1
timeoutSeconds: 10
create 'webapps' in /dockerdata-nfs, add writeaccess for everybody to webapps dir (tomcat will want to extract war in that location)
copy the mso.war to /dockerdata-nfs/webapps (war file name must be 'mso' since it will appear in URL's of exposed services)
change target port of so-bpmn-infra to 8080 ( kubectl -n onap edit service so-bpmn-infra ))
Adding ONAP CA certificate
Some workflow tasks communicate with external services (like AAI) and need to validate that service certificate authenticity.
Original setup:
there is some default onap-ca.crt that is copied and preinstalled in base so docker image
the image allows providing additional certificates mounted as volume, but the pod definition does not make use of that possibility → the hardcoded cert is in use
system-wide ca cert installation requires root priviledges and the original mso-bpmn-infra app is running as root.
For the POC purpose onap-ca.crt is preinstalled in the image
Dockerfile
FROM camunda/camunda-bpm-platform:7.10.0
RUN rm -r /camunda/webapps/examples /camunda/webapps/docs /camunda/webapps/camunda-invoice
USER root
COPY ca-certificates/onap-ca.crt /usr/local/share/ca-certificates/onap-ca.crt
RUN update-ca-certificates --fresh
USER camunda
# Springboot configuration (required)
VOLUME /camunda/app/config
COPY maven/app.war /camunda/webapps/mso.war
it needst to be further analized how to provide possibility to update the cert without the need to use root account
Patch set on top of dublin including building cammunda-based so-bpmn-infra image with hardcoded onap-ca.crt: https://gerrit.onap.org/r/c/so/+/101907
Logging
Current POC implementation is not using origianl onap - style logback logging config that stores application logs in some files
All logging is output to system out → one can use standard kubectl -n onap logs dev-so-so-bpmn-infra-77cbf89bd7-krdrw commands to see camunda starup logs as well as application logs.
By since no logging level is explicitly configured for mso.war if visibility of debug logs is desired one can configure it by adding logging.level.org.onap: debug into so-bpmn-infra configmap:
kubectl -n onap edit configmap dev-so-so-bpmn-infra-app-configmap
Adding custom workflow application
The goal is to demonstrate that it could be possible to modularize SO into multiple war files so that they can be independently updated without a need to rebuild full so-bpmn-infra docker image.
In reality extracting any self contained workflow module from SO is challanging.
Therefore for the purpose of this POC a war with simple SO BuildingBlock style workflow is created. The workflow consists of single task that delegates execution to a simple Spring bean that performs some logging.
The test workflow application is created here:
The foo.war can be produced by simple 'mvn package' execution.
Deploying foo.war
Deploying foo.war is done by copying it to onap lab and moving to /dockerdata-nfs/webapps directory that is mounted as /cammunda/webaps inside so-bpmn-infra container.
sudo cp foo.war /dockerdata-nfs/webapps/foo.war
When succeded a similar log output should be found in so container:
foo deployment log
07-Nov-2019 10:28:40.714 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/camunda/webapps/foo.war]
07-Nov-2019 10:28:40.716 INFO [main] org.apache.catalina.startup.ExpandWar.expand An expanded directory [/camunda/webapps/foo] was found with a last modified time that did not match the associated WAR. It will be deleted.
07-Nov-2019 10:28:48.549 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/camunda/lib/slf4j-jdk14-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/camunda/webapps/foo/WEB-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.8.RELEASE)
2019-11-07 10:28:49.407 INFO 6 --- [ main] org.onap.so.foo.Application : Starting Application on dev-so-so-bpmn-infra-77cbf89bd7-6pkzj with PID 6 (/camunda/webapps/foo/WEB-INF/classes started by camunda in /camunda)
2019-11-07 10:28:49.411 INFO 6 --- [ main] org.onap.so.foo.Application : No active profile set, falling back to default profiles: default
2019-11-07 10:28:50.500 INFO 6 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 874 ms
2019-11-07 10:28:51.249 INFO 6 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
07-Nov-2019 10:28:51.991 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo ENGINE-08024 Found processes.xml file at file:/camunda/webapps/foo/WEB-INF/classes/META-INF/processes.xml
07-Nov-2019 10:28:52.001 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo ENGINE-08023 Deployment summary for process archive 'foo-process-archive':
FooBB.bpmn
07-Nov-2019 10:28:52.015 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo ENGINE-07021 ProcessApplication 'processApplication' registered for DB deployments [6496b53e-0149-11ea-b5e9-d256bb3982b8]. Will execute process definitions
FooBB[version: 1, id: FooBB:1:649814d0-0149-11ea-b5e9-d256bb3982b8]
Deployment does not provide any case definitions.
07-Nov-2019 10:28:52.019 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo SPIN-01010 Discovered Spin data format provider: org.camunda.spin.impl.json.jackson.format.JacksonJsonDataFormatProvider[name = application/json]
07-Nov-2019 10:28:52.020 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo SPIN-01010 Discovered Spin data format provider: org.camunda.spin.impl.xml.dom.format.DomXmlDataFormatProvider[name = application/xml]
07-Nov-2019 10:28:52.021 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo SPIN-01009 Discovered Spin data format: org.camunda.spin.impl.xml.dom.format.DomXmlDataFormat[name = application/xml]
07-Nov-2019 10:28:52.021 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo SPIN-01009 Discovered Spin data format: org.camunda.spin.impl.json.jackson.format.JacksonJsonDataFormat[name = application/json]
07-Nov-2019 10:28:52.022 INFO [main] org.camunda.commons.logging.BaseLogger.logInfo ENGINE-08050 Process application processApplication successfully deployed
2019-11-07 10:28:52.028 INFO 6 --- [ main] org.onap.so.foo.Application : Started Application in 3.302 seconds (JVM running for 52.781)
07-Nov-2019 10:28:52.043 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/camunda/webapps/foo.war] has finished in [11,330] ms
Including FooBB in some existing workflow
Inclusion FooBB in Service-Macro-Create workflow can be done by putting a few new entries into database tables used by catalog-db service.
INSERT INTO orchestration_flow_reference
(COMPOSITE_ACTION, SEQ_NO, FLOW_NAME, FLOW_VERSION, NB_REQ_REF_LOOKUP_ID)
VALUES('Service-Macro-Create', 20, 'FooBB', 1, 101);
INSERT INTO building_block_detail
(BUILDING_BLOCK_NAME, RESOURCE_TYPE, TARGET_ACTION)
VALUES('FooBB', 'SERVICE', 'CUSTOM');
INSERT INTO orchestration_status_state_transition_directive
(RESOURCE_TYPE, ORCHESTRATION_STATUS, TARGET_ACTION, FLOW_DIRECTIVE)
VALUES('SERVICE', 'ACTIVE', 'CUSTOM', 'CONTINUE');
Running modified Service-Macro-Create workflow
Start the macro create service workflow from VID.
It should also be possible to see the log entries produced during Foo java delegate execution
log entries produced by Foo task implementation deployed as separate war
2019-11-07 12:32:48.656 INFO 6 --- [pool-2-thread-1] org.onap.so.foo.Foo : _________________________________________________ FOO !!!
2019-11-07 12:32:48.656 INFO 6 --- [pool-2-thread-1] org.onap.so.foo.Foo : variable: `gBuildingBlockExecution`: org.onap.so.bpmn.common.DelegateExecutionImpl@3cbbf5bb
2019-11-07 12:32:48.656 INFO 6 --- [pool-2-thread-1] org.onap.so.foo.Foo : variable: `mso-request-id`: a9b386b2-8abe-4407-b4d7-fa9959e4c251