Decoupling ACM-R from Policy Framework

Decoupling ACM-R from Policy Framework

Background

Currently, developing, building & releasing ACM as a standalone component directly requires maintenance & delivery of five Policy repos:

  • policy/parent - integration POM used by all components including ACM

  • policy/common - kafka client code & utilities used in ACM

  • policy/models - Tosca model

  • policy/clamp - ACM source code and docker images

  • policy/docker - docker-compose, helm charts & CSITs

Indirectly e.g. through CSITs, the remaining 8 policy repos are depended on, e.g. api, pap, pdps.

This can cause delays in the development & delivery of ACM. For example, if a dependency uplift is needed for ACM, currently it is uplifted in the parent POM. An uplift could break another component like Apex PDP, which would lead to test failures in the CSITs for ACM. Additionally, CSITs for ACM are hosted in the docker repo, meaning CSITs do not run on every code commit - only for changes made in the docker repo. This has led to delays caused by late discovery of test failures.

In addition, many unneeded dependencies are included. Inspecting maven dependency tree for ACM Runtime shows dependencies on jetty, jersey & jaxb introduced from policy-common-endpoints, while ACM-R uses Spring Boot with Tomcat as the HTTP server.

In order to minimize delays in development of ACM, it is proposed to decouple ACM from the rest of the Policy Framework, allowing end-to-end development, testing, and delivery using only a single repo (policy/clamp).

The decoupling will enable further improvements, such as dependency auto-uplift, which is currently not feasible in multi-repo setup.

Analysis of Dependencies & Proposed Changes

The following table shows each Policy Framework dependency used by ACM (clamp repo), what they currently used for, proposed changes, and risk of breakage. Note the changes are largely independent and can be worked on in parallel, and in any order.

Purpose

Repo

Dependency Packages

Proposed Change

Cost

Time

Risk

Jira

Purpose

Repo

Dependency Packages

Proposed Change

Cost

Time

Risk

Jira

1

Dependency Management

parent

org.onap.policy.parent.integration:pom

Integrate dependencies to clamp pom, may also need plugin configs, checkstyle, jacoco, etc.

M

1 Week

Medium

https://lf-onap.atlassian.net/browse/POLICY-5521

2

Exception Class Definitions

models

org.onap.policy.models.errors.concepts.*

Copy the classes to clamp.

XS

Hours

None

https://lf-onap.atlassian.net/browse/POLICY-5519

3

Exception Base

models

org.onap.policy.models.base.PfModelException
PfModelRuntimeException

Copy to clamp preserving package structure.

XS

Hours

High*

https://lf-onap.atlassian.net/browse/POLICY-5519

4

TOSCA Support

models

org.onap.policy.models.tosca.*

Copy to clamp preserving package structure.

S

1 Day

High *

https://lf-onap.atlassian.net/browse/POLICY-5519

5

Policy Participant (PDP Dependency)

models

org.onap.policy.models.pdp.concepts.*

Classes are simple DTOs, can be copied.

XS

Hours

None

https://lf-onap.atlassian.net/browse/POLICY-5498

6

JPA Model

models

org.onap.policy.models.base.PfAuthorative
PfKey, PfNameVersion, etc.

Note: Overlaps with Bean Validation. Recommend copying some classes like PfAuthoratative to clamp, while replacing some usages with Bean Validation.

M

1 Week

Medium

https://lf-onap.atlassian.net/browse/POLICY-5519

7

YAML Support

common

org.onap.policy.common.spring.utils.YamlHttpMessageConverter

Copy the class to clamp.

XS

Hours

None

https://lf-onap.atlassian.net/browse/POLICY-5520

8

TOSCA Template (Examples Module)

common

org.onap.policy.common.gson.InstantAsMillisTypeAdapter

Copy the class to clamp.

XS

Hours

None

https://lf-onap.atlassian.net/browse/POLICY-5520

9

Test Utility: toString tester

common

org.onap.policy.common.utils.test.ToStringTester

Copy the class to clamp.

XS

Hours

None

https://lf-onap.atlassian.net/browse/POLICY-5520

10

Test Utility: Resource Loading

common

org.onap.policy.common.utils.resources.ResourceUtils

Copy the class to clamp. Alternately replace with Spring Boot resource loader

XS

Hours

None

https://lf-onap.atlassian.net/browse/POLICY-5520

11

Hibernate Naming Strategy

common

org.onap.policy.common.spring.utils.CustomImplicitNamingStrategy

Copy the class to clamp. Note it is set in application.yaml and AcRuntimeParameters.yaml; double-check if the custom class is needed, if so remove from each AcRuntimeParameters.yaml.

S

2 Days

Low

https://lf-onap.atlassian.net/browse/POLICY-5520

12

Test Utility: Mock Server

common

org.onap.policy.common.endpoints.http.server.*
org.onap.policy.common.utils.network.NetworkUtil
org.onap.policy.common.gson.GsonMessageBodyHandler

Replace with off-the-shelf component e.g. OkHttp MockWebServer.

M

1 Week

None

https://lf-onap.atlassian.net/browse/POLICY-5506

13

Policy Participant (REST Communication)

common

org.onap.policy.common.endpoints.http.client.*
org.onap.policy.common.parameters.rest.*
org.onap.policy.common.parameters.topic.BusTopicParams

Replace with Spring’s RestTemplate/WebClient/RestClient.

M

1 Week

None

https://lf-onap.atlassian.net/browse/POLICY-5507

14

JSON/YAML & other Type Conversions

common

org.onap.policy.common.utils.coder.*

Copy the classes to clamp? Alternatively, replacing Gson with Jackson can be done to remove further dependencies.

M

1 Week

None

https://lf-onap.atlassian.net/browse/POLICY-5508

15

Java Bean Validation

common

org.onap.policy.common.parameters.annotations.*
org.onap.policy.common.utils.validation.Assertions

Replace with spring-boot-starter-validation (JSR-380).

M

1 Week

Medium

https://lf-onap.atlassian.net/browse/POLICY-5509

16

Kafka Messaging

common

org.onap.policy.common.endpoints.listeners.*
org.onap.policy.common.message.bus.*
org.onap.policy.common.parameters.topic.*
org.onap.policy.common.utils.services.*

Replace with Spring Kafka.

L

3 Weeks

High

https://lf-onap.atlassian.net/browse/POLICY-5510

17

Spring Config

docker

policy/docker repo overrides with AcRuntimeParameters.yaml

Have only one application.yaml in clamp, override settings with env vars

L

3 Weeks

High

https://lf-onap.atlassian.net/browse/POLICY-5511

18

Logback Config

docker

policy/docker repo overrides logback.xml

Have only one logback.xml in clamp, remove overrides

M

1 Week

Medium

https://lf-onap.atlassian.net/browse/POLICY-5512

19

CSITs

docker

policy/docker repo contains clamp CSITs

Move to clamp repo and make CSITs run per commit

M

1 Week

Low

https://lf-onap.atlassian.net/browse/POLICY-5513

* risk can be eliminated by preserving original package structure.

The epic is estimated to be 3.5 person-months of development effort.

Release Plan

Duration: 5 releases, spanning less than 4 to 5 months

To minimize risk of breaking changes, it is proposed that high risk items be spread across multiple releases. This will help with traceability in the event of a bug.

Item

Risk Level

Reward Level

Item

Risk Level

Reward Level

1

POM decoupling

Medium

High

2

Spring Boot 4

High

Medium

3

Spring Kafka: ACM-R only

Medium

High

4

De-duplicating Spring & Logback configs

Medium

High

5

Spring Kafka: participant intermediary

High

High

Note: the above release plan does not explicitly include low-risk items, which could be done in any release, e.g. test utilities, policy participant changes.

Release 1 - POM decoupling

Risk: None if done correctly; this is mainly copying files, but care must be taken not to change package structures for packages exposed by intermediary.
Mitigation: Require all changes to not modify participant-impl source code; can be observed in code review.

Copy all used Policy Framework dependencies directly into clamp repo, without modification, i.e. maintaining existing package structures, and remove POM dependencies. This virtually eliminates all risk, since no actual modifications are made.

  1. copy used classes/packages from policy-models into clamp/models maintaining original package structure

  2. copy used classes/packages from policy-common into clamp/common maintaining original package structure

  3. copy policy-parent/integration into clamp/parent without modification

  4. fix POM dependencies to use clamp versions, e.g. org.onap.policy.models:policy-models-tosca becomes org.onap.policy.clamp:models

  5. verify using mvn dependency:tree and running CSITs

This means that any future POM changes can be done in clamp repo only, not affecting any other PF component. Everything is under a single repo, other than clamp CSITs, which is in docker repo.

Parent POM cleanup

By copying the entire parent POM without modification, we will be copying things we don't need (e.g. clamp/parent doesn't need drools). The work of cleaning unused dependencies can be done independently in any release. Basically the approach is: instead of integrate, we replicate and tidy up after.

It is proposed to use a mechanical & maintainable solution, for example using Maven dependency plugin. See https://www.baeldung.com/maven-unused-dependencies

  1. Use maven dependency plugin to identify unused dependencies using mvn dependency:analyze

  2. Specify used dependencies in the <usedDependencies> section, as Maven can give false results, e.g. saying picocli is unused, when it is a runtime dependency, used for Liquibase rollback.

  3. Once sign-off is done by the team, re-run dependency analysis and remove any unused dependencies.

This process can be used on an ongoing basis as the decoupling work is done.

Future Dependency Uplifts

It is proposed that dependencies be auto-uplifted in future, e.g. using maven version plugin, or tools like Renovate or Dependabot. Currently, this is not feasible as changes to policy-parent do not trigger CSIT jobs for affected repos, meaning impacts are not known until later testing. Once dependencies are isolated to the clamp repo and CSITs run on every clamp code change, it becomes feasible to auto-uplift dependencies, preventing CVEs.

Release 2 - Spring Boot 4

Spring Boot 4 is needed for Spring Kafka to be compatible with Apache Kafka client 4.1, which was already delivered as a fix for stalled Kafka consumer issue.

Risk: A major uplift of Spring Boot carries a risk of breakage due to many dependency changes.
Mitigation: Separate release for Spring Boot uplift.

Release 3 - Spring Kafka: ACM-R only

Risk Implementation is being swapped out; Spring Kafka will certainly behave differently to policy-common message-bus. As such, there is some risk of bugs caused by behavioural differences.
Mitigation: Minimize risk by separating releases for Spring Kafka implementation for ACM-R and Participant Intermediary.

Risk: Spring Boot 3.5 does not (officially) support Apache Kafka client 4.1 - we need to either downgrade Kafka or uplift Spring Boot.
Mitigation: Uplift to Spring Boot 4 will be done first to ensure compatibility.

Release 4 - De-duplicating Spring & Logback configs

Risk: Some config may be inadvertently changed.
Mitigation: Compare the configs used before and after.

Refactoring Spring & Logback configurations to cleanup docker/helm charts and remove duplication. Some of these tasks could possibly be released with low risk items.

Release 5 - Spring Kafka: participant intermediary

Risk: Same as for ACM-R, however intermediary is used by multiple microservices, so the risk is magnified.
Mitigation: Spring Kafka for ACM-R is released in a previous release so any issues are detected before delivering Intermediary changes.

Risk: Version of Spring Kafka may rely on Spring Boot 4, so participants may need to uplift Spring Boot before Intermediary.
Mitigation: Additional study of compatibility recommended. Plenty of advanced notice for teams to uplift in advance.

Additional items that can be delivered in any release

Java Bean Validation

Risk: Low, given there is extensive test coverage using different service templates.
Mitigation: None needed, test coverage is solid.

Bean Validation is the only work item that depends on both policy-common and -models directly. As such, it is a high priority to remove, as it will block removal of policy-models.