我有一个奇怪的问题,我正在为消费者 A 创建第二个协议,第一个提供商是 B,现在我刚刚上传了提供商 C 的协议。问题是,虽然我在 UI 上看到了该协议,但当冰壶/打电话。
使用:
junit5 4.6.3 协议
契约经纪人2.110.0-pactbroker2.107.1
https://brokerurl/pacts/provider/C/for-verification
我看到这个
{"_embedded":{"pacts":[]},"_links":{"self":{"href":"https://brokerurl/pacts/provider/C/for-verification","title":"Pacts to be verified"}}}
我不知道问题是什么,因为我从消费者端的同一类上传合约。
有什么想法吗?
import au.com.dius.pact.consumer.MessagePactBuilder
import au.com.dius.pact.consumer.dsl.PactDslJsonBody
import au.com.dius.pact.consumer.junit5.PactConsumerTest
import au.com.dius.pact.consumer.junit5.PactTestFor
import au.com.dius.pact.consumer.junit5.ProviderType
import au.com.dius.pact.core.model.PactSpecVersion
import au.com.dius.pact.core.model.annotations.Pact
import au.com.dius.pact.core.model.messaging.Message
import au.com.dius.pact.core.model.messaging.MessagePact
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.traderepublic.schemas.avro4k.resolve.core.ConversationCreatedEvent
import com.traderepublic.schemas.avro4k.resolve.core.CustomerCreatedEvent
import org.junit.jupiter.api.Test
import kotlin.test.assertNull
@PactConsumerTest
class TestPactConsumerTest {
@Pact(
provider = "B",
consumer = "A",
)
fun bAsyncEvent(builder: MessagePactBuilder): MessagePact {
val body =
with(PactDslJsonBody()) {
uuid("id")
`object`("context")
.uuid("correlationId")
.closeObject()
`object`("payload")
.uuid("id")
.closeObject()
return@with this
}
return builder.expectsToReceive("create B created event")
.withContent(body)
.toPact()
}
@Test
@PactTestFor(
pactMethod = "bAsyncEvent",
providerType = ProviderType.ASYNCH,
pactVersion = PactSpecVersion.V3,
)
fun bCreatedAsyncEventTest(messages: List<Message>) {
val testObjectMapper = jacksonObjectMapper().registerModule(JavaTimeModule())
val message =
testObjectMapper.readValue(
messages.single().contentsAsString(),
CustomerCreatedEvent::class.java,
)
assertNull(message.context!!.trigger, "If the trigger is not set, it should be null")
}
@Pact(
provider = "C",
consumer = "A",
)
fun cCreatedAsyncEvent(builder: MessagePactBuilder): MessagePact {
val body =
with(PactDslJsonBody()) {
uuid("id")
`object`("payload")
.uuid("Id")
.closeObject()
return@with this
}
return builder.expectsToReceive("create C created event")
.withContent(body)
.toPact()
}
@Test
@PactTestFor(
pactMethod = "cCreatedAsyncEvent",
providerType = ProviderType.ASYNCH,
pactVersion = PactSpecVersion.V3,
)
fun cCreatedAsyncEventTest(messages: List<Message>) {
val testObjectMapper = jacksonObjectMapper().registerModule(JavaTimeModule())
val message =
testObjectMapper.readValue(
messages.single().contentsAsString(),
ConversationCreatedEvent::class.java,
)
assertNull(message.context, "If the context is not set, it should be null")
}
}
我还尝试为新服务 C 使用随机名称,例如(test-provider),但我得到了相同的错误,所以我想知道问题是否是期望的名称。欢迎任何帮助。
所以我发现最新协议的查询会在pact_publications
main
上搜索"branch_heads"."branch_name" AS "branch_name"
分支。
这是完整的查询:
SELECT "pact_publications".* FROM (SELECT "pact_publications".*, "branch_heads"."branch_name" AS "branch_name" FROM "pact_publications" INNER JOIN "pacticipants" AS "consumers" ON ("pact_publications"."consumer_id" = "consumers"."id")
INNER JOIN "branch_heads" ON (("pact_publications"."consumer_version_id" = "branch_heads"."version_id")
# The issue was on this inner join and on the second
AND ("consumers"."main_branch" = "branch_heads"."branch_name")) WHERE (("pact_publications"."provider_id" = 15) AND ("pact_publications"."consumer_id" IN (SELECT "pacticipants"."id" FROM "pacticipants" WHERE (("name" = 'resolve-core-ticket-service-async') AND ("pacticipants"."id" IS NOT NULL)))))) AS "pact_publications" INNER JOIN "latest_pact_publication_ids_for_consumer_versions" AS "lp" ON ("lp"."pact_publication_id" = "pact_publications"."id")
长话短说,如果您没有标记
main
,它不会返回。这有点破坏了我们对于加入应用程序的流程,但我们找到了解决方法。
此外,如果您的主分支是
master
,您可能需要更新您的 CI 或运行命令来更新参与者的主分支。
pact-broker create-or-update-pacticipant --name Foo --main-branch dev