<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.netfoundry</groupId>
    <artifactId>frontdoor</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>frontdoor</name>
    <description>NetFoundry Frontdoor Service</description>
    <properties>
        <java.version>25</java.version>
        <bouncycastle.version>1.84</bouncycastle.version>
        <jacoco.version>0.8.13</jacoco.version>
        <aws-sdk.version>2.55.1</aws-sdk.version>
        <shedlock.version>6.10.0</shedlock.version>
        <spring-ai.version>1.1.8</spring-ai.version>
        <sonar.projectName>frontdoor</sonar.projectName>
        <sonar.projectKey>netfoundry_frontdoor</sonar.projectKey>
        <sonar.organization>netfoundry</sonar.organization>
        <sonar.host.url>https://sonarcloud.io</sonar.host.url>
        <sonar.sources>src/main</sonar.sources>
        <sonar.tests>src/test</sonar.tests>
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
        <sonar.java.pmd.reportPaths>target/dependency-check-report-pmd.xml</sonar.java.pmd.reportPaths>
        <sonar.exclusions>
            **/config/*
        </sonar.exclusions>
        <sonar.coverage.exclusions>
            **/config/*, **/external/**/*
        </sonar.coverage.exclusions>
        <sonar.cpd.exclusions/>
        <!-- Main-code rules that do not fit test code. Add one tN entry per rule. -->
        <sonar.issue.ignore.multicriteria>t1,t2,t3</sonar.issue.ignore.multicriteria>
        <!-- S1872: a test may compare against a private library class it cannot reference. -->
        <sonar.issue.ignore.multicriteria.t1.ruleKey>java:S1872</sonar.issue.ignore.multicriteria.t1.ruleKey>
        <sonar.issue.ignore.multicriteria.t1.resourceKey>src/test/**</sonar.issue.ignore.multicriteria.t1.resourceKey>
        <!-- S5778: more than one call in an assertThrows lambda. -->
        <sonar.issue.ignore.multicriteria.t2.ruleKey>java:S5778</sonar.issue.ignore.multicriteria.t2.ruleKey>
        <sonar.issue.ignore.multicriteria.t2.resourceKey>src/test/**</sonar.issue.ignore.multicriteria.t2.resourceKey>
        <!-- S1192: a test repeats string literals so each case reads on its own. -->
        <sonar.issue.ignore.multicriteria.t3.ruleKey>java:S1192</sonar.issue.ignore.multicriteria.t3.ruleKey>
        <sonar.issue.ignore.multicriteria.t3.resourceKey>src/test/**</sonar.issue.ignore.multicriteria.t3.resourceKey>

        <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
        <maven.compiler.release>25</maven.compiler.release>
        <surefire.reuseForks>true</surefire.reuseForks>
        <surefire.forkCount>1</surefire.forkCount>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Carries the servlet stack the actuator endpoints are served over, and what the REST API will build on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- The DataSource, JdbcTemplate and transaction manager the repository layer builds on. -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
        <!-- HAL+JSON for the REST API, which is the platform's representation convention. -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- Resource-change messages: the broker topology this service publishes on, and the cascade listeners that consume it. -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <!-- The audit index. The client and ElasticsearchTemplate are auto-configured from spring.elasticsearch.*; see io.netfoundry.audit.index. -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
        </dependency>
        <!-- RabbitListenerIdentityAspect binds the initiating identity around every listener, which needs AspectJ weaving. -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!-- Distributed locking and shared detector heartbeats, both backed by the Redis Redisson configures -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.52.0</version>
        </dependency>

        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-mysql</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- Logging and Tracing Dependencies -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-elastic</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-tracing-bridge-brave</artifactId>
        </dependency>
        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>8.1</version>
        </dependency>

        <!-- Misc Dependencies -->
        <dependency>
            <groupId>commons-validator</groupId>
            <artifactId>commons-validator</artifactId>
            <version>1.11.0</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.20.0</version>
        </dependency>
        <dependency>
            <groupId>net.jodah</groupId>
            <artifactId>failsafe</artifactId>
            <version>2.4.4</version>
        </dependency>
        <!--
            JsonNullable, which is how a PATCH body tells "omitted" apart from "sent as null" - the difference between leaving a field alone and clearing it.
            Self-registering: the jar ships a META-INF/services entry for JsonNullableModule, which Boot's Jackson builder finds on its own.

            Note for when the OpenAPI customizer lands: springdoc renders JsonNullable<T> as a wrapper schema rather than as T. customer-connect unwraps it in
            config/OpenApiConfiguration.java; copy that alongside the customizer.
        -->
        <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>jackson-databind-nullable</artifactId>
            <version>0.2.11</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--
			Documentation Dependencies

			The starter is COMPILE scope, not test, because the thing that fills in the examples runs inside the
			application: NetFoundryOpenApiCustomizer is a bean, it reads the captured snippets off the classpath, and
			the spec is served from /v3/api-docs. Copied from conflict-detection, which is where the annotations and
			the snippet round trip come from.

			`springdoc-openapi-hateoas` is deliberately NOT copied. The version the sibling carries - 1.8.0 - is the
			springdoc 1.x line and drags springdoc-openapi-common 1.8.0 onto a Boot 3.5 classpath. springdoc 2.x
			carries HATEOAS support in springdoc-openapi-starter-common, which the starter below already brings.
		-->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
            <version>2.9.1</version>
        </dependency>

        <!-- The MCP server: a stateless streamable-HTTP endpoint at /mcp on the servlet stack, so the platform auth chain runs on it. -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
        </dependency>

        <!--
            NetFoundryOpenApiCustomizer calls JsonRequestResponseSnippet.toKebabCase while building the spec, and that
            class `implements` restdocs' Snippet - so loading it on a request to /v3/api-docs needs restdocs at RUNTIME,
            not just in tests.
        -->
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-core</artifactId>
        </dependency>

        <dependency>
            <groupId>io.netfoundry</groupId>
            <artifactId>ziti-management-client</artifactId>
            <version>0.4.0</version>
        </dependency>
        <!-- @Process/@Step, the long-running workflow engine both siblings use. -->
        <dependency>
            <groupId>io.netfoundry</groupId>
            <artifactId>process-framework</artifactId>
            <version>0.39.0</version>
        </dependency>

        <!-- AWS. -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>secretsmanager</artifactId>
        </dependency>
        <!--
            Parameter Store, for the certificate material: each Frontdoor account's intermediate CA, each client
            certificate, and the enrollment JWT signing key. Secrets Manager holds the ingress identity instead,
            because that document is about 8 KB and a parameter caps at 8 KB even on the advanced tier.
        -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>ssm</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
        </dependency>
        <!-- Route53, for the NetFoundry DNS record that points an account's CNAME target at its ziti-ingress stack. -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>route53</artifactId>
        </dependency>
        <dependency>
            <groupId>io.netfoundry</groupId>
            <artifactId>common-util-framework</artifactId>
            <version>4.5.0</version>
        </dependency>
        <!-- RabbitMQ topology and the message envelope every sibling service publishes on. -->
        <dependency>
            <groupId>io.netfoundry</groupId>
            <artifactId>messaging-framework</artifactId>
            <version>0.12.0</version>
        </dependency>
        <!-- InterServiceTokenProvider, for the core-management call that mints controller credentials. -->
        <dependency>
            <groupId>io.netfoundry</groupId>
            <artifactId>authorization</artifactId>
            <version>2.12.1</version>
            <classifier>client</classifier>
            <exclusions>
                <!-- Excluding default (4.0) version of httpclient in favor of the newer one (5.0) -->
                <exclusion>
                    <groupId>org.apache.httpcomponents</groupId>
                    <artifactId>httpclient</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--
            JOSE, for the certificate enrollment JWT. It arrives transitively through authorization:client, but this
            service signs and verifies with it directly, so it is declared at the version already resolving rather
            than left to survive the next authorization bump by luck.
        -->
        <dependency>
            <groupId>org.bitbucket.b_c</groupId>
            <artifactId>jose4j</artifactId>
            <version>0.9.6</version>
        </dependency>
        <!-- Bounded caches for names and controller credentials. Versions come from spring-boot-dependencies. -->
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
        </dependency>
        <!-- A dead controller must not become this service's problem. -->
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-circuitbreaker</artifactId>
            <!-- Pinned. conflict-detection gets this from the spring-cloud BOM; importing that whole BOM for one
                 artifact would drag in far more version management than this service wants. -->
            <version>2.4.0</version>
        </dependency>

        <!-- One instance at a time runs a startup job. Same provider and version as zrok-connector. -->
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>${shedlock.version}</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.vaadin.external.google</groupId>
                    <artifactId>android-json</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-mockmvc</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-testcontainers</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- The database the repository layer is tested against. Version comes from the testcontainers BOM. -->
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mysql</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.redis</groupId>
            <artifactId>testcontainers-redis</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- The OpenZiti controller the container-backed repository tests run against. Same artifact and version customer-connect and
             ziti-management-client use, resolved from central. -->
        <dependency>
            <groupId>io.netfoundry</groupId>
            <artifactId>testcontainers-ziti-java</artifactId>
            <version>0.2.1</version>
            <scope>test</scope>
        </dependency>
        <!--
            A REAL broker, for the end-to-end tests that publish a captured message and assert an alert lands in
            Elasticsearch. The in-memory one below cannot serve them: it does not enforce queue arguments, and the
            listener container, the message converter and the AMQP connection are three of the seams those tests
            exist to cover. Version comes from the testcontainers BOM that spring-boot-dependencies imports.
        -->
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>rabbitmq</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>elasticsearch</artifactId>
            <scope>test</scope>
        </dependency>
        <!--
            Delivery is asynchronous, so the end-to-end tests wait on a condition rather than on a sleep. A sleep long
            enough to be reliable is far longer than the wait usually needs, and one that is not long enough fails as
            a flake blamed on the broker. Version comes from spring-boot-dependencies.
        -->
        <dependency>
            <groupId>org.awaitility</groupId>
            <artifactId>awaitility</artifactId>
            <scope>test</scope>
        </dependency>

        <!--
            An in-memory AMQP broker, so a test can declare the real topology and publish through it without Docker.
            The same choice core-management makes. Version matches theirs.

            Still the default for every context test - see MessagingTestConfiguration - so a test context needs no
            broker. The tests that need a broker that actually behaves like one ask for the container by property.
        -->
        <dependency>
            <groupId>com.github.fridujo</groupId>
            <artifactId>rabbitmq-mock</artifactId>
            <version>1.2.0</version>
            <scope>test</scope>
        </dependency>
        <!--
            BouncyCastle, for the ingress identity's enrollment. The Ziti controller signs a CSR this service
            builds, and answers the CA fetch with base64 PKCS#7, so both a PKCS#10 builder and a CMS parser are
            needed. `bcpkix` carries the CSR builder and pulls `bcprov`, which carries the CMS parser.
            `zrok-connector` runs the same pair for its own certificate work.
        -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk18on</artifactId>
            <version>${bouncycastle.version}</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws-sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!-- JDK 23+ no longer runs annotation processors found on the plain classpath.
                 Lombok must be declared here so javac gets an explicit processor path. -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

            <!--  provides Spring Boot support in Maven, letting you package executable jar or war archives and run an application “in-place” -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-info</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- will provide git information in the healthcheck endpoint -->
            <plugin>
                <groupId>pl.project13.maven</groupId>
                <artifactId>git-commit-id-plugin</artifactId>
                <version>4.9.10</version>
            </plugin>

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.3</version>
                <configuration>
                    <!-- Surefire reads the user properties reuseForks and forkCount, not these, so they are wired here explicitly. -->
                    <forkCount>${surefire.forkCount}</forkCount>
                    <reuseForks>${surefire.reuseForks}</reuseForks>
                    <rerunFailingTestsCount>1</rerunFailingTestsCount>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <systemPropertyVariables>
                        <org.springframework.restdocs.outputDir>
                            ${project.build.directory}/generated-snippets
                        </org.springframework.restdocs.outputDir>
                        <org.springframework.restdocs.javadocJsonDir>
                            ${project.build.directory}/generated-javadoc-json
                        </org.springframework.restdocs.javadocJsonDir>
                        <!-- One fork serves a whole run, so contexts with the same configuration start once. Matches core-management. -->
                        <spring.test.context.cache.maxSize>32</spring.test.context.cache.maxSize>
                    </systemPropertyVariables>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <excludes>
                                <exclude>**/config/*</exclude>
                                <exclude>**/FrontdoorApplication.class</exclude>
                            </excludes>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>target/jacoco.exec</dataFile>
                            <outputDirectory>target/jacoco-ut</outputDirectory>
                            <excludes>
                                <exclude>**/config/*</exclude>
                                <exclude>**/FrontdoorApplication.class</exclude>
                            </excludes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.sonarsource.scanner.maven</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>3.10.0.2594</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <profiles>
        <!--
            The CI fast lane: every test that is not tagged e2e, an untagged one included. It runs beside the Prepare
            stage while that provisions containers, so it must need none of them.

            One fork per core, because no test here starts a context or a container. The e2e lanes keep one fork each,
            because their tests share the lane's one MySQL and its context cache.
        -->
        <profile>
            <id>tests-fast</id>
            <properties>
                <surefire.forkCount>1C</surefire.forkCount>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <excludedGroups>e2e</excludedGroups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <!--
            Every e2e test in one fork. CI runs this profile after the fast lane, without `clean`, because jacoco
            appends to target/jacoco.exec and Sonar reads the coverage of both lanes.
        -->
        <profile>
            <id>tests-e2e</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <groups>e2e</groups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>test</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>pl.project13.maven</groupId>
                        <artifactId>git-commit-id-plugin</artifactId>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                    </plugin>

                    <!-- Surefire Plugin is used during the test phase of the build lifecycle to execute the unit tests of an application. It generates reports. -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.2.5</version>
                        <configuration>
                            <rerunFailingTestsCount>1</rerunFailingTestsCount>
                            <includes>
                                <include>**/*Test.java,*Test.java</include>
                            </includes>
                            <systemPropertyVariables>
                                <org.springframework.restdocs.outputDir>
                                    ${project.build.directory}/generated-snippets
                                </org.springframework.restdocs.outputDir>
                                <org.springframework.restdocs.javadocJsonDir>
                                    ${project.build.directory}/generated-javadoc-json
                                </org.springframework.restdocs.javadocJsonDir>
                                <spring.test.context.cache.maxSize>32</spring.test.context.cache.maxSize>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.jacoco</groupId>
                        <artifactId>jacoco-maven-plugin</artifactId>
                        <version>${jacoco.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>prepare-agent</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>report</id>
                                <phase>prepare-package</phase>
                                <goals>
                                    <goal>report</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>post-unit-test</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>report</goal>
                                </goals>
                                <configuration>
                                    <!-- Sets the path to the file which contains the execution
                                      data. -->
                                    <dataFile>target/jacoco.exec</dataFile>
                                    <!-- Sets the output directory for the code coverage report. -->
                                    <outputDirectory>target/jacoco-ut</outputDirectory>
                                </configuration>
                            </execution>
                        </executions>
                        <dependencies>
                            <dependency>
                                <groupId>com.fasterxml.jackson.core</groupId>
                                <artifactId>jackson-core</artifactId>
                                <version>2.16.1</version>
                            </dependency>
                            <dependency>
                                <groupId>com.fasterxml.jackson.core</groupId>
                                <artifactId>jackson-databind</artifactId>
                                <version>2.16.1</version>
                            </dependency>
                        </dependencies>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <!--
            OWASP dependency-check, matching alerting, core-management, sds and authorization.

            Neither plugin declares an <executions> block, so `verify -Pdependency_check` runs nothing - the profile
            supplies configuration for goals invoked by name:

              ./mvnw -Pdependency_check dependency-check:check xml:transform

            The first writes target/dependency-check-report.{xml,html,json}; the second turns the XML into a PMD
            report that Sonar reads as issues (see sonar.sh and the sonar.java.pmd.reportPaths property above).

            The paths are owasp/, not src/main/resources/ - files under src/main/resources get bundled into the
            built jar, which build-time-only config has no business in.

            No NVD API key is configured here. Without one the NVD feed is rate-limited hard, so the first run takes
            tens of minutes and can fail outright. Set -DnvdApiKey=... to make it usable.
        -->
        <profile>
            <id>dependency_check</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.owasp</groupId>
                        <artifactId>dependency-check-maven</artifactId>
                        <version>10.0.3</version>
                        <configuration>
                            <!-- Fail Build On CVSS core more than 8.0 which is HIGH-->
                            <!-- <failBuildOnCVSS>8</failBuildOnCVSS> -->
                            <!-- Generate all report formats -->
                            <format>ALL</format>
                            <!-- Don't use Nexus Analyzer -->
                            <retireJsAnalyzerEnabled>false</retireJsAnalyzerEnabled>
                            <centralAnalyzerEnabled>false</centralAnalyzerEnabled>
                            <ossindexAnalyzerEnabled>false</ossindexAnalyzerEnabled>
                            <!-- Am I the latest version? -->
                            <versionCheckEnabled>true</versionCheckEnabled>
                            <!--suppression Files -->
                            <suppressionFiles>owasp/suppressed.xml</suppressionFiles>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>xml-maven-plugin</artifactId>
                        <configuration>
                            <transformationSets>
                                <transformationSet>
                                    <dir>${project.build.directory}</dir>
                                    <includes>
                                        <include>dependency-check-report.xml</include>
                                    </includes>
                                    <stylesheet>owasp/dependencycheck_to_pmd.xsl</stylesheet>
                                    <outputDir>target</outputDir>
                                    <fileMappers>
                                        <fileMapper implementation="org.codehaus.plexus.components.io.filemappers.MergeFileMapper">
                                            <targetName>dependency-check-report-pmd.xml</targetName>
                                        </fileMapper>
                                    </fileMappers>
                                </transformationSet>
                            </transformationSets>
                        </configuration>
                        <dependencies>
                            <dependency>
                                <groupId>net.sf.saxon</groupId>
                                <artifactId>saxon</artifactId>
                                <version>8.7</version>
                            </dependency>
                        </dependencies>
                    </plugin>

                </plugins>
            </build>
        </profile>

    </profiles>

</project>
