2.4. 修补 Red Hat Fuse 应用程序

使用新的 patch-maven-plugin 机制,您可以对 Red Hat Fuse 应用程序应用补丁。此机制允许您更改由不同 Red Hat Fuse BOMS 提供的独立版本,如 fuse-springboot-bomfuse-karaf-bom

2.4.1. 关于 patch-maven-plugin

patch-maven-plugin 执行以下操作:

  • 检索与当前 Red Hat Fuse BOM 相关的补丁元数据。
  • 将版本更改应用到从 BOMs 导入的 <dependencyManagement >。

patch-maven-plugin 获取元数据后,它会迭代声明插件的项目的所有受管和直接依赖项,并使用 CVE/patch 元数据替换依赖项版本(如果匹配)。替换了版本后,Maven 构建将继续,并通过标准 Maven 项目阶段进行进度。

2.4.2. 将补丁应用到 Red Hat Fuse 应用程序

patch-maven-plugin 的目的是将 Red Hat Fuse BOM 中列出的依赖项版本更新为您要应用到应用程序的补丁元数据中指定的版本。

步骤

以下流程解释了如何将补丁应用到您的应用程序。

  1. patch-maven-plugin 添加到项目的 pom.xml 文件中。patch-maven-plugin 的版本必须与 Fuse BOM 的版本相同。

    <build>
        <plugins>
            <plugin>
                <groupId>org.jboss.redhat-fuse</groupId>
                <artifactId>patch-maven-plugin</artifactId>
                <version>${version.org.jboss-redhat-fuse}</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
  2. 当您运行 mvn clean deploy mvn dependency:tree 命令中的任何一个时,插件会搜索项目模块来检查是否使用其中一个 Red Hat Fuse BOM。只有两个被认为是支持的 BOM:

    • org.jboss.redhat-fuse:fuse-karaf-bom: 用于 Fuse Karaf BOM
    • org.jboss.redhat-fuse:fuse-springboot-bom: 用于 Fuse Spring Boot BOM
  3. 如果没有找到以上 BOM,插件将显示以下信息:

    $ mvn clean install
    [INFO] Scanning for projects...
    [INFO]
    
    ========== Red Hat Fuse Maven patching ==========
    
    [INFO] [PATCH] No project in the reactor uses Fuse Karaf or Fuse Spring Boot BOM. Skipping patch processing.
    [INFO] [PATCH] Done in 3ms
  4. 如果同时找到了两个 Fuse BOM,patch-maven-plugin 会停止,并显示以下警告:

    $ mvn clean install
    [INFO] Scanning for projects...
    [INFO]
    
    ========== Red Hat Fuse Maven patching ==========
    
    [WARNING] [PATCH] Reactor uses both Fuse Karaf and Fuse Spring Boot BOMs. Please use only one. Skipping patch processing.
    [INFO] [PATCH] Done in 3ms
  5. patch-maven-plugin 尝试获取以下 Maven 元数据值之一。

    • 对于使用 Fuse Karaf BOM 的项目,org.jboss.redhat-fuse/fuse-karaf-patch-metadata/maven-metadata.xml 已解决。这是带有 org.jboss.redhat-fuse:fuse-karaf-patch-metadata:RELEASE 的工件的元数据。
    • 对于使用 Fuse Spring Boot BOM 项目的项目,org.jboss.redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml 已解决。这是带有 org.jboss.redhat-fuse:fuse-springboot-patch-metadata:RELEASE 的工件的元数据。

      Maven 生成的元数据示例

      <?xml version="1.0" encoding="UTF-8"?>
      <metadata>
        <groupId>org.jboss.redhat-fuse</groupId>
        <artifactId>fuse-springboot-patch-metadata</artifactId>
        <versioning>
          <release>7.8.1.fuse-sb2-781025</release>
          <versions>
            <version>7.8.0.fuse-sb2-780025</version>
            <version>7.7.0.fuse-sb2-770010</version>
            <version>7.7.0.fuse-770010</version>
            <version>7.8.1.fuse-sb2-781025</version>
          </versions>
          <lastUpdated>20201023131724</lastUpdated>
        </versioning>
      </metadata>

  6. patch-maven-plugin 解析元数据,以选择适用于当前项目的版本。这只适用于使用带有版本 7.8.xxx 的 Fuse BOM 的 Maven 项目。只有与版本范围 7.8、7.9 或更高版本匹配的元数据才适用,且只获取最新版本的元数据。
  7. patch-maven-plugin 收集在下载由 groupId、artifactId 和版本中找到的 groupIdartifactId 和版本 标识时使用的远程 Maven 存储库列表。这些 Maven 存储库是活跃配置集的项目 < repositories> 元素中列出的 Maven 存储库,以及来自 settings.xml 文件中的存储库。

    $ mvn clean install
    [INFO] Scanning for projects...
    [INFO]
    
    ========== Red Hat Fuse Maven patching ==========
    
    [INFO] [PATCH] Reading patch metadata and artifacts from 2 project repositories
    [INFO] [PATCH]  - local-nexus: http://everfree.forest:8081/repository/maven-releases/
    [INFO] [PATCH]  - central: https://repo.maven.apache.org/maven2
    Downloading from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml
    ...
  8. 另外,如果要使用离线存储库,您可以使用 -Dpatch 选项指定由 fuse-karaf/fuse-karaf-patch-repositoryfuse-springboot/fuse-springboot-patch - repository 模块生成的 ZIP 文件。这些 ZIP 文件与 Maven 存储库结构具有相同的内部结构。例如,

    $ mvn clean install -Dpatch=../../../test/resources/patch-3.zip
    [INFO] Scanning for projects...
    [INFO]
    
    ========== Red Hat Fuse Maven patching ==========
    
    [INFO] [PATCH] Reading metadata and artifacts from /data/sources/github.com/jboss-fuse/redhat-fuse/fuse-tools/patch-maven-plugin/src/test/resources/patch-3.zip
    Downloading from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml
    Downloaded from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml (406 B at 16 kB/s)
    Downloading from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml
    Downloaded from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml (926 B at 309 kB/s)
    [INFO] [PATCH] Resolved patch descriptor: /home/user/.m2/repository/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml
    ...
  9. 元数据是否来自远程存储库、本地存储库还是 ZIP 文件,它由 patch-maven-plugin 进行分析。获取的元数据包含 CVE 列表,以及每个 CVE 都有一个受影响的 Maven 工件列表(由 glob 模式和版本范围指定),以及一个包含给定 CVE 修复的版本。例如,

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <metadata xmlns="urn:redhat:fuse:patch-metadata:1">
        <product-bom groupId="org.jboss.redhat-fuse" artifactId="fuse-springboot-bom" versions="[7.8,7.9)" />
        <cves>
            <cve id="CVE-2020-xyz" description="Jetty can be configured to listen on port 8080"
                    cve-link="https://nvd.nist.gov/vuln/detail/CVE-2020-xyz"
                    bz-link="https://bugzilla.redhat.com/show_bug.cgi?id=42">
                <affects groupId="org.eclipse.jetty" artifactId="jetty-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" />
                <affects groupId="org.eclipse.jetty.http2" artifactId="http2-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" />
            </cve>
        </cves>
        <fixes />
    </metadata>
  10. 最后,当迭代当前项目中的所有受管依赖项时,会查阅补丁元数据中指定的修复列表。这些匹配的依赖项(和受管依赖项)会改为固定版本。例如:

    $ mvn clean install -U
    [INFO] Scanning for projects...
    [INFO
    
    ========== Red Hat Fuse Maven patching ==========
    
    [INFO] [PATCH] Reading patch metadata and artifacts from 2 project repositories
    [INFO] [PATCH]  - local-nexus: http://everfree.forest:8081/repository/maven-releases/
    [INFO] [PATCH]  - central: https://repo.maven.apache.org/maven2
    Downloading from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml
    Downloading from central: https://repo.maven.apache.org/maven2/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml
    Downloaded from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml (363 B at 4.3 kB/s)
    [INFO] [PATCH] Resolved patch descriptor: /home/user/.m2/repository/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-780032/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-780032.xml
    [INFO] [PATCH] Patch metadata found for org.jboss.redhat-fuse/fuse-springboot-bom/[7.8,7.9)
    [INFO] [PATCH]  - patch contains 1 CVE fix
    [INFO] [PATCH] Processing managed dependencies to apply CVE fixes... (https://nvd.nist.gov/vuln/detail/CVE-2020-xyz, https://bugzilla.redhat.com/show_bug.cgi?id=42_
    [INFO] [PATCH] - CVE-2020-xyz: Jetty can be configured to expose itself on port 8080
    [INFO] [PATCH]   Applying change org.eclipse.jetty/jetty-*/[9.4,9.4.32) -> 9.4.32.v20200930
    [INFO] [PATCH]    - managed dependency: org.eclipse.jetty/jetty-alpn-client/9.4.30.v20200611 -> 9.4.32.v20200930
    ...
    [INFO] [PATCH]    - managed dependency: org.eclipse.jetty/jetty-openid/9.4.30.v20200611 -> 9.4.32.v20200930
    [INFO] [PATCH]   Applying change org.eclipse.jetty.http2/http2-*/[9.4,9.4.32) -> 9.4.32.v20200930
    [INFO] [PATCH]    - managed dependency: org.eclipse.jetty.http2/http2-client/9.4.30.v20200611 -> 9.4.32.v20200930
    ...
    [INFO] [PATCH] Done in 635ms
    
    =================================================

跳过补丁

如果您不希望将特定补丁应用到项目,则 patch-maven-plugin 会提供 skip 选项。假设已将 patch-maven-plugin 添加到项目的 pom.xml 文件中,并且您不想更改版本,您可以使用以下任一方法跳过补丁。

  • 将 skip 选项添加到项目的 pom.xml 文件中,如下所示:
<build>
    <plugins>
        <plugin>
            <groupId>org.jboss.redhat-fuse</groupId>
            <artifactId>patch-maven-plugin</artifactId>
            <version>${version.org.jboss-redhat-fuse}</version>
            <extensions>true</extensions>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>
    </plugins>
</build>
  • 运行 mvn 命令时或使用 -DskipPatch 选项,如下所示:
$ mvn dependency:tree -DskipPatch
[INFO] Scanning for projects...
[INFO]
[INFO] ------< org.jboss.redhat-fuse:cve-dependency-management-module1 >-------
[INFO] Building cve-dependency-management-module1 7.8.0.fuse-sb2-780033
[INFO] --------------------------------[ jar ]---------------------------------
...

如上述输出中所示,patch-maven-plugin 没有调用,这会导致补丁不会应用到应用。