<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>io.confluent.flink</groupId>
    <artifactId>cp-flink-models-parent</artifactId>
    <version>0.1.0</version>
  </parent>

  <artifactId>cp-flink-ai-detect-anomalies</artifactId>
  <packaging>jar</packaging>

  <properties>
    <jackson.version>2.22.3</jackson.version>
    <!-- Outside io.confluent.cpflink.udf.ai, the package CMF treats as AI functions. -->
    <shaded.base>io.confluent.cpflink.udf.shaded</shaded.base>
  </properties>

  <dependencyManagement>
    <dependencies>
      <!-- Testcontainers' commons-compress needs a newer commons-io than Flink brings; with
           Flink's, copying a file into a container fails with NoSuchMethodError. -->
      <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.22.0</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!--
    CP Flink SQL's build of Flink, which the functions run on in a compute pool.
    provided: Flink is already on the cluster and in CMF's planner. Shading it in
    would break class identity (our AggregateFunction would not be Flink's).
    -->
    <dependency>
      <groupId>io.confluent.flink</groupId>
      <artifactId>flink-table-common</artifactId>
      <version>${flink.version}</version>
      <scope>provided</scope>
    </dependency>

    <!--
    compile scope on purpose: this is the reason the jar has to be an uber jar.
    CMF serves the UDF classloader from a fail-closed allowlist (java.*, javax.*,
    org.apache.flink.*, io.confluent.flink.*, org.slf4j.*, org.apache.kafka.*), so
    com.fasterxml.* is NOT visible from the host and must travel inside the artifact.
    The HTTP client, by contrast, is java.net.http (allowlisted), hence no OkHttp.
    -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>

    <!-- Test-only: local planner + mini-cluster. -->
    <dependency>
      <groupId>io.confluent.flink</groupId>
      <artifactId>flink-table-api-java-bridge</artifactId>
      <version>${flink.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.confluent.flink</groupId>
      <artifactId>flink-table-planner-loader</artifactId>
      <version>${flink.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.confluent.flink</groupId>
      <artifactId>flink-table-runtime</artifactId>
      <version>${flink.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.confluent.flink</groupId>
      <artifactId>flink-clients</artifactId>
      <version>${flink.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.14.4</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.27.7</version>
      <scope>test</scope>
    </dependency>
    <!-- The ITCase runs the stand-in model server from dummy-inference/ in a container. -->
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>testcontainers</artifactId>
      <version>2.0.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.6.0</version>
        <configuration>
          <argLine>
            --add-opens=java.base/java.util=ALL-UNNAMED
            --add-opens=java.base/java.lang=ALL-UNNAMED
          </argLine>
        </configuration>
      </plugin>

      <!-- Runs *ITCase classes in `verify`. They need Docker. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.6.0</version>
        <configuration>
          <argLine>
            --add-opens=java.base/java.util=ALL-UNNAMED
            --add-opens=java.base/java.lang=ALL-UNNAMED
          </argLine>
          <systemPropertyVariables>
            <dummyInferenceServer>${project.basedir}/../dummy-inference/server.py</dummyInferenceServer>
          </systemPropertyVariables>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>integration-test</goal>
              <goal>verify</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.6.2</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>shade</goal></goals>
            <configuration>
              <createDependencyReducedPom>false</createDependencyReducedPom>
              <!-- Keep the jar to our classes + Jackson. Without this, transitive
                   provided-scope Flink would not be included but test-scope noise could be. -->
              <artifactSet>
                <includes>
                  <include>io.confluent.flink:cp-flink-ai-detect-anomalies</include>
                  <include>com.fasterxml.jackson.core:*</include>
                </includes>
              </artifactSet>
              <relocations>
                <!-- Relocate so our Jackson cannot collide with whatever version
                     flink-dist happens to expose on the TaskManager. -->
                <relocation>
                  <pattern>com.fasterxml.jackson</pattern>
                  <shadedPattern>${shaded.base}.jackson</shadedPattern>
                </relocation>
              </relocations>
              <filters>
                <filter>
                  <artifact>*:*</artifact>
                  <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                    <exclude>module-info.class</exclude>
                    <!--
                    Jackson ships multi-release copies under META-INF/versions/N/.
                    The shade plugin does not rewrite package names inside those, so
                    they would sit in the jar as UNrelocated com.fasterxml classes that
                    our (relocated) code can never reference anyway. Dropping them leaves
                    the complete base implementation in place and keeps the invariant
                    "no unrelocated com/fasterxml in the artifact" checkable.
                    -->
                    <exclude>META-INF/versions/**</exclude>
                  </excludes>
                </filter>
              </filters>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
