diff --git a/api-tests/pom.xml b/api-tests/pom.xml index 4fb422a95..f2e36addd 100644 --- a/api-tests/pom.xml +++ b/api-tests/pom.xml @@ -13,12 +13,13 @@ UTF-8 4.3.4 4.3.4 - 7.33.0 - 1.5.18 + 7.34.2 + 1.5.32 UTF-8 4 - 2.19.2 + 2.21.1 + 2.21 17 (@Functional or @Smoke or @Performance) and not @Ignore @@ -29,41 +30,41 @@ 4.0.10 4.0.10 4.0.10 - 4.9.4 + 4.9.8 11.0.0 5.13.4 - 3.27.4 + 3.27.7 3.0 - 1.17.6 + 1.18.5 3.0.0 3.0.0 - 33.4.8-jre + 33.5.0-jre 20250517 - 4.2.8.Final - 4.2.3.Final - 4.2.3.Final - 5.5 + 4.2.10.Final + 4.2.10.Final + 4.2.10.Final + 5.6 2.12.2 - 1.19.0 + 1.21.0 6.2.9 2.3.34 - 2.13.1 + 2.13.2 5.5.5 0.9.275 - 1.18.38 + 1.18.42 - 4.9.3.2 - 12.1.9 + 4.9.8.2 + 12.2.0 2.13 3.6.0 - 3.5.3 - 3.5.3 - 3.14.0 - 4.6.17 - 3.27.0 + 3.5.5 + 3.5.5 + 3.15.0 + 4.6.20 + 3.28.0 3.0.5 - 3.5.1 + 3.6.3 @@ -259,7 +260,7 @@ com.fasterxml.jackson.core jackson-annotations - ${jackson.version} + ${jackson.annotations.version} io.netty diff --git a/api-tests/src/test/java/com/amido/stacks/tests/api/CucumberTestSuite.java b/api-tests/src/test/java/com/amido/stacks/tests/api/CucumberTestSuite.java index 8ab260260..223735f6d 100644 --- a/api-tests/src/test/java/com/amido/stacks/tests/api/CucumberTestSuite.java +++ b/api-tests/src/test/java/com/amido/stacks/tests/api/CucumberTestSuite.java @@ -1,6 +1,7 @@ package com.amido.stacks.tests.api; import static io.cucumber.junit.platform.engine.Constants.FEATURES_PROPERTY_NAME; +import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; @@ -18,4 +19,5 @@ @DisabledIfSystemProperty(named = "untagged.test.check", matches = "true") @IncludeEngines("cucumber") @ConfigurationParameter(key = FEATURES_PROPERTY_NAME, value = "classpath:cucumber/features") +@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.amido.stacks.tests.api.stepdefinitions") public class CucumberTestSuite {} diff --git a/build/azDevOps/azure/azure-pipelines-javaspring-k8s.yml b/build/azDevOps/azure/azure-pipelines-javaspring-k8s.yml index 4abac5ac6..31695cf52 100644 --- a/build/azDevOps/azure/azure-pipelines-javaspring-k8s.yml +++ b/build/azDevOps/azure/azure-pipelines-javaspring-k8s.yml @@ -7,6 +7,12 @@ ############################################################################################################################# name: $(version_major).$(version_minor).$(version_patch)-$(Build.SourceBranchName)-$(Rev:r) +parameters: + - name: runVulnerabilityScan + displayName: Run OWASP Dependency Check + type: boolean + default: false + pr: - master @@ -138,7 +144,7 @@ variables: # Vulnerability Scan - name: vulnerability_scan - value: true + value: ${{ parameters.runVulnerabilityScan }} - name: vulnerability_scan_report value: "target/dependency-check-report.html" - name: oss_index_username diff --git a/build/azDevOps/azure/coverage/package-lock.json b/build/azDevOps/azure/coverage/package-lock.json index 30a9bb79f..acc17d6ae 100644 --- a/build/azDevOps/azure/coverage/package-lock.json +++ b/build/azDevOps/azure/coverage/package-lock.json @@ -270,16 +270,6 @@ "node": ">=10" } }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", @@ -1443,6 +1433,21 @@ "node": ">=10.13.0" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3168,6 +3173,16 @@ "dev": true, "license": "MIT" }, + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, "node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -3418,19 +3433,19 @@ } }, "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", + "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", "dev": true, "license": "MIT", "dependencies": { - "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", - "picocolors": "^1.0.0" + "picocolors": "^1.0.0", + "sax": "^1.5.0" }, "bin": { "svgo": "bin/svgo" diff --git a/docs/spring-boot-3.5-migration.md b/docs/spring-boot-3.5-migration.md index aee1a94b6..a3cef8765 100644 --- a/docs/spring-boot-3.5-migration.md +++ b/docs/spring-boot-3.5-migration.md @@ -11,7 +11,7 @@ The `stacks-modules-parent:3.0.98` brings in Spring Boot 3.5.7, which introduces **Problem:** The current Spring Cloud version (`2022.0.4`) is incompatible with Spring Boot 3.5.7. -``` +```text Spring Boot [3.5.7] is not compatible with this Spring Cloud release train. Change Spring Boot version to one of the following versions [3.0.x, 3.1.x]. ``` @@ -24,7 +24,7 @@ Update `spring.cloud.dependencies.version` to a version compatible with Spring B | 3.0.x, 3.1.x | 2022.0.x (Kilburn) | | 3.2.x | 2023.0.x (Leyton) | | 3.3.x, 3.4.x | 2024.0.x | -| 3.5.x | 2025.0.x | +| 3.5.x | 2024.0.x in this repository | **Workaround (current):** Projects can disable the compatibility verifier in `application-test.yml`: @@ -36,7 +36,7 @@ spring: enabled: false ``` -**Action Required:** Update parent POM to use Spring Cloud 2024.0.x or later (once 2025.0.x is available for Spring Boot 3.5.x support). +**Action Required:** Keep this repository on Spring Cloud 2024.0.x while it remains on the current parent POM and Spring Boot 3.5.x line. This repository now uses Spring Cloud 2024.0.3 because Spring Cloud 2025.1.1 pulled in `spring-cloud-config-client 5.0.1`, which is not compatible with the Spring Framework 6.2.x line provided by the current parent. --- @@ -45,7 +45,7 @@ spring: **Problem:** Spring Boot 3.5.x has stricter validation for Spring Security filter chains. Multiple `SecurityFilterChain` beans matching "any request" now throw an error: -``` +```text UnreachableFilterChainException: A filter chain that matches any request [...ApplicationConfig...] has already been configured, which means that this filter chain [...ApplicationNoSecurity...] will never get invoked. @@ -81,7 +81,7 @@ public class ApplicationNoSecurity { **Problem:** Spring Boot 3.5.x has stricter bean resolution when multiple beans of the same type exist through inheritance: -``` +```text NoUniqueBeanDefinitionException: expected single matching bean but found 2: menuService, menuServiceV2 ``` @@ -111,7 +111,7 @@ public class MenuServiceV2 extends MenuService { **Problem:** Property placeholders like `@aws.profile.name@` in `application.yml` are not being replaced because Maven resource filtering is not enabled by default. -``` +```text Profile '@aws.profile.name@' must start and end with a letter or digit ``` @@ -149,9 +149,9 @@ Enable resource filtering in `pom.xml`: ### Recommended (Should Add) -2. **Add default resource filtering configuration** so child projects don't need to configure it manually +1. **Add default resource filtering configuration** so child projects don't need to configure it manually -3. **Update documentation** to note the following breaking changes for downstream projects: +2. **Update documentation** to note the following breaking changes for downstream projects: - Security filter chain mutual exclusivity requirements - Bean resolution changes for inheritance hierarchies - Profile annotation requirements for conditional configurations @@ -160,12 +160,10 @@ Enable resource filtering in `pom.xml`: Until the parent POM is updated, the following workarounds have been applied: -| Issue | Workaround | File | -|--------------------------------|---------------------------------|-------------------------------------------| -| Spring Cloud incompatibility | Disabled compatibility verifier | `src/test/resources/application-test.yml` | -| Security filter chain conflict | Added `@Profile("!test")` | `ApplicationConfig.java` | -| Bean resolution conflict | Added `@Primary` | `MenuService.java` | -| Resource filtering | Added filtering config | `pom.xml` | +- Spring Cloud incompatibility: pin the BOM to `2024.0.3` and avoid Spring bootstrapping in mapper unit tests. Files: `java/pom.xml`, `java/src/test/java/com/amido/stacks/workloads/menu/mappers/DomainToDtoMapperMapstructTest.java` +- Security filter chain conflict: added `@Profile("!test")`. File: `ApplicationConfig.java` +- Bean resolution conflict: added `@Primary`. File: `MenuService.java` +- Resource filtering: added filtering config. File: `pom.xml` ## Testing Verification diff --git a/java/pom.xml b/java/pom.xml index 87c03022c..94cbd91f3 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -7,7 +7,7 @@ com.ensono.stacks.modules stacks-modules-parent - 3.0.111 + 3.0.139 com.amido.stacks.workloads @@ -28,15 +28,15 @@ 2.6.4 4.0.0 4.0.10 - 4.6.17 - 4.6.17 - 1.12.788 + 4.6.19 + 4.6.19 + 1.12.797 1.9.9.1 - 3.5.1 - 2025.0.0 + 3.6.3 + 2024.0.3 3.5.24 3.5.2 - 12.1.9 + 12.2.0 5.13.4 1.13.4 @@ -398,7 +398,7 @@ org.pitest pitest-junit5-plugin - 1.2.1 + 1.2.3 org.junit.platform diff --git a/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java b/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java index db8f210dc..d5193c0fc 100644 --- a/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java @@ -12,12 +12,14 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"management.port=0"}) @EnableAutoConfiguration @Tag("Component") +@ActiveProfiles("test") class ActuatorTest { @Value("${local.management.port}") diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/mappers/DomainToDtoMapperMapstructTest.java b/java/src/test/java/com/amido/stacks/workloads/menu/mappers/DomainToDtoMapperMapstructTest.java index 9b4a573b2..81360651a 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/mappers/DomainToDtoMapperMapstructTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/mappers/DomainToDtoMapperMapstructTest.java @@ -15,30 +15,32 @@ import java.util.UUID; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.util.ReflectionTestUtils; @Tag("Unit") -@SpringBootTest( - classes = { - MenuMapper.class, - MenuMapperImpl.class, - CategoryMapper.class, - CategoryMapperImpl.class, - ItemMapper.class, - ItemMapperImpl.class, - SearchMenuResultItemMapper.class, - SearchMenuResultItemMapperImpl.class - }) class DomainToDtoMapperMapstructTest { - @Autowired private MenuMapper menuMapper; + private final MenuMapper menuMapper; - @Autowired private CategoryMapper categoryMapper; + private final CategoryMapper categoryMapper; - @Autowired private ItemMapper itemMapper; + private final ItemMapper itemMapper; - @Autowired private SearchMenuResultItemMapper searchMenuResultItemMapper; + private final SearchMenuResultItemMapper searchMenuResultItemMapper; + + DomainToDtoMapperMapstructTest() { + itemMapper = new ItemMapperImpl(); + + CategoryMapperImpl categoryMapperImpl = new CategoryMapperImpl(); + ReflectionTestUtils.setField(categoryMapperImpl, "itemMapper", itemMapper); + categoryMapper = categoryMapperImpl; + + MenuMapperImpl menuMapperImpl = new MenuMapperImpl(); + ReflectionTestUtils.setField(menuMapperImpl, "categoryMapper", categoryMapper); + menuMapper = menuMapperImpl; + + searchMenuResultItemMapper = new SearchMenuResultItemMapperImpl(); + } @Test void menuToMenuDto() { diff --git a/java/src/test/resources/application-test.yml b/java/src/test/resources/application-test.yml new file mode 100644 index 000000000..650e48484 --- /dev/null +++ b/java/src/test/resources/application-test.yml @@ -0,0 +1,6 @@ +spring: + cloud: + compatibility-verifier: + enabled: false + config: + enabled: false