Skip to content

Commit

Permalink
feat: Update Maven plugin with latest consumer version selectors
Browse files Browse the repository at this point in the history
  • Loading branch information
uglyog committed Aug 2, 2022
1 parent eb32583 commit 34d19e3
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ sealed class ConsumerVersionSelectors {
/**
* Corresponds to the old consumer version selectors
*/
@Deprecated(message = "Tags have been deprecated in favor of branches")
@Deprecated(message = "Old form of consumer version selectors have been deprecated in favor of the newer forms (Branches, Tags, etc.)")
data class Selector @JvmOverloads constructor(
val tag: String? = null,
val latest: Boolean? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,199 @@
package au.com.dius.pact.provider.maven

import au.com.dius.pact.core.pactbroker.ConsumerVersionSelectors
import org.apache.maven.plugin.MojoFailureException
import java.net.URL

data class EnablePending @JvmOverloads constructor(val providerTags: List<String> = emptyList())

abstract class BaseSelector {
abstract fun toSelector(): ConsumerVersionSelectors
}

/**
* The latest version from the main branch of each consumer, as specified by the consumer's mainBranch property.
*/
open class MainBranch() : BaseSelector() {
override fun toSelector() = ConsumerVersionSelectors.MainBranch

override fun toString(): String {
return "MainBranch"
}
}

/**
* The latest version from a particular branch of each consumer, or for a particular consumer if the second
* parameter is provided. If fallback is provided, falling back to the fallback branch if none is found from the
* specified branch.
*/
open class Branch : BaseSelector() {
var name: String = ""
var consumer: String? = null
var fallback: String? = null

override fun toSelector(): ConsumerVersionSelectors {
if (name.isEmpty()) {
throw MojoFailureException("Branch selector requires the 'name' attribute")
}

return ConsumerVersionSelectors.Branch(name, consumer, fallback)
}

override fun toString(): String {
return "Branch(name='$name', consumer=$consumer, fallback=$fallback)"
}
}

/**
* All the currently deployed and currently released and supported versions of each consumer.
*/
open class DeployedOrReleased(): BaseSelector() {
override fun toSelector() = ConsumerVersionSelectors.DeployedOrReleased

override fun toString(): String {
return "DeployedOrReleased"
}
}

/**
* The latest version from any branch of the consumer that has the same name as the current branch of the provider.
* Used for coordinated development between consumer and provider teams using matching feature branch names.
*/
open class MatchingBranch(): BaseSelector() {
override fun toSelector() = ConsumerVersionSelectors.MatchingBranch

override fun toString(): String {
return "MatchingBranch"
}
}

/**
* Any versions currently deployed to the specified environment
*/
open class DeployedTo: BaseSelector() {
var environment: String = ""

override fun toSelector(): ConsumerVersionSelectors {
if (environment.isEmpty()) {
throw MojoFailureException("DeployedTo selector requires the 'environment' attribute")
}

return ConsumerVersionSelectors.DeployedTo(environment)
}

override fun toString(): String {
return "DeployedTo(environment='$environment')"
}
}

/**
* Any versions currently released and supported in the specified environment
*/
open class ReleasedTo: BaseSelector() {
var environment: String = ""

override fun toSelector(): ConsumerVersionSelectors {
if (environment.isEmpty()) {
throw MojoFailureException("ReleasedTo selector requires the 'environment' attribute")
}

return ConsumerVersionSelectors.ReleasedTo(environment)
}

override fun toString(): String {
return "ReleasedTo(environment='$environment')"
}
}

/**
* Any versions currently deployed or released and supported in the specified environment
*/
open class Environment: BaseSelector() {
var name: String = ""

override fun toSelector(): ConsumerVersionSelectors {
if (name.isEmpty()) {
throw MojoFailureException("Environment selector requires the 'name' attribute")
}

return ConsumerVersionSelectors.Environment(name)
}

override fun toString(): String {
return "Environment(name='$name')"
}
}

/**
* All versions with the specified tag
*/
open class TagName: BaseSelector() {
var name: String = ""

override fun toSelector(): ConsumerVersionSelectors {
if (name.isEmpty()) {
throw MojoFailureException("TagName selector requires the 'name' attribute")
}

return ConsumerVersionSelectors.Tag(name)
}

override fun toString(): String {
return "TagName(name='$name')"
}
}

/**
* The latest version for each consumer with the specified tag. If fallback is provided, will fall back to the
* fallback tag if none is found with the specified tag
*/
open class LatestTag: BaseSelector() {
var name: String = ""
var fallback: String? = null

override fun toSelector(): ConsumerVersionSelectors {
if (name.isEmpty()) {
throw MojoFailureException("LatestTag selector requires the 'name' attribute")
}

return ConsumerVersionSelectors.LatestTag(name, fallback)
}

override fun toString(): String {
return "LatestTag(name='$name', fallback=$fallback)"
}
}

/**
* Corresponds to the old consumer version selectors
*/
open class Selector: BaseSelector() {
var tag: String? = null
var latest: Boolean? = null
var consumer: String? = null
var fallbackTag: String? = null

override fun toSelector() = ConsumerVersionSelectors.Selector(tag, latest, consumer, fallbackTag)

override fun toString(): String {
return "Selector(tag=$tag, latest=$latest, consumer=$consumer, fallbackTag=$fallbackTag)"
}
}

/**
* Bean to configure a pact broker to query
*/
data class PactBroker @JvmOverloads constructor(
val url: URL? = null,
@Deprecated("use consumer version selectors instead")
val tags: List<String>? = emptyList(),
val authentication: PactBrokerAuth? = null,
val serverId: String? = null,
var enablePending: EnablePending? = null,
@Deprecated("use consumer version selectors instead")
val fallbackTag: String? = null,
val insecureTLS: Boolean? = false
val insecureTLS: Boolean? = false,
val selectors: List<BaseSelector> = emptyList()
)

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package au.com.dius.pact.provider.maven

import au.com.dius.pact.core.model.FileSource
import au.com.dius.pact.core.model.Interaction
import au.com.dius.pact.core.pactbroker.ConsumerVersionSelector
import au.com.dius.pact.core.pactbroker.ConsumerVersionSelectors
import au.com.dius.pact.core.pactbroker.NotFoundHalResponse
import au.com.dius.pact.core.support.expressions.DataType
import au.com.dius.pact.core.support.expressions.ExpressionParser
import au.com.dius.pact.core.support.handleWith
import au.com.dius.pact.core.support.isNotEmpty
import au.com.dius.pact.core.support.toUrl
import au.com.dius.pact.provider.ConsumerInfo
import au.com.dius.pact.provider.IConsumerInfo
Expand Down Expand Up @@ -95,19 +101,37 @@ open class PactProviderMojo : PactBaseMojo() {

try {
val failures = serviceProviders.flatMap { provider ->
provider.host = if (provider.host is String) {
ExpressionParser.parseExpression(provider.host as String, DataType.RAW)
} else provider.host
provider.port = if (provider.port is String) {
ExpressionParser.parseExpression(provider.port as String, DataType.RAW)
} else provider.port

val consumers = mutableListOf<IConsumerInfo>()
consumers.addAll(provider.consumers)
consumers.addAll(provider.consumers.map {
if (it.pactSource is String) {
it.pactSource = FileSource<Interaction>(File(it.pactSource as String))
it
} else {
it
}
})

if (provider.pactFileDirectory != null) {
consumers.addAll(loadPactFiles(provider, provider.pactFileDirectory!!))
}

if (provider.pactFileDirectories != null && provider.pactFileDirectories!!.isNotEmpty()) {
provider.pactFileDirectories!!.forEach {
consumers.addAll(loadPactFiles(provider, it))
}
}

if (provider.pactBrokerUrl != null || provider.pactBroker != null) {
loadPactsFromPactBroker(provider, consumers)
}

if (provider.pactFileDirectory == null &&
(provider.pactFileDirectories == null || provider.pactFileDirectories!!.isEmpty()) &&
provider.pactBrokerUrl == null && provider.pactBroker == null && (
Expand Down Expand Up @@ -165,7 +189,7 @@ open class PactProviderMojo : PactBaseMojo() {
options["insecureTLS"] = true
}

when {
val selectors = when {
pactBroker?.enablePending != null -> {
if (pactBroker.enablePending!!.providerTags.isEmpty()) {
throw MojoFailureException("""
Expand All @@ -180,27 +204,34 @@ open class PactProviderMojo : PactBaseMojo() {
|</enablePending>
""".trimMargin())
}
val selectors = pactBroker.tags?.map {
ConsumerVersionSelector(it, true, fallbackTag = pactBroker.fallbackTag) } ?: emptyList()
consumers.addAll(provider.hasPactsFromPactBrokerWithSelectors(options +
mapOf("enablePending" to true, "providerTags" to pactBroker.enablePending!!.providerTags),
pactBrokerUrl.toString(), selectors))
options.putAll(mapOf("enablePending" to true, "providerTags" to pactBroker.enablePending!!.providerTags))
if (pactBroker.selectors.isNotEmpty()) {
pactBroker.selectors.map { it.toSelector() }
} else {
pactBroker.tags?.map {
ConsumerVersionSelectors.Selector(it, true, fallbackTag = pactBroker.fallbackTag)
} ?: emptyList()
}
}
pactBroker?.tags != null && pactBroker.tags.isNotEmpty() -> {
val selectors = pactBroker.tags.map {
ConsumerVersionSelector(it, true, fallbackTag = pactBroker.fallbackTag) }
consumers.addAll(provider.hasPactsFromPactBrokerWithSelectors(options, pactBrokerUrl.toString(), selectors))
pactBroker?.selectors.isNotEmpty() -> pactBroker?.selectors?.map { it.toSelector() } ?: emptyList()
pactBroker?.tags.isNotEmpty() -> {
log.warn("Tags are deprecated. Use selectors instead.")
pactBroker?.tags?.map {
ConsumerVersionSelectors.Selector(it, true, fallbackTag = pactBroker.fallbackTag)
} ?: emptyList()
}
else -> consumers.addAll(
handleWith<List<ConsumerInfo>> {
provider.hasPactsFromPactBrokerWithSelectors(options, pactBrokerUrl.toString(), emptyList())
}.getOrElse { handleException(it) }
)
else -> emptyList()
}

consumers.addAll(
handleWith<List<ConsumerInfo>> {
provider.hasPactsFromPactBrokerWithSelectorsV2(options, pactBrokerUrl.toString(), selectors)
}.getOrElse { handleException(it) }
)
}

private fun handleException(exception: Exception): List<ConsumerInfo> {
return when (exception) {
return when (exception.cause) {
is NotFoundHalResponse -> when {
failIfNoPactsFound -> throw exception
else -> emptyList()
Expand Down
Loading

0 comments on commit 34d19e3

Please sign in to comment.