Repository: companieshouse/company-appointments-consumer
Pull request #20: [JU-1694] Upgrade to Java 21
Author: login: dtoulcher-ch
Created: 2025-05-06T14:33:37Z | Merged: 2025-05-12T09:45:09Z

## Describe the changes

### Related Jira tickets
[Jira Ticket](URL)

## Developer check list
### General
- [ ] Is the PR as small as it can be?
- [ ] Has the Jira ticket been updated with any relevant comments?
- [ ] Is the `README` up to date?
- [ ] Has the `POM` been updated for the latest versions of dependencies?
- [ ] Has the code been double-checked against `main`?
- [ ] Does the code adhere standards in this repository, including SonarQube checks?

### Testing
- [ ] Do the code changes have unit and integration tests with code coverage > 80%?
- [ ] Has the code been tested locally and/or passed the API Karate tests on Tilt?
- [ ] Have mandatory manual test cases been run?
- [ ] Are extra Karate tests required?
- [ ] Are all the test data resources up to date?

### Release preparation
_Where possible, add links to the respective Jira tickets when an item is checked_
- [ ] Have these changes been included in a release ticket?
- [ ] Are changes required to the `docker-chs-development` deployment or test data?
- [ ] Are any changes required to the environment added to `chs-configs`?

## Notes to the tester
_Add any testing hints or instructions here._



Diff:
diff --git a/.gitignore b/.gitignore
index cb689e6..9c1c818 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,8 @@ hs_err_pid*
 .idea/
 *.iml
 
+.vscode/
+
 # Mac files
 .DS_Store
 
diff --git a/Makefile b/Makefile
index 18aa6db..348c130 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,5 @@
 artifact_name       := company-appointments-consumer
-version             := latest
-
-dependency_check_base_suppressions:=common_suppressions_spring_6.xml
-dependency_check_suppressions_repo_branch:=main
-dependency_check_minimum_cvss := 4
-dependency_check_assembly_analyzer_enabled := false
-dependency_check_suppressions_repo_url:=git@github.com:companieshouse/dependency-check-suppressions.git
-suppressions_file := target/suppressions.xml
+version             := "unversioned"
 
 .PHONY: all
 all: build
@@ -29,12 +22,12 @@ build:
 test: test-unit test-integration
 
 .PHONY: test-unit
-test-unit:
-	mvn clean verify -Dskip.unit.tests=false -Dskip.integration.tests=false
+test-unit: clean
+	mvn test -DexcludedGroups="integration-test"
 
 .PHONY: test-integration
-test-integration:
-	mvn verify -Dskip.unit.tests=true -Dskip.integration.tests=false
+test-integration: clean
+	mvn test -Dgroups="integration-test"
 
 .PHONY: package
 package:
@@ -61,35 +54,7 @@ sonar:
 sonar-pr-analysis:
 	mvn sonar:sonar -P sonar-pr-analysis
 
-.PHONY: dependency-check
-dependency-check:
-	@ if [ -d "$(DEPENDENCY_CHECK_SUPPRESSIONS_HOME)" ]; then \
-		suppressions_home="$${DEPENDENCY_CHECK_SUPPRESSIONS_HOME}"; \
-	fi; \
-	if [ ! -d "$${suppressions_home}" ]; then \
-	    suppressions_home_target_dir="./target/dependency-check-suppressions"; \
-		if [ -d "$${suppressions_home_target_dir}" ]; then \
-			suppressions_home="$${suppressions_home_target_dir}"; \
-		else \
-			mkdir -p "./target"; \
-			git clone $(dependency_check_suppressions_repo_url) "$${suppressions_home_target_dir}" && \
-				suppressions_home="$${suppressions_home_target_dir}"; \
-			if [ -d "$${suppressions_home_target_dir}" ] && [ -n "$(dependency_check_suppressions_repo_branch)" ]; then \
-				cd "$${suppressions_home}"; \
-				git checkout $(dependency_check_suppressions_repo_branch); \
-				cd -; \
-			fi; \
-		fi; \
-	fi; \
-	suppressions_path="$${suppressions_home}/suppressions/$(dependency_check_base_suppressions)"; \
-	if [  -f "$${suppressions_path}" ]; then \
-		cp -av "$${suppressions_path}" $(suppressions_file); \
-		mvn org.owasp:dependency-check-maven:check -Dformats="json,html" -DprettyPrint -DfailBuildOnCVSS=$(dependency_check_minimum_cvss) -DassemblyAnalyzerEnabled=$(dependency_check_assembly_analyzer_enabled) -DsuppressionFiles=$(suppressions_file); \
-	else \
-		printf -- "\n ERROR Cannot find suppressions file at '%s'\n" "$${suppressions_path}" >&2; \
-		exit 1; \
-	fi
-
 .PHONY: security-check
-security-check: dependency-check
-
+security-check:
+	mvn org.owasp:dependency-check-maven:update-only
+	mvn org.owasp:dependency-check-maven:check -DfailBuildOnCVSS=4 -DassemblyAnalyzerEnabled=false
diff --git a/README.md b/README.md
index da5c40c..5d5a94c 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 ## Summary
 
-* The company appointments consumer consumes messages from the stream-company-profile Kafka topic and deserialises them 
+* The company appointments consumer consumes messages from the stream-company-profile Kafka topic and deserialises them
 using the ResourceChangeData avro schema.
 * The messages are processed by sending PATCH requests to the Company Appointments API to update each appointment
 for the changed company profiles.
@@ -34,10 +34,10 @@ sequenceDiagram
    README.
 2. Enable the following services using the command `./bin/chs-dev services enable <service>`.
    * company-appointments-consumer
-   * company-appointments-api-ch-gov-uk
-3. Enable the streaming module using the command `./bin/chs-dev modules enable streaming`
-4. Boot up the services' containers on docker using tilt `tilt up`.
-5. Messages can be produced to the stream-company-profile using the instructions given in 
+   * chs-kafka-api
+   * chs-streaming-api
+3. Boot up the services' containers on docker using chs-dev `chs-dev up`.
+4. Messages can be produced to the stream-company-profile using the instructions given in
 [CHS Kafka API](https://github.com/companieshouse/chs-kafka-api).
 
 ## Environment variables
@@ -81,4 +81,3 @@ short-term, we have decided to change the `make test-unit` command in the Makefi
 will ensure unit AND integration tests are run and that coverage is added to the jacoco reporting and, therefore, produce accurate SonarQube reporting on GitHub.
 
 For a more in-depth explanation, please see: https://companieshouse.atlassian.net/wiki/spaces/TEAM4/pages/4357128294/DSND-1990+Tech+Debt+Spike+-+Fix+SonarQube+within+Pom+of+Projects
-
diff --git a/pom.xml b/pom.xml
index b342240..1cb8aaf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,29 +22,19 @@
   <packaging>jar</packaging>
 
   <properties>
-    <maven.compiler.source>11</maven.compiler.source>
-    <maven.compiler.target>11</maven.compiler.target>
-    <spring.boot.version>2.7.14</spring.boot.version>
-    <cucumber.version>7.11.2</cucumber.version>
-    <jib.version>3.3.1</jib.version>
-    <structured-logging.version>1.9.37</structured-logging.version>
-    <api-sdk-manager-java-library.version>1.0.6</api-sdk-manager-java-library.version>
-    <private-api-sdk-java.version>2.0.294</private-api-sdk-java.version>
-    <kafka-models.version>1.0.31</kafka-models.version>
-    <wiremock.version>3.5.2</wiremock.version>
-    <!--explicit versions of transitive dependencies with vulnerabilities in previous versions-->
-    <jayway-jsonpath.version>2.9.0</jayway-jsonpath.version>
-    <skip.unit.tests>false</skip.unit.tests>
-    <skip.integration.tests>false</skip.integration.tests>
-    <!--sonar configuration-->
-    <sonar.projectKey>uk.gov.companieshouse:company-appointments-consumer</sonar.projectKey>
-    <sonar.sources>src/main</sonar.sources>
-    <sonar.tests>src/test</sonar.tests>
-    <sonar.verbose>true</sonar.verbose>
-    <sonar.coverage.jacoco.xmlReportPaths>${project.build.directory}/site/jacoco/jacoco.xml
-    </sonar.coverage.jacoco.xmlReportPaths>
-    <sonar.jacoco.reports>${project.build.directory}/site</sonar.jacoco.reports>
-    <test-containers.version>1.19.7</test-containers.version>
+    <maven.compiler.source>21</maven.compiler.source>
+    <maven.compiler.target>21</maven.compiler.target>
+    <spring.boot.version>3.4.5</spring.boot.version>
+    <jib-maven-plugin.version>3.4.5</jib-maven-plugin.version>
+    <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
+    <structured-logging.version>3.0.31</structured-logging.version>
+    <private-api-sdk-java.version>4.0.295</private-api-sdk-java.version>
+    <kafka-models.version>3.0.17</kafka-models.version>
+    <wiremock.version>3.13.0</wiremock.version>
+    <mockito.version>5.17.0</mockito.version>
+    <avro.version>1.12.0</avro.version>
+    <test-containers.version>1.21.0</test-containers.version>
+    <maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
   </properties>
 
   <dependencyManagement>
@@ -56,67 +46,29 @@
         <type>pom</type>
         <scope>import</scope>
       </dependency>
-      <dependency>
-        <groupId>io.cucumber</groupId>
-        <artifactId>cucumber-bom</artifactId>
-        <version>${cucumber.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
         <version>${test-containers.version}</version>
         <type>pom</type>
-        <scope>import</scope>
+        <scope>test</scope>
       </dependency>
+    <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-bom</artifactId>
+        <version>${mockito.version}</version>
+        <type>pom</type>
+        <scope>test</scope>
+    </dependency>
     </dependencies>
   </dependencyManagement>
   <dependencies>
-    <!--the following transitive dependencies are added specifically to avoid vulnerabilities-->
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <version>1.26.1</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-beanutils</groupId>
-      <artifactId>commons-beanutils</artifactId>
-      <version>1.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.plexus</groupId>
-      <artifactId>plexus-utils</artifactId>
-      <version>4.0.1</version>
-    </dependency>
     <dependency>
       <groupId>org.wiremock</groupId>
       <artifactId>wiremock-standalone</artifactId>
       <version>${wiremock.version}</version>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>com.jayway.jsonpath</groupId>
-      <artifactId>json-path</artifactId>
-      <version>${jayway-jsonpath.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.bitbucket.b_c</groupId>
-      <artifactId>jose4j</artifactId>
-      <version>0.9.6</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-      <version>33.1.0-jre</version>
-    </dependency>
-    <dependency>
-      <groupId>org.xerial.snappy</groupId>
-      <artifactId>snappy-java</artifactId>
-      <version>1.1.10.5</version>
-    </dependency>
-    <!--end transitive dependencies-->
-
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter</artifactId>
@@ -127,20 +79,6 @@
         </exclusion>
       </exclusions>
     </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-logging</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.apache.logging.log4j</groupId>
-          <artifactId>log4j-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>org.apache.logging.log4j</groupId>
-          <artifactId>log4j-to-slf4j</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
@@ -162,51 +100,21 @@
       <artifactId>structured-logging</artifactId>
       <version>${structured-logging.version}</version>
     </dependency>
-    <dependency>
-      <groupId>uk.gov.companieshouse</groupId>
-      <artifactId>api-sdk-manager-java-library</artifactId>
-      <version>${api-sdk-manager-java-library.version}</version>
-      <exclusions>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>commons-collections</groupId>
-          <artifactId>commons-collections</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>io.grpc</groupId>
-          <artifactId>grpc-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>io.grpc</groupId>
-          <artifactId>grpc-context</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
     <dependency>
       <groupId>uk.gov.companieshouse</groupId>
       <artifactId>private-api-sdk-java</artifactId>
       <version>${private-api-sdk-java.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.avro</groupId>
+      <artifactId>avro</artifactId>
+      <version>${avro.version}</version>
+    </dependency>
     <dependency>
       <groupId>uk.gov.companieshouse</groupId>
       <artifactId>kafka-models</artifactId>
       <version>${kafka-models.version}</version>
       <exclusions>
-        <exclusion>
-          <groupId>com.jayway.jsonpath</groupId>
-          <artifactId>json-path</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>commons-fileupload</groupId>
-          <artifactId>commons-fileupload</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>org.eclipse.jetty</groupId>
-          <artifactId>jetty-xml</artifactId>
-        </exclusion>
         <exclusion>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-client</artifactId>
@@ -219,10 +127,6 @@
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-webapp</artifactId>
         </exclusion>
-        <exclusion>
-          <groupId>com.github.tomakehurst</groupId>
-          <artifactId>wiremock-jre8</artifactId>
-        </exclusion>
       </exclusions>
     </dependency>
     <dependency>
@@ -235,16 +139,6 @@
       <artifactId>spring-kafka-test</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-api</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-engine</artifactId>
-      <scope>test</scope>
-    </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
@@ -255,36 +149,6 @@
       <artifactId>mockito-junit-jupiter</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-inline</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>io.cucumber</groupId>
-      <artifactId>cucumber-java</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>io.cucumber</groupId>
-      <artifactId>cucumber-spring</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.platform</groupId>
-      <artifactId>junit-platform-suite</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>io.cucumber</groupId>
-      <artifactId>cucumber-junit-platform-engine</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.platform</groupId>
-      <artifactId>junit-platform-commons</artifactId>
-      <scope>test</scope>
-    </dependency>
     <dependency>
       <groupId>org.testcontainers</groupId>
       <artifactId>testcontainers</artifactId>
@@ -301,116 +165,54 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
+
   <build>
     <plugins>
       <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <version>${spring.boot.version}</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>repackage</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>3.0.0</version>
         <configuration>
-          <skipTests>${skip.unit.tests}</skipTests>
-          <excludes>
-            <exclude>**/Runner.java</exclude>
-          </excludes>
+          <mainClass>uk.gov.companieshouse.appointments.subdelta.Application</mainClass>
         </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <version>3.0.0</version>
         <executions>
           <execution>
             <goals>
-              <goal>integration-test</goal>
-              <goal>verify</goal>
+              <goal>repackage</goal>
             </goals>
           </execution>
         </executions>
-        <configuration>
-          <!-- See SUREFIRE-1198 -->
-          <classesDirectory>${project.build.outputDirectory}</classesDirectory>
-          <properties>
-            <configurationParameters>
-              cucumber.junit-platform.naming-strategy=long
-            </configurationParameters>
-          </properties>
-          <skipITs>${skip.integration.tests}</skipITs>
-          <includes>
-            <include>**/Runner.java</include>
-          </includes>
-        </configuration>
       </plugin>
       <plugin>
         <groupId>com.google.cloud.tools</groupId>
         <artifactId>jib-maven-plugin</artifactId>
-        <version>${jib.version}</version>
+        <version>${jib-maven-plugin.version}</version>
         <configuration>
+          <from>
+            <image>416670754337.dkr.ecr.eu-west-2.amazonaws.com/ci-corretto-build-21</image>
+          </from>
+          <to>
+            <image>416670754337.dkr.ecr.eu-west-2.amazonaws.com/company-appointments-consumer</image>
+          </to>
           <container>
             <expandClasspathDependencies>true</expandClasspathDependencies>
           </container>
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <version>${jacoco-maven-plugin.version}</version>
-
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${maven-surefire-plugin.version}</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>${maven-compiler-plugin.version}</version>
         <configuration>
-          <append>true</append>
-          <destFile>${sonar.jacoco.reports}/jacoco.exec</destFile>
-          <dataFile>${sonar.jacoco.reports}/jacoco.exec</dataFile>
-          <outputDirectory>${sonar.jacoco.reports}/jacoco</outputDirectory>
+          <source>21</source>
+          <target>21</target>
         </configuration>
-
-        <executions>
-          <execution>
-            <id>pre-unit-test</id>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <propertyName>surefireArgLine</propertyName>
-            </configuration>
-          </execution>
-          <execution>
-            <id>post-unit-test</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>report</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>pre-integration-test</id>
-            <phase>pre-integration-test</phase>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <propertyName>failsafeArgLine</propertyName>
-            </configuration>
-          </execution>
-          <execution>
-            <id>post-integration-test</id>
-            <phase>verify</phase>
-            <goals>
-              <goal>report</goal>
-            </goals>
-          </execution>
-        </executions>
       </plugin>
     </plugins>
   </build>
 </project>
-
diff --git a/src/main/java/uk/gov/companieshouse/appointments/subdelta/companyprofile/CompanyProfileChangedService.java b/src/main/java/uk/gov/companieshouse/appointments/subdelta/companyprofile/CompanyProfileChangedService.java
index bed3695..eedb799 100644
--- a/src/main/java/uk/gov/companieshouse/appointments/subdelta/companyprofile/CompanyProfileChangedService.java
+++ b/src/main/java/uk/gov/companieshouse/appointments/subdelta/companyprofile/CompanyProfileChangedService.java
@@ -40,6 +40,7 @@ public void processMessage(ResourceChangedData changedData) {
 
         LOGGER.debug(DESERIALISE_SUCCEEDED_MESSAGE, DataMapHolder.getLogMap());
         String uri = changedData.getResourceUri() + EXISTING_APPOINTMENTS_URI_SUFFIX;
+
         appointmentsClient.patchCompanyNameAndStatusForAllAppointments(uri, companyProfileData.getCompanyName(),
                 companyProfileData.getCompanyStatus());
     }
diff --git a/src/main/java/uk/gov/companieshouse/appointments/subdelta/kafka/Consumer.java b/src/main/java/uk/gov/companieshouse/appointments/subdelta/kafka/Consumer.java
index 9760856..d01bc1c 100644
--- a/src/main/java/uk/gov/companieshouse/appointments/subdelta/kafka/Consumer.java
+++ b/src/main/java/uk/gov/companieshouse/appointments/subdelta/kafka/Consumer.java
@@ -3,8 +3,8 @@
 import org.springframework.kafka.annotation.KafkaListener;
 import org.springframework.kafka.annotation.RetryableTopic;
 import org.springframework.kafka.retrytopic.DltStrategy;
-import org.springframework.kafka.retrytopic.FixedDelayStrategy;
 import org.springframework.kafka.retrytopic.RetryTopicHeaders;
+import org.springframework.kafka.retrytopic.SameIntervalTopicReuseStrategy;
 import org.springframework.kafka.support.KafkaHeaders;
 import org.springframework.messaging.Message;
 import org.springframework.messaging.handler.annotation.Header;
@@ -47,13 +47,13 @@ public Consumer(ServiceRouter router, MessageFlags messageFlags) {
             retryTopicSuffix = "-${consumer.group_id}-retry",
             dltTopicSuffix = "-${consumer.group_id}-error",
             dltStrategy = DltStrategy.FAIL_ON_ERROR,
-            fixedDelayTopicStrategy = FixedDelayStrategy.SINGLE_TOPIC,
+            sameIntervalTopicReuseStrategy = SameIntervalTopicReuseStrategy.SINGLE_TOPIC,
             include = RetryableException.class
     )
     public void consume(Message<ResourceChangedData> message,
             @Header(name = RetryTopicHeaders.DEFAULT_HEADER_ATTEMPTS, required = false) Integer attempts,
             @Header(KafkaHeaders.RECEIVED_TOPIC) String topic,
-            @Header(KafkaHeaders.RECEIVED_PARTITION_ID) Integer partition,
+            @Header(KafkaHeaders.RECEIVED_PARTITION) Integer partition,
             @Header(KafkaHeaders.OFFSET) Long offset) {
         try {
             DataMapHolder.get().companyNumber(message.getPayload().getResourceId());
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/ApplicationIT.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/ApplicationTest.java
similarity index 98%
rename from src/test/java/uk/gov/companieshouse/appointments/subdelta/ApplicationIT.java
rename to src/test/java/uk/gov/companieshouse/appointments/subdelta/ApplicationTest.java
index 1da2118..c240727 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/ApplicationIT.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/ApplicationTest.java
@@ -16,7 +16,7 @@
 
 @AutoConfigureMockMvc
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-class ApplicationIT {
+class ApplicationTest {
 
     @Autowired
     private MockMvc mockMvc;
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/AbstractKafkaTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/AbstractKafkaTest.java
index d93105e..e942187 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/AbstractKafkaTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/AbstractKafkaTest.java
@@ -1,7 +1,7 @@
 package uk.gov.companieshouse.appointments.subdelta.kafka;
 
 import org.springframework.context.annotation.Import;
-import org.testcontainers.containers.KafkaContainer;
+import org.testcontainers.kafka.ConfluentKafkaContainer;
 import org.testcontainers.junit.jupiter.Container;
 import org.testcontainers.junit.jupiter.Testcontainers;
 import org.testcontainers.utility.DockerImageName;
@@ -11,6 +11,6 @@
 public abstract class AbstractKafkaTest {
 
     @Container
-    protected static final KafkaContainer kafka = new KafkaContainer(DockerImageName.parse(
-            "confluentinc/cp-kafka:latest"));
-}
+    protected static final ConfluentKafkaContainer kafka = new ConfluentKafkaContainer(DockerImageName.parse(
+            "confluentinc/cp-kafka:7.9.1"));
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerInvalidTopicTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerInvalidTopicTest.java
index 757d952..0acae51 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerInvalidTopicTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerInvalidTopicTest.java
@@ -6,10 +6,10 @@
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_RETRY_TOPIC;
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_TOPIC;
 
-import com.github.tomakehurst.wiremock.junit5.WireMockTest;
 import java.io.ByteArrayOutputStream;
 import java.time.Duration;
 import java.util.concurrent.Future;
+
 import org.apache.avro.io.DatumWriter;
 import org.apache.avro.io.Encoder;
 import org.apache.avro.io.EncoderFactory;
@@ -26,9 +26,10 @@
 import org.springframework.kafka.test.utils.KafkaTestUtils;
 import org.springframework.test.context.DynamicPropertyRegistry;
 import org.springframework.test.context.DynamicPropertySource;
+import org.testcontainers.containers.wait.strategy.Wait;
+import static java.time.temporal.ChronoUnit.SECONDS;
 
-@SpringBootTest
-@WireMockTest(httpPort = 8888)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 class ConsumerInvalidTopicTest extends AbstractKafkaTest {
 
     @Autowired
@@ -46,6 +47,8 @@ static void props(DynamicPropertyRegistry registry) {
 
     @BeforeEach
     public void setup() {
+                kafka.setWaitStrategy(Wait.defaultWaitStrategy()
+                .withStartupTimeout(Duration.of(300, SECONDS)));
         testConsumerAspect.resetLatch();
         testConsumer.poll(Duration.ofMillis(1000));
     }
@@ -63,7 +66,7 @@ void testPublishToCompanyProfileInvalidMessageTopicIfInvalidDataDeserialised() t
                 new ProducerRecord<>(STREAM_COMPANY_PROFILE_TOPIC,
                         0, System.currentTimeMillis(), "key", outputStream.toByteArray()));
         future.get();
-        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, 10000L, 2);
+        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, Duration.ofMillis(10000L), 2);
 
         //then
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_TOPIC)).isEqualTo(1);
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerNonRetryableExceptionTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerNonRetryableExceptionTest.java
index 5bd45af..1fd699e 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerNonRetryableExceptionTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerNonRetryableExceptionTest.java
@@ -10,11 +10,11 @@
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_RETRY_TOPIC;
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_TOPIC;
 
-import com.github.tomakehurst.wiremock.junit5.WireMockTest;
 import java.io.ByteArrayOutputStream;
 import java.time.Duration;
 import java.util.Collections;
 import java.util.concurrent.TimeUnit;
+
 import org.apache.avro.io.DatumWriter;
 import org.apache.avro.io.Encoder;
 import org.apache.avro.io.EncoderFactory;
@@ -27,17 +27,18 @@
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.kafka.test.utils.KafkaTestUtils;
 import org.springframework.test.context.DynamicPropertyRegistry;
 import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+
 import uk.gov.companieshouse.appointments.subdelta.companyprofile.ServiceRouter;
 import uk.gov.companieshouse.appointments.subdelta.exception.NonRetryableException;
 import uk.gov.companieshouse.stream.EventRecord;
 import uk.gov.companieshouse.stream.ResourceChangedData;
+import static java.time.temporal.ChronoUnit.SECONDS;
 
-@SpringBootTest
-@WireMockTest(httpPort = 8888)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 class ConsumerNonRetryableExceptionTest extends AbstractKafkaTest {
 
     @Autowired
@@ -47,7 +48,7 @@ class ConsumerNonRetryableExceptionTest extends AbstractKafkaTest {
     @Autowired
     private TestConsumerAspect testConsumerAspect;
 
-    @MockBean
+    @MockitoBean
     private ServiceRouter router;
 
     @DynamicPropertySource
@@ -58,6 +59,7 @@ static void props(DynamicPropertyRegistry registry) {
 
     @BeforeEach
     public void setup() {
+        kafka.withStartupTimeout(Duration.of(300, SECONDS));
         testConsumerAspect.resetLatch();
         testConsumer.poll(Duration.ofMillis(1000));
     }
@@ -80,7 +82,7 @@ void testRepublishToCompanyProfileInvalidMessageTopicIfNonRetryableExceptionThro
         if (!testConsumerAspect.getLatch().await(30L, TimeUnit.SECONDS)) {
             fail("Timed out waiting for latch");
         }
-        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, 10000L, 2);
+        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, Duration.ofMillis(10000L), 2);
 
         //then
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_TOPIC)).isEqualTo(1);
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerPositiveTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerPositiveTest.java
index 793b415..0fb6341 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerPositiveTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerPositiveTest.java
@@ -9,11 +9,11 @@
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_RETRY_TOPIC;
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_TOPIC;
 
-import com.github.tomakehurst.wiremock.junit5.WireMockTest;
 import java.io.ByteArrayOutputStream;
 import java.time.Duration;
 import java.util.Collections;
 import java.util.concurrent.TimeUnit;
+
 import org.apache.avro.io.DatumWriter;
 import org.apache.avro.io.Encoder;
 import org.apache.avro.io.EncoderFactory;
@@ -26,16 +26,17 @@
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.kafka.test.utils.KafkaTestUtils;
 import org.springframework.test.context.DynamicPropertyRegistry;
 import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+import static java.time.temporal.ChronoUnit.SECONDS;
+
 import uk.gov.companieshouse.appointments.subdelta.companyprofile.ServiceRouter;
 import uk.gov.companieshouse.stream.EventRecord;
 import uk.gov.companieshouse.stream.ResourceChangedData;
 
-@SpringBootTest
-@WireMockTest(httpPort = 8888)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 class ConsumerPositiveTest extends AbstractKafkaTest {
 
     @Autowired
@@ -45,7 +46,7 @@ class ConsumerPositiveTest extends AbstractKafkaTest {
     @Autowired
     private TestConsumerAspect testConsumerAspect;
 
-    @MockBean
+    @MockitoBean
     private ServiceRouter router;
 
     @DynamicPropertySource
@@ -56,6 +57,7 @@ static void props(DynamicPropertyRegistry registry) {
 
     @BeforeEach
     public void setup() {
+        kafka.withStartupTimeout(Duration.of(300, SECONDS));
         testConsumerAspect.resetLatch();
         testConsumer.poll(Duration.ofMillis(1000));
     }
@@ -78,7 +80,7 @@ void testConsumeFromStreamCompanyProfileTopic() throws Exception {
         }
 
         //then
-        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, 10000L, 1);
+        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, Duration.ofMillis(10000L), 1);
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_TOPIC)).isOne();
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_RETRY_TOPIC)).isZero();
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_ERROR_TOPIC)).isZero();
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerRetryableExceptionTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerRetryableExceptionTest.java
index 3aff0c0..d03ce4b 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerRetryableExceptionTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ConsumerRetryableExceptionTest.java
@@ -11,11 +11,12 @@
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_RETRY_TOPIC;
 import static uk.gov.companieshouse.appointments.subdelta.kafka.TestUtils.STREAM_COMPANY_PROFILE_TOPIC;
 
-import com.github.tomakehurst.wiremock.junit5.WireMockTest;
 import java.io.ByteArrayOutputStream;
 import java.time.Duration;
 import java.util.Collections;
 import java.util.concurrent.TimeUnit;
+import static java.time.temporal.ChronoUnit.SECONDS;
+
 import org.apache.avro.io.DatumWriter;
 import org.apache.avro.io.Encoder;
 import org.apache.avro.io.EncoderFactory;
@@ -28,17 +29,17 @@
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.kafka.test.utils.KafkaTestUtils;
 import org.springframework.test.context.DynamicPropertyRegistry;
 import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+
 import uk.gov.companieshouse.appointments.subdelta.companyprofile.ServiceRouter;
 import uk.gov.companieshouse.appointments.subdelta.exception.RetryableException;
 import uk.gov.companieshouse.stream.EventRecord;
 import uk.gov.companieshouse.stream.ResourceChangedData;
 
-@SpringBootTest
-@WireMockTest(httpPort = 8888)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 class ConsumerRetryableExceptionTest extends AbstractKafkaTest {
 
     @Autowired
@@ -48,7 +49,7 @@ class ConsumerRetryableExceptionTest extends AbstractKafkaTest {
     @Autowired
     private TestConsumerAspect testConsumerAspect;
 
-    @MockBean
+    @MockitoBean
     private ServiceRouter router;
 
     @DynamicPropertySource
@@ -59,6 +60,7 @@ static void props(DynamicPropertyRegistry registry) {
 
     @BeforeEach
     public void setup() {
+        kafka.withStartupTimeout(Duration.of(300, SECONDS));
         testConsumerAspect.resetLatch();
         testConsumer.poll(Duration.ofMillis(1000));
     }
@@ -83,7 +85,7 @@ void testRepublishToCompanyProfileErrorTopicThroughRetryTopics() throws Exceptio
         }
 
         //then
-        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, 10000L, 6);
+        ConsumerRecords<?, ?> consumerRecords = KafkaTestUtils.getRecords(testConsumer, Duration.ofMillis(10000L), 6);
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_TOPIC)).isEqualTo(1);
         assertThat(TestUtils.noOfRecordsForTopic(consumerRecords, STREAM_COMPANY_PROFILE_RETRY_TOPIC))
                 .isEqualTo(4);
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataDeserialiserTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataDeserialiserTest.java
index ce3ff25..8a00b87 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataDeserialiserTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataDeserialiserTest.java
@@ -48,7 +48,7 @@ void testDeserialiseDelta() throws IOException {
 
     @Test
     @DisplayName("Throws InvalidPayloadException if IOException encountered when deserialising a message")
-    void testDeserialiseDataThrowsInvalidPayloadExceptionlIfIOExceptionEncountered()
+    void testDeserialiseDataThrowsInvalidPayloadExceptionIfIOExceptionEncountered()
             throws IOException {
         // given
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@@ -65,11 +65,12 @@ void testDeserialiseDataThrowsInvalidPayloadExceptionlIfIOExceptionEncountered()
         // Note the '\n' is the length prefix of the invalid data sent to the deserialiser
         assertThat(exception.getMessage()).isEqualTo("Invalid payload: [\nhello] was provided.");
         assertThat(exception.getCause()).isInstanceOf(IOException.class);
+        deserialiser.close();
     }
 
     @Test
     @DisplayName("Throws InvalidPayloadException if AvroRuntimeException encountered when deserialising a message")
-    void testDeserialiseDataThrowsInvalidPayloadExceptionlIfAvroRuntimeExceptionEncountered() {
+    void testDeserialiseDataThrowsInvalidPayloadExceptionIfAvroRuntimeExceptionEncountered() {
         // given
         ResourceChangedDataDeserialiser deserialiser = new ResourceChangedDataDeserialiser();
 
@@ -81,5 +82,6 @@ void testDeserialiseDataThrowsInvalidPayloadExceptionlIfAvroRuntimeExceptionEnco
         InvalidPayloadException exception = assertThrows(InvalidPayloadException.class, actual);
         assertThat(exception.getMessage()).isEqualTo("Invalid payload: [invalid] was provided.");
         assertThat(exception.getCause()).isInstanceOf(AvroRuntimeException.class);
+        deserialiser.close();
     }
 }
\ No newline at end of file
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataSerialiserTest.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataSerialiserTest.java
index 9934933..6f1583f 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataSerialiserTest.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/ResourceChangedDataSerialiserTest.java
@@ -9,12 +9,14 @@
 
 import java.io.IOException;
 import java.util.Collections;
+
 import org.apache.avro.io.DatumWriter;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.function.Executable;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
+
 import uk.gov.companieshouse.appointments.subdelta.exception.NonRetryableException;
 import uk.gov.companieshouse.stream.EventRecord;
 import uk.gov.companieshouse.stream.ResourceChangedData;
@@ -38,6 +40,7 @@ void testSerialiseResourceChangedData() {
 
         // then
         assertThat(actual).isNotNull();
+        serialiser.close();
     }
 
     @Test
diff --git a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/TestConfig.java b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/TestConfig.java
index 91c741f..2cae5c8 100644
--- a/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/TestConfig.java
+++ b/src/test/java/uk/gov/companieshouse/appointments/subdelta/kafka/TestConfig.java
@@ -8,6 +8,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.consumer.KafkaConsumer;
 import org.apache.kafka.clients.producer.KafkaProducer;
@@ -20,6 +21,7 @@
 import org.springframework.boot.test.context.TestConfiguration;
 import org.springframework.context.annotation.Bean;
 
+
 @TestConfiguration
 public class TestConfig {
 
diff --git a/start.sh b/start.sh
deleted file mode 100644
index 74be258..0000000
--- a/start.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-APP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-if [[ -z "${MESOS_SLAVE_PID}" ]]; then
-  echo "This script must be run from within Mesos" >&2
-  exit 1
-fi
-
-PORT="$1"
-CONFIG_URL="$2"
-ENVIRONMENT="$3"
-APP_NAME="$4"
-
-source /etc/profile
-
-echo "Downloading environment from: ${CONFIG_URL}/${ENVIRONMENT}/${APP_NAME}"
-wget -O "${APP_DIR}/private_env" "${CONFIG_URL}/${ENVIRONMENT}/private_env"
-wget -O "${APP_DIR}/global_env" "${CONFIG_URL}/${ENVIRONMENT}/global_env"
-wget -O "${APP_DIR}/app_env" "${CONFIG_URL}/${ENVIRONMENT}/${APP_NAME}/env"
-source "${APP_DIR}/private_env"
-source "${APP_DIR}/global_env"
-source "${APP_DIR}/app_env"
-
-exec java ${JAVA_MEM_ARGS} -jar -Dserver.port="${PORT}" "${APP_DIR}/company-appointments-consumer.jar"
\ No newline at end of file
diff --git a/suppress.xml b/suppress.xml
new file mode 100644
index 0000000..442d77a
--- /dev/null
+++ b/suppress.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
+
+</suppressions>
\ No newline at end of file


Reviews:
user: login: vaibhavcompanieshouse
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-07T13:34:52Z
user: login: dtoulcher-ch
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T14:30:06Z
user: login: vaibhavcompanieshouse
state: APPROVED
author_association: NONE
submitted_at: 2025-05-08T08:51:58Z
user: login: dtoulcher-ch
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T10:03:00Z

Review comments:
diff_hunk: @@ -56,67 +46,29 @@
         <type>pom</type>
         <scope>import</scope>
       </dependency>
-      <dependency>
-        <groupId>io.cucumber</groupId>
-        <artifactId>cucumber-bom</artifactId>
-        <version>${cucumber.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
         <version>${test-containers.version}</version>
         <type>pom</type>
-        <scope>import</scope>
+        <scope>test</scope>
       </dependency>
+    <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-bom</artifactId>
+        <version>${mockito.version}</version>
+        <type>pom</type>
+        <scope>test</scope>
+    </dependency>
     </dependencies>
   </dependencyManagement>
   <dependencies>
-    <!--the following transitive dependencies are added specifically to avoid vulnerabilities-->
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <version>1.26.1</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-beanutils</groupId>
-      <artifactId>commons-beanutils</artifactId>
-      <version>1.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.plexus</groupId>
-      <artifactId>plexus-utils</artifactId>
-      <version>4.0.1</version>
-    </dependency>
     <dependency>
       <groupId>org.wiremock</groupId>
       <artifactId>wiremock-standalone</artifactId>
-      <version>${wiremock.version}</version>
+      <version>3.13.0</version>
path: pom.xml
user: login: vaibhavcompanieshouse
body: version can be moved to property
created_at: 2025-05-07T13:26:36Z
author_association: NONE
diff_hunk: @@ -22,29 +22,19 @@
   <packaging>jar</packaging>
 
   <properties>
-    <maven.compiler.source>11</maven.compiler.source>
-    <maven.compiler.target>11</maven.compiler.target>
-    <spring.boot.version>2.7.14</spring.boot.version>
-    <cucumber.version>7.11.2</cucumber.version>
-    <jib.version>3.3.1</jib.version>
-    <structured-logging.version>1.9.37</structured-logging.version>
-    <api-sdk-manager-java-library.version>1.0.6</api-sdk-manager-java-library.version>
-    <private-api-sdk-java.version>2.0.294</private-api-sdk-java.version>
-    <kafka-models.version>1.0.31</kafka-models.version>
+    <maven.compiler.source>21</maven.compiler.source>
+    <maven.compiler.target>21</maven.compiler.target>
+    <spring.boot.version>3.4.5</spring.boot.version>
+    <jib-maven-plugin.version>3.4.5</jib-maven-plugin.version>
+    <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
+    <structured-logging.version>3.0.31</structured-logging.version>
+    <private-api-sdk-java.version>4.0.290</private-api-sdk-java.version>
+    <kafka-models.version>3.0.13</kafka-models.version>
path: pom.xml
user: login: vaibhavcompanieshouse
body: kafka-models.version 3.0.13->3.0.17 is also available so can we upgrade
created_at: 2025-05-07T13:50:27Z
author_association: NONE
path: .vscode/settings.json
user: login: vaibhavcompanieshouse
body: Do we need this file?
created_at: 2025-05-07T13:50:51Z
author_association: NONE
diff_hunk: @@ -56,67 +46,29 @@
         <type>pom</type>
         <scope>import</scope>
       </dependency>
-      <dependency>
-        <groupId>io.cucumber</groupId>
-        <artifactId>cucumber-bom</artifactId>
-        <version>${cucumber.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
       <dependency>
         <groupId>org.testcontainers</groupId>
         <artifactId>testcontainers-bom</artifactId>
         <version>${test-containers.version}</version>
         <type>pom</type>
-        <scope>import</scope>
+        <scope>test</scope>
       </dependency>
+    <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-bom</artifactId>
+        <version>${mockito.version}</version>
+        <type>pom</type>
+        <scope>test</scope>
+    </dependency>
     </dependencies>
   </dependencyManagement>
   <dependencies>
-    <!--the following transitive dependencies are added specifically to avoid vulnerabilities-->
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <version>1.26.1</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-beanutils</groupId>
-      <artifactId>commons-beanutils</artifactId>
-      <version>1.9.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.plexus</groupId>
-      <artifactId>plexus-utils</artifactId>
-      <version>4.0.1</version>
-    </dependency>
     <dependency>
       <groupId>org.wiremock</groupId>
       <artifactId>wiremock-standalone</artifactId>
-      <version>${wiremock.version}</version>
+      <version>3.13.0</version>
path: pom.xml
user: login: dtoulcher-ch
body: Updated to use the property version.
created_at: 2025-05-07T14:30:05Z
author_association: CONTRIBUTOR
path: .vscode/settings.json
user: login: dtoulcher-ch
body: I've add it to the `.gitignore`  file and removed it
created_at: 2025-05-08T10:03:00Z
author_association: CONTRIBUTOR

PR comments:
user: login: ch-code-analysis
created_at: 2025-05-09T16:10:23Z
body: CI: No security warnings found
author_association: NONE
user: login: ch-code-analysis
created_at: 2025-05-12T07:28:40Z
body: CI: No security warnings found
author_association: NONE
user: login: ch-code-analysis
created_at: 2025-05-12T08:51:32Z
body: CI: No security warnings found
author_association: NONE
user: login: ch-code-analysis
created_at: 2025-05-12T08:51:39Z
body: CI: Security warnings found!
author_association: NONE
user: login: ch-code-analysis
created_at: 2025-05-12T08:57:44Z
body: CI: No security warnings found
author_association: NONE
user: login: chsonarqubeprchecks[bot]
created_at: 2025-05-12T09:38:47Z
body: **SonarQube Quality Gate**

[![Quality Gate passed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](http://code-analysis.platform.aws.chdev.org:9000/dashboard?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20)

[![Bug](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/common/bug-16px.png 'Bug')](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=BUG) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/RatingBadge/A-16px.png 'A')](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=BUG) [0 Bugs](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=BUG)  
[![Vulnerability](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/common/vulnerability-16px.png 'Vulnerability')](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=VULNERABILITY) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/RatingBadge/A-16px.png 'A')](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/common/security_hotspot-16px.png 'Security Hotspot')](http://code-analysis.platform.aws.chdev.org:9000/security_hotspots?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/RatingBadge/A-16px.png 'A')](http://code-analysis.platform.aws.chdev.org:9000/security_hotspots?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20) [0 Security Hotspots](http://code-analysis.platform.aws.chdev.org:9000/security_hotspots?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20)  
[![Code Smell](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/common/code_smell-16px.png 'Code Smell')](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=CODE_SMELL) [![A](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/RatingBadge/A-16px.png 'A')](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=CODE_SMELL) [0 Code Smells](http://code-analysis.platform.aws.chdev.org:9000/project/issues?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](http://code-analysis.platform.aws.chdev.org:9000/component_measures?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&metric=coverage&view=list) No Coverage information  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v86/checks/Duplications/3-16px.png '0.0%')](http://code-analysis.platform.aws.chdev.org:9000/component_measures?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](http://code-analysis.platform.aws.chdev.org:9000/component_measures?id=uk.gov.companieshouse%3Acompany-appointments-consumer&pullRequest=20&metric=new_duplicated_lines_density&view=list)


author_association: NONE
user: login: ch-code-analysis
created_at: 2025-05-12T09:42:46Z
body: CI: No security warnings found
author_association: NONE