该版本仍在开发中,尚未被视为稳定。对于最新的稳定版本,请使用 spring-cloud-contract 5.0.0!spring-doc.cadn.net.cn

我怎样才能使用带合同的通用仓库,而不是把合同存储给生产者?

另一种保存合同的方式,而不是与制片人共享,而是保留 他们在一个公共的地方。这种情况可能与安全问题有关(其中 消费者无法克隆生产者的代码)。另外,如果你把合同放在一个地方, 然后,作为生产者,你知道你有多少消费者,以及你可能破坏哪个消费者 随着你当地的变化。spring-doc.cadn.net.cn

仓库结构

假设我们有一个生产者,坐标为com.example:server三 消费者:客户1,客户端2客户端3.然后,在仓库里用 common 你可以设置以下内容(你可以在Spring Cloud Contract的仓库里查看) 样本/独立/合同子文件夹)。 以下列表展示了此类结构:spring-doc.cadn.net.cn

├── com
│   └── example
│       └── server
│           ├── client1
│           │   └── expectation.groovy
│           ├── client2
│           │   └── expectation.groovy
│           ├── client3
│           │   └── expectation.groovy
│           └── pom.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    └── assembly
        └── contracts.xml

在斜线划分下Groupid/artifact ID文件夹(com/example/server),你有 三位消费者的期望(客户1,客户端2客户端3).标准的Groovy DSL标准 合同文件,如本文档中所述。该仓库必须生成一个 JAR 文件,用于映射 与仓库内容一一对应。spring-doc.cadn.net.cn

以下示例展示了一个pom.xml文件内的服务器文件夹:spring-doc.cadn.net.cn

除了 Spring Cloud Contract Maven 插件外,没有其他依赖。 那些pom.xml文件是消费者端运行的必要条件mvn 干净安装 - DskipTests本地安装 制作人项目的简短稿。spring-doc.cadn.net.cn

pom.xml根文件夹中的文件可以如下样子:spring-doc.cadn.net.cn

它使用汇编插件来构建包含所有合同的 JAR。以下示例 展示了这样的设置:spring-doc.cadn.net.cn

工作流程

该工作流程假设 Spring Cloud Contract 既在消费者端设置,也在 制作人方面。在公共仓库中也有合适的插件设置 合同。CI 作业设置为一个公共仓库,以构建所有 artifact 然后上传到Nexus或Artifactory。下图展示了该模型的UML 工作流程:spring-doc.cadn.net.cn

如何共用仓库

消费者

当消费者希望离线处理合同,而不是克隆生产商时 代码,消费者团队克隆了公共仓库,然后送到所需的生产者那里 文件夹(例如,com/example/server)并运行mvn 干净安装 - DskipTests自 本地安装从合同转换的存根。spring-doc.cadn.net.cn

你需要本地安装 Maven

制作人

作为生产者,你可以修改 Spring Cloud 合约验证器以提供 URL 和 包含合同的JAR依赖关系如下:spring-doc.cadn.net.cn

<plugin>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
	<configuration>
		<contractsMode>REMOTE</contractsMode>
		<contractsRepositoryUrl>
			https://link/to/your/nexus/or/artifactory/or/sth
		</contractsRepositoryUrl>
		<contractDependency>
			<groupId>com.example.standalone</groupId>
			<artifactId>contracts</artifactId>
		</contractDependency>
	</configuration>
</plugin>

在这种配置下,JAR配备了群体com.example.standalone以及文物合同下载自链接/至/你的/Nexus/或/Artifactory/或/sth.是的 然后在本地临时文件夹中解压,合同则在com/example/server被选为用于生成测试和存根的样本。由于 根据该惯例,生产团队可以知道哪些消费者团队在何时被破坏 有些改动并不兼容。spring-doc.cadn.net.cn

其余的流程看起来都一样。spring-doc.cadn.net.cn

我如何定义每个主题的消息合约,而不是每个制作人?

为了避免消息契约在公共仓库中重复,当少数生产者对同一主题写消息时, 我们可以创建一个结构,将 REST 合同放在每个生产者和消息发送的文件夹中 合同会按主题放入文件夹。spring-doc.cadn.net.cn

对于Maven项目

为了使生产者端能够工作,我们应指定包含模式 通过发送感兴趣主题的消息过滤常见仓库的jar文件。这包含文件Maven Spring Cloud Contract 插件的属性 让我们来吧。也合同路径需要指定,因为默认路径是 公共仓库Groupid/Artifactid.以下示例展示了一个Maven Spring Cloud Contract的插件:spring-doc.cadn.net.cn

<plugin>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-contract-maven-plugin</artifactId>
   <version>${spring-cloud-contract.version}</version>
   <configuration>
      <contractsMode>REMOTE</contractsMode>
      <contractsRepositoryUrl>https://link/to/your/nexus/or/artifactory/or/sth</contractsRepositoryUrl>
      <contractDependency>
         <groupId>com.example</groupId>
         <artifactId>common-repo-with-contracts</artifactId>
         <version>+</version>
      </contractDependency>
      <contractsPath>/</contractsPath>
      <baseClassMappings>
         <baseClassMapping>
            <contractPackageRegex>.*messaging.*</contractPackageRegex>
            <baseClassFQN>com.example.services.MessagingBase</baseClassFQN>
         </baseClassMapping>
         <baseClassMapping>
            <contractPackageRegex>.*rest.*</contractPackageRegex>
            <baseClassFQN>com.example.services.TestBase</baseClassFQN>
         </baseClassMapping>
      </baseClassMappings>
      <includedFiles>
         <includedFile>**/${project.artifactId}/**</includedFile>
         <includedFile>**/${first-topic}/**</includedFile>
         <includedFile>**/${second-topic}/**</includedFile>
      </includedFiles>
   </configuration>
</plugin>
之前的 Maven 插件中的许多数值是可以更改的。我们把它包含在 为了说明,而不是试图提供一个“典型”的例子。

关于Gradle项目

要参与Gradle项目:spring-doc.cadn.net.cn

  1. 为公共仓库依赖添加自定义配置,具体如下:spring-doc.cadn.net.cn

    ext {
        contractsGroupId = "com.example"
        contractsArtifactId = "common-repo"
        contractsVersion = "1.2.3"
    }
    
    configurations {
        contracts {
            transitive = false
        }
    }
  2. 将通用仓库依赖添加到你的类路径中,具体如下:spring-doc.cadn.net.cn

    dependencies {
        contracts "${contractsGroupId}:${contractsArtifactId}:${contractsVersion}"
        testCompile "${contractsGroupId}:${contractsArtifactId}:${contractsVersion}"
    }
  3. 将依赖下载到相应文件夹,具体如下:spring-doc.cadn.net.cn

    task getContracts(type: Copy) {
        from configurations.contracts
        into new File(project.buildDir, "downloadedContracts")
    }
  4. 按以下方式打开罐子拉链:spring-doc.cadn.net.cn

    task unzipContracts(type: Copy) {
        def zipFile = new File(project.buildDir, "downloadedContracts/${contractsArtifactId}-${contractsVersion}.jar")
        def outputDir = file("${buildDir}/unpackedContracts")
    
        from zipTree(zipFile)
        into outputDir
    }
  5. 清理未使用的合同如下:spring-doc.cadn.net.cn

    task deleteUnwantedContracts(type: Delete) {
        delete fileTree(dir: "${buildDir}/unpackedContracts",
            include: "**/*",
            excludes: [
                "**/${project.name}/**"",
                "**/${first-topic}/**",
                "**/${second-topic}/**"])
    }
  6. 创建任务依赖关系,具体如下:spring-doc.cadn.net.cn

    unzipContracts.dependsOn("getContracts")
    deleteUnwantedContracts.dependsOn("unzipContracts")
    build.dependsOn("deleteUnwantedContracts")
  7. 通过指定包含合同的目录来配置插件,方法是设置 这contractsDslDir性质,具体如下:spring-doc.cadn.net.cn

    contracts {
        contractsDslDir = new File("${buildDir}/unpackedContracts")
    }