1
1
package au.com.dius.pact.core.pactbroker
2
2
3
+ import arrow.core.Either
3
4
import au.com.dius.pact.com.github.michaelbull.result.Err
4
5
import au.com.dius.pact.com.github.michaelbull.result.Ok
5
6
import au.com.dius.pact.com.github.michaelbull.result.Result
6
7
import au.com.dius.pact.core.support.Json
8
+ import au.com.dius.pact.core.support.handleWith
7
9
import au.com.dius.pact.core.support.isNotEmpty
8
10
import com.github.salomonbrys.kotson.get
9
11
import com.github.salomonbrys.kotson.jsonArray
@@ -66,6 +68,13 @@ sealed class Latest {
66
68
67
69
data class CanIDeployResult (val ok : Boolean , val message : String , val reason : String )
68
70
71
+ /* *
72
+ * Consumer version selector. See https://docs.pact.io/pact_broker/advanced_topics/selectors
73
+ */
74
+ data class ConsumerVersionSelector (val tag : String , val latest : Boolean = true ) {
75
+ fun toJson () = jsonObject(" tag" to tag, " latest" to latest)
76
+ }
77
+
69
78
/* *
70
79
* Client for the pact broker service
71
80
*/
@@ -76,6 +85,8 @@ open class PactBrokerClient(val pactBrokerUrl: String, val options: Map<String,
76
85
/* *
77
86
* Fetches all consumers for the given provider
78
87
*/
88
+ @Deprecated(message = " Use the version that takes selectors instead" ,
89
+ replaceWith = ReplaceWith (" fetchConsumersWithSelectors" ))
79
90
open fun fetchConsumers (provider : String ): List <PactBrokerConsumer > {
80
91
return try {
81
92
val halClient = newHalClient()
@@ -99,6 +110,8 @@ open class PactBrokerClient(val pactBrokerUrl: String, val options: Map<String,
99
110
/* *
100
111
* Fetches all consumers for the given provider and tag
101
112
*/
113
+ @Deprecated(message = " Use the version that takes selectors instead" ,
114
+ replaceWith = ReplaceWith (" fetchConsumersWithSelectors" ))
102
115
open fun fetchConsumersWithTag (provider : String , tag : String ): List <PactBrokerConsumer > {
103
116
return try {
104
117
val halClient = newHalClient()
@@ -120,6 +133,48 @@ open class PactBrokerClient(val pactBrokerUrl: String, val options: Map<String,
120
133
}
121
134
}
122
135
136
+ /* *
137
+ * Fetches all consumers for the given provider and selectors
138
+ */
139
+ open fun fetchConsumersWithSelectors (provider : String , consumerVersionSelectors : List <ConsumerVersionSelector >): Either <Exception , List <PactResult >> {
140
+ val halClient = newHalClient()
141
+ val pactsForVerification = when {
142
+ halClient.linkUrl(PROVIDER_PACTS_FOR_VERIFICATION ) != null -> PROVIDER_PACTS_FOR_VERIFICATION
143
+ halClient.linkUrl(BETA_PROVIDER_PACTS_FOR_VERIFICATION ) != null -> BETA_PROVIDER_PACTS_FOR_VERIFICATION
144
+ else -> null
145
+ }
146
+ if (pactsForVerification != null ) {
147
+ val body = jsonObject(
148
+ " consumerVersionSelectors" to jsonArray(consumerVersionSelectors.map { it.toJson() })
149
+ )
150
+ return handleWith {
151
+ halClient.postJson(pactsForVerification, mapOf (" provider" to provider), body.toString()).map { result ->
152
+ result[" _embedded" ][" pacts" ].asJsonArray.map { pactJson ->
153
+ val selfLink = pactJson[" _links" ][" self" ]
154
+ val href = Precoded (Json .toString(selfLink[" href" ])).decoded().toString()
155
+ val name = Json .toString(selfLink[" name" ])
156
+ val notices = pactJson[" verificationProperties" ][" notices" ].asJsonArray
157
+ .map { VerificationNotice .fromJson(it) }
158
+ if (options.containsKey(" authentication" )) {
159
+ PactResult (name, href, pactBrokerUrl, options[" authentication" ] as List <String >, notices)
160
+ } else {
161
+ PactResult (name, href, pactBrokerUrl, emptyList(), notices)
162
+ }
163
+ }
164
+ }
165
+ }
166
+ } else {
167
+ return handleWith {
168
+ if (consumerVersionSelectors.isEmpty()) {
169
+ fetchConsumers(provider).map { PactResult .fromConsumer(it) }
170
+ } else {
171
+ fetchConsumersWithTag(provider, consumerVersionSelectors.first().tag)
172
+ .map { PactResult .fromConsumer(it) }
173
+ }
174
+ }
175
+ }
176
+ }
177
+
123
178
/* *
124
179
* Uploads the given pact file to the broker, and optionally applies any tags
125
180
*/
@@ -268,6 +323,8 @@ open class PactBrokerClient(val pactBrokerUrl: String, val options: Map<String,
268
323
/* *
269
324
* Fetches the consumers of the provider that have no associated tag
270
325
*/
326
+ @Deprecated(message = " Use the version that takes selectors instead" ,
327
+ replaceWith = ReplaceWith (" fetchConsumersWithSelectors" ))
271
328
open fun fetchLatestConsumersWithNoTag (provider : String ): List <PactBrokerConsumer > {
272
329
return try {
273
330
val halClient = newHalClient()
@@ -342,6 +399,8 @@ open class PactBrokerClient(val pactBrokerUrl: String, val options: Map<String,
342
399
const val LATEST_PROVIDER_PACTS_WITH_NO_TAG = " pb:latest-untagged-pact-version"
343
400
const val LATEST_PROVIDER_PACTS = " pb:latest-provider-pacts"
344
401
const val LATEST_PROVIDER_PACTS_WITH_TAG = " pb:latest-provider-pacts-with-tag"
402
+ const val PROVIDER_PACTS_FOR_VERIFICATION = " pb:provider-pacts-for-verification"
403
+ const val BETA_PROVIDER_PACTS_FOR_VERIFICATION = " beta:provider-pacts-for-verification"
345
404
const val PROVIDER = " pb:provider"
346
405
const val PROVIDER_TAG_VERSION = " pb:version-tag"
347
406
const val PACTS = " pb:pacts"
0 commit comments