From 2ab9e38a3845fd2c2e29d2869177298814c1b4ab Mon Sep 17 00:00:00 2001 From: jbwheatley Date: Tue, 20 Oct 2020 10:28:49 +0100 Subject: [PATCH] use pactBrokerClientTimeout setting for result publisher too (#183) --- .../itv/scalapact/plugin/ScalaPactEnv.scala | 3 +- .../shared/ScalaPactVerifyCommand.scala | 4 +- .../itv/scalapactcore/verifier/Verifier.scala | 14 +- .../http4s16a/impl/HttpInstances.scala | 7 +- .../http4s16a/impl/ResultPublisher.scala | 38 ++--- .../http4s16a/impl/ResultPublisherSpec.scala | 3 +- .../impl/ScalaPactHttpClientSpec.scala | 86 ++++++------ .../http4s17/impl/HttpInstances.scala | 7 +- .../http4s17/impl/ResultPublisher.scala | 36 ++--- .../http4s17/impl/ResultPublisherSpec.scala | 3 +- .../impl/ScalaPactHttpClientSpec.scala | 132 +++++++++--------- .../http4s18/impl/HttpInstances.scala | 7 +- .../http4s18/impl/ResultPublisher.scala | 42 +++--- .../http4s18/impl/ResultPublisherSpec.scala | 3 +- .../impl/ScalaPactHttpClientSpec.scala | 82 ++++++----- .../http4s20/impl/Http4sClientHelper.scala | 19 +-- .../http4s20/impl/HttpInstances.scala | 7 +- .../http4s20/impl/ResultPublisher.scala | 69 ++++----- .../http4s20/impl/ScalaPactHttpClient.scala | 14 +- .../http4s20/impl/ResultPublisherSpec.scala | 3 +- .../impl/ScalaPactHttpClientSpec.scala | 86 ++++++------ .../http4s21/impl/Http4sClientHelper.scala | 13 +- .../http4s21/impl/HttpInstances.scala | 8 +- .../http4s21/impl/ResultPublisher.scala | 52 +++---- .../http4s21/impl/ScalaPactHttpClient.scala | 14 +- .../http4s21/impl/ResultPublisherSpec.scala | 3 +- .../impl/ScalaPactHttpClientSpec.scala | 86 ++++++------ .../com/itv/scalapact/ScalaPactVerify.scala | 30 ++-- .../scalapact/shared/ScalaPactSettings.scala | 2 + .../{ => typeclasses}/IResultPublisher.scala | 6 +- .../typeclasses/IResultPublisherBuilder.scala | 7 + 31 files changed, 422 insertions(+), 464 deletions(-) rename scalapact-shared/src/main/scala/com/itv/scalapact/shared/{ => typeclasses}/IResultPublisher.scala (68%) create mode 100644 scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisherBuilder.scala diff --git a/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/ScalaPactEnv.scala b/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/ScalaPactEnv.scala index 3ec882ced..d86be0ae4 100644 --- a/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/ScalaPactEnv.scala +++ b/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/ScalaPactEnv.scala @@ -1,6 +1,7 @@ package com.itv.scalapact.plugin -import com.itv.scalapact.shared.{BrokerPublishData, ScalaPactSettings} +import com.itv.scalapact.shared.ScalaPactSettings +import com.itv.scalapact.shared.typeclasses.BrokerPublishData import scala.concurrent.duration._ diff --git a/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/shared/ScalaPactVerifyCommand.scala b/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/shared/ScalaPactVerifyCommand.scala index b3975766a..043a115d4 100644 --- a/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/shared/ScalaPactVerifyCommand.scala +++ b/sbt-scalapact-shared/src/main/scala/com/itv/scalapact/plugin/shared/ScalaPactVerifyCommand.scala @@ -3,7 +3,7 @@ package com.itv.scalapact.plugin.shared import com.itv.scalapact.shared.ColourOutput._ import com.itv.scalapact.shared._ import com.itv.scalapactcore.common.LocalPactFileLoader -import com.itv.scalapact.shared.typeclasses.{IPactReader, IPactWriter, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.typeclasses.{IPactReader, IPactWriter, IResultPublisherBuilder, IScalaPactHttpClientBuilder} import com.itv.scalapact.shared.ProviderStateResult.SetupProviderState import com.itv.scalapactcore.verifier.Verifier @@ -29,7 +29,7 @@ object ScalaPactVerifyCommand { )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher): Unit = { + publisher: IResultPublisherBuilder): Unit = { PactLogger.message("*************************************".white.bold) PactLogger.message("** ScalaPact: Running Verifier **".white.bold) PactLogger.message("*************************************".white.bold) diff --git a/scalapact-core/src/main/scala/com/itv/scalapactcore/verifier/Verifier.scala b/scalapact-core/src/main/scala/com/itv/scalapactcore/verifier/Verifier.scala index 25726c97e..e74254521 100644 --- a/scalapact-core/src/main/scala/com/itv/scalapactcore/verifier/Verifier.scala +++ b/scalapact-core/src/main/scala/com/itv/scalapactcore/verifier/Verifier.scala @@ -8,11 +8,13 @@ import com.itv.scalapactcore.common._ import scala.util.Left import com.itv.scalapact.shared.PactLogger import com.itv.scalapact.shared.ProviderStateResult.SetupProviderState -import com.itv.scalapact.shared.typeclasses.{IPactReader, IPactWriter, IScalaPactHttpClient, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.typeclasses.{IPactReader, IPactWriter, IResultPublisherBuilder, IScalaPactHttpClient, IScalaPactHttpClientBuilder} + +import scala.concurrent.duration.DurationInt class Verifier[F[_]](pactBrokerClient: PactBrokerClient[F])(implicit pactReader: IPactReader, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher) { + publisherBuilder: IResultPublisherBuilder) { def verify( loadPactFiles: String => ScalaPactSettings => List[Pact], @@ -105,9 +107,11 @@ class Verifier[F[_]](pactBrokerClient: PactBrokerClient[F])(implicit pactReader: else PactLogger.message(scalaPactLogPrefix + s"$failureCount Pact verify tests failed.".red) - arguments.publishResultsEnabled.foreach( + arguments.publishResultsEnabled.foreach { + val publisher = publisherBuilder + .build(pactVerifySettings.pactBrokerClientTimeout.getOrElse(2.seconds), pactVerifySettings.sslContextName) publisher.publishResults(pactVerifyResults, _, pactVerifySettings.pactBrokerAuthorization) - ) + } testCount > 0 && failureCount == 0 } @@ -185,7 +189,7 @@ object Verifier { def apply[F[_]](implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClient: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher): Verifier[F] = + publisher: IResultPublisherBuilder): Verifier[F] = new Verifier[F](new PactBrokerClient[F]) } diff --git a/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/HttpInstances.scala b/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/HttpInstances.scala index aca9d2a84..213d596b2 100644 --- a/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/HttpInstances.scala +++ b/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/HttpInstances.scala @@ -1,7 +1,7 @@ package com.itv.scalapact.http4s16a.impl -import com.itv.scalapact.shared.typeclasses.{IPactStubber, IScalaPactHttpClientBuilder} -import com.itv.scalapact.shared.{IResultPublisher, SslContextMap} +import com.itv.scalapact.shared.typeclasses.{IPactStubber, IResultPublisherBuilder, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.SslContextMap import scalaz.concurrent.Task import scala.concurrent.duration.Duration @@ -16,5 +16,6 @@ trait HttpInstances { implicit def httpClientBuilder(implicit sslContextMap: SslContextMap): IScalaPactHttpClientBuilder[Task] = (clientTimeout: Duration, sslContextName: Option[String]) => ScalaPactHttpClient(clientTimeout, sslContextName) - implicit val resultPublisher: IResultPublisher = new ResultPublisher(Http4sClientHelper.doRequest) + implicit def resultPublisherBuilder(implicit sslContextMap: SslContextMap): IResultPublisherBuilder = + (clientTimeout: Duration, sslContextName: Option[String]) => ResultPublisher(clientTimeout, sslContextName) } diff --git a/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/ResultPublisher.scala b/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/ResultPublisher.scala index 1fcd79962..f9706181f 100644 --- a/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/ResultPublisher.scala +++ b/scalapact-http4s-0-16a/src/main/scala/com/itv/scalapact/http4s16a/impl/ResultPublisher.scala @@ -2,20 +2,17 @@ package com.itv.scalapact.http4s16a.impl import com.itv.scalapact.shared.ColourOutput._ import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.{BrokerPublishData, IResultPublisher} import org.http4s.client.Client import scalaz.concurrent.Task import scala.concurrent.duration._ -class ResultPublisher(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) extends IResultPublisher { - - val maxTotalConnections: Int = 2 - private val clientTimeout = 10.seconds - +class ResultPublisher(client: Client)(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) extends IResultPublisher { override def publishResults( pactVerifyResults: List[PactVerifyResult], brokerPublishData: BrokerPublishData, - pactBrokerAuthorization: Option[PactBrokerAuthorization])(implicit sslContextMap: SslContextMap): Unit = { + pactBrokerAuthorization: Option[PactBrokerAuthorization]): Unit = { val list = pactVerifyResults.map { result => result.pact._links.flatMap(_.get("pb:publish-verification-results")).map(_.href) match { case Some(link) => @@ -29,20 +26,15 @@ class ResultPublisher(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) None ) - SslContextMap(request)( - sslContext => - simpleRequestWithoutFakeHeader => { - val client = Http4sClientHelper.buildPooledBlazeHttpClient(maxTotalConnections, clientTimeout, sslContext) - fetcher(simpleRequestWithoutFakeHeader, client) - .map { response => - if (response.is2xx) { - PactLogger.message(s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}") - } else { - PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) - } - } + fetcher(request, client) + .map { response => + if (response.is2xx) { + PactLogger.message(s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}") + } else { + PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) } - ) + } + case None => Task.now(PactLogger.error("Unable to publish verification results as there is no pb:publish-verification-results link".red)) } @@ -55,4 +47,12 @@ class ResultPublisher(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) val buildUrl = brokerPublishData.buildUrl.fold("")(u => s""", "buildUrl": "$u"""") Option(s"""{ "success": $success, "providerApplicationVersion": "${brokerPublishData.providerVersion}"$buildUrl }""") } +} + +object ResultPublisher { + def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IResultPublisher = { + val sslContext = sslContextMap(sslContextName) + val client = Http4sClientHelper.buildPooledBlazeHttpClient(2, clientTimeout, sslContext) + new ResultPublisher(client)(Http4sClientHelper.doRequest) + } } \ No newline at end of file diff --git a/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ResultPublisherSpec.scala b/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ResultPublisherSpec.scala index 3e122a15d..f32713546 100644 --- a/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ResultPublisherSpec.scala +++ b/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ResultPublisherSpec.scala @@ -1,5 +1,6 @@ package com.itv.scalapact.http4s16a.impl import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.BrokerPublishData import org.http4s.client.Client import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} import scalaz.concurrent.Task @@ -54,7 +55,7 @@ class ResultPublisherSpec extends FunSpec with Matchers with BeforeAndAfter { Task.now(SimpleResponse(200)) } - private val resultPublisher = new ResultPublisher(fakeCaller) + private val resultPublisher = new ResultPublisher(null)(fakeCaller) before { requests = ArrayBuffer.empty[SimpleRequest] diff --git a/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ScalaPactHttpClientSpec.scala b/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ScalaPactHttpClientSpec.scala index c9d4f1892..c5b59d8f1 100644 --- a/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ScalaPactHttpClientSpec.scala +++ b/scalapact-http4s-0-16a/src/test/scala/com/itv/scalapact/http4s16a/impl/ScalaPactHttpClientSpec.scala @@ -1,44 +1,42 @@ -//package com.itv.scalapact.http4s16a.impl -// -//import com.itv.scalapact.shared._ -//import org.http4s.client.Client -//import org.scalatest.{FunSpec, Matchers} -//import scalaz.concurrent.Task -// -//import scala.concurrent.duration._ -// -//class ScalaPactHttpClientSpec extends FunSpec with Matchers { -// -// describe("Making an interaction request") { -// -// it("should be able to make and interaction request and get an interaction response") { -// -// val requestDetails = InteractionRequest( -// method = Some("GET"), -// headers = None, -// query = None, -// path = Some("/foo"), -// body = None, -// matchingRules = None -// ) -// -// val responseDetails = InteractionResponse( -// status = Some(200), -// headers = None, -// body = None, -// matchingRules = None -// ) -// -// val fakeCaller: (SimpleRequest, Client) => Task[SimpleResponse] = (_, _) => Task.now(SimpleResponse(200)) -// -// val result = new ScalaPactHttpClient(fakeCaller) -// .doInteractionRequest("", requestDetails, 1.second, sslContextName = None) -// .unsafePerformSync -// -// result shouldEqual responseDetails -// -// } -// -// } -// -//} +package com.itv.scalapact.http4s16a.impl + +import com.itv.scalapact.shared._ +import org.http4s.client.Client +import org.scalatest.{FunSpec, Matchers} +import scalaz.concurrent.Task + +class ScalaPactHttpClientSpec extends FunSpec with Matchers { + + describe("Making an interaction request") { + + it("should be able to make and interaction request and get an interaction response") { + + val requestDetails = InteractionRequest( + method = Some("GET"), + headers = None, + query = None, + path = Some("/foo"), + body = None, + matchingRules = None + ) + + val responseDetails = InteractionResponse( + status = Some(200), + headers = None, + body = None, + matchingRules = None + ) + + val fakeCaller: (SimpleRequest, Client) => Task[SimpleResponse] = (_, _) => Task.now(SimpleResponse(200)) + + val result = new ScalaPactHttpClient(null)(fakeCaller) + .doInteractionRequest("", requestDetails) + .unsafePerformSync + + result shouldEqual responseDetails + + } + + } + +} diff --git a/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/HttpInstances.scala b/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/HttpInstances.scala index 2cee80907..f9f64db57 100644 --- a/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/HttpInstances.scala +++ b/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/HttpInstances.scala @@ -1,7 +1,7 @@ package com.itv.scalapact.http4s17.impl -import com.itv.scalapact.shared.typeclasses.{IPactStubber, IScalaPactHttpClientBuilder} -import com.itv.scalapact.shared.{IResultPublisher, SslContextMap} +import com.itv.scalapact.shared.typeclasses.{IPactStubber, IResultPublisherBuilder, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.SslContextMap import fs2.Task import scala.concurrent.duration.Duration @@ -16,5 +16,6 @@ trait HttpInstances { implicit def httpClientBuilder(implicit sslContextMap: SslContextMap): IScalaPactHttpClientBuilder[Task] = (clientTimeout: Duration, sslContextName: Option[String]) => ScalaPactHttpClient(clientTimeout, sslContextName) - implicit val resultPublisher: IResultPublisher = new ResultPublisher(Http4sClientHelper.doRequest) + implicit def resultPublisherBuilder(implicit sslContextMap: SslContextMap): IResultPublisherBuilder = + (clientTimeout: Duration, sslContextName: Option[String]) => ResultPublisher(clientTimeout, sslContextName) } diff --git a/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/ResultPublisher.scala b/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/ResultPublisher.scala index bcf984143..7c14f0bc1 100644 --- a/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/ResultPublisher.scala +++ b/scalapact-http4s-0-17/src/main/scala/com/itv/scalapact/http4s17/impl/ResultPublisher.scala @@ -2,17 +2,15 @@ package com.itv.scalapact.http4s17.impl import com.itv.scalapact.shared.ColourOutput._ import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.{BrokerPublishData, IResultPublisher} import fs2.Task import org.http4s.client.Client import scala.concurrent.duration._ -class ResultPublisher(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) extends IResultPublisher { +class ResultPublisher(client: Client)(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) extends IResultPublisher { - val maxTotalConnections: Int = 2 - private val clientTimeout = 10.seconds - - override def publishResults(pactVerifyResults: List[PactVerifyResult], brokerPublishData: BrokerPublishData, pactBrokerAuthorization: Option[PactBrokerAuthorization])(implicit sslContextMap: SslContextMap): Unit = { + override def publishResults(pactVerifyResults: List[PactVerifyResult], brokerPublishData: BrokerPublishData, pactBrokerAuthorization: Option[PactBrokerAuthorization]): Unit = { Task.traverse(pactVerifyResults){ result => result.pact._links.flatMap(_.get("pb:publish-verification-results")).map(_.href) match { case Some(link) => @@ -26,20 +24,14 @@ class ResultPublisher(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) None ) - SslContextMap(request)( - sslContext => - simpleRequestWithoutFakeHeader => { - val client = Http4sClientHelper.buildPooledBlazeHttpClient(maxTotalConnections, clientTimeout, sslContext) - fetcher(simpleRequestWithoutFakeHeader, client) - .map { response => - if (response.is2xx) { - PactLogger.message(s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}") - } else { - PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) - } - } + fetcher(request, client) + .map { response => + if (response.is2xx) { + PactLogger.message(s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}") + } else { + PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) } - ) + } case None => Task.now(PactLogger.error("Unable to publish verification results as there is no pb:publish-verification-results link".red)) } @@ -51,3 +43,11 @@ class ResultPublisher(fetcher: (SimpleRequest, Client) => Task[SimpleResponse]) Option(s"""{ "success": $success, "providerApplicationVersion": "${brokerPublishData.providerVersion}"$buildUrl }""") } } + +object ResultPublisher { + def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IResultPublisher = { + val sslContext = sslContextMap(sslContextName) + val client = Http4sClientHelper.buildPooledBlazeHttpClient(2, clientTimeout, sslContext) + new ResultPublisher(client)(Http4sClientHelper.doRequest) + } +} \ No newline at end of file diff --git a/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ResultPublisherSpec.scala b/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ResultPublisherSpec.scala index ed4a75bd8..4a6d73a73 100644 --- a/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ResultPublisherSpec.scala +++ b/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ResultPublisherSpec.scala @@ -1,5 +1,6 @@ package com.itv.scalapact.http4s17.impl import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.BrokerPublishData import fs2.Task import org.http4s.client.Client import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} @@ -54,7 +55,7 @@ class ResultPublisherSpec extends FunSpec with Matchers with BeforeAndAfter { Task.now(SimpleResponse(200)) } - private val resultPublisher = new ResultPublisher(fakeCaller) + private val resultPublisher = new ResultPublisher(null)(fakeCaller) before { requests = ArrayBuffer.empty[SimpleRequest] diff --git a/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ScalaPactHttpClientSpec.scala b/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ScalaPactHttpClientSpec.scala index f12011861..c63da3468 100644 --- a/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ScalaPactHttpClientSpec.scala +++ b/scalapact-http4s-0-17/src/test/scala/com/itv/scalapact/http4s17/impl/ScalaPactHttpClientSpec.scala @@ -1,73 +1,71 @@ -//package com.itv.scalapact.http4s17.impl +package com.itv.scalapact.http4s17.impl + +import com.itv.scalapact.shared._ +import fs2.Task +import org.http4s.client.Client +import org.scalamock.scalatest.MockFactory +import org.scalatest.{FunSpec, Matchers} + +class ScalaPactHttpClientSpec extends FunSpec with Matchers with MockFactory { + + val requestDetails = InteractionRequest( + method = Some("GET"), + headers = None, + query = None, + path = Some("/foo"), + body = None, + matchingRules = None + ) + + val responseDetails = InteractionResponse( + status = Some(200), + headers = None, + body = None, + matchingRules = None + ) + + describe("Making an interaction request") { + + it("should be able to make and interaction request and get an interaction response") { + val fakeCaller: (SimpleRequest, Client) => Task[SimpleResponse] = (_, _) => Task.now(SimpleResponse(200)) + val result = new ScalaPactHttpClient(null)(fakeCaller) + .doInteractionRequestIO("", requestDetails) + .unsafeRun() + result shouldEqual responseDetails + } + + // Does this test anything other than that the arguments are passed through correctly? +// it("should pass the SSL context to the client builder") { // -//import com.itv.scalapact.shared._ -//import fs2.Task -//import org.http4s.client.Client -//import org.scalamock.scalatest.MockFactory -//import org.scalatest.{FunSpec, Matchers} +// val sslContext = mock[SSLContext] +// implicit val sslContextMap = new SslContextMap(Map("someSSLName" -> sslContext)) +// val client = "the client" +// val fakeCaller: (SimpleRequest, String) => Task[SimpleResponse] = (sr, actualClient) => { +// sr shouldBe SimpleRequest("", "/foo", HttpMethod.GET, Some("someSSLName")) +// actualClient shouldBe client +// Task.now(SimpleResponse(200)) +// } // -//import scala.concurrent.duration._ +// val result = new ScalaPactHttpClient[String] { +// override def buildClient = new BuildClient[String] { +// override def apply(maxTotalConntections: Int, +// clientTimeout: Duration, +// actualSslContext: Option[SSLContext]): String = { +// actualSslContext shouldBe Some(sslContext) +// clientTimeout shouldBe 1.second +// maxTotalConntections shouldBe 1 +// client +// } +// } // -//class ScalaPactHttpClientSpec extends FunSpec with Matchers with MockFactory { -// -// val requestDetails = InteractionRequest( -// method = Some("GET"), -// headers = None, -// query = None, -// path = Some("/foo"), -// body = None, -// matchingRules = None -// ) -// -// val responseDetails = InteractionResponse( -// status = Some(200), -// headers = None, -// body = None, -// matchingRules = None -// ) -// -// describe("Making an interaction request") { -// -// it("should be able to make and interaction request and get an interaction response") { -// val fakeCaller: (SimpleRequest, Client) => Task[SimpleResponse] = (_, _) => Task.now(SimpleResponse(200)) -// val result = new ScalaPactHttpClient(fakeCaller) -// .doInteractionRequestTask(fakeCaller, "", requestDetails, 1.second, sslContextName = None) +// override def doRequest = ??? +// }.doInteractionRequestTask(fakeCaller, "", requestDetails, 1.second, sslContextName = Some("someSSLName")) // .unsafeRun() -// result shouldEqual responseDetails -// } -// -// // Does this test anything other than that the arguments are passed through correctly? -//// it("should pass the SSL context to the client builder") { -//// -//// val sslContext = mock[SSLContext] -//// implicit val sslContextMap = new SslContextMap(Map("someSSLName" -> sslContext)) -//// val client = "the client" -//// val fakeCaller: (SimpleRequest, String) => Task[SimpleResponse] = (sr, actualClient) => { -//// sr shouldBe SimpleRequest("", "/foo", HttpMethod.GET, Some("someSSLName")) -//// actualClient shouldBe client -//// Task.now(SimpleResponse(200)) -//// } -//// -//// val result = new ScalaPactHttpClient[String] { -//// override def buildClient = new BuildClient[String] { -//// override def apply(maxTotalConntections: Int, -//// clientTimeout: Duration, -//// actualSslContext: Option[SSLContext]): String = { -//// actualSslContext shouldBe Some(sslContext) -//// clientTimeout shouldBe 1.second -//// maxTotalConntections shouldBe 1 -//// client -//// } -//// } -//// -//// override def doRequest = ??? -//// }.doInteractionRequestTask(fakeCaller, "", requestDetails, 1.second, sslContextName = Some("someSSLName")) -//// .unsafeRun() -//// -//// result shouldEqual responseDetails -//// -//// } // -// } +// result shouldEqual responseDetails // -//} +// } + + } + +} diff --git a/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/HttpInstances.scala b/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/HttpInstances.scala index 511cd6238..12870f305 100644 --- a/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/HttpInstances.scala +++ b/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/HttpInstances.scala @@ -1,8 +1,8 @@ package com.itv.scalapact.http4s18.impl import cats.effect.IO -import com.itv.scalapact.shared.typeclasses.{IPactStubber, IScalaPactHttpClientBuilder} -import com.itv.scalapact.shared.{IResultPublisher, SslContextMap} +import com.itv.scalapact.shared.typeclasses.{IPactStubber, IResultPublisherBuilder, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.SslContextMap import scala.concurrent.duration.Duration @@ -16,5 +16,6 @@ trait HttpInstances { implicit def httpClientBuilder(implicit sslContextMap: SslContextMap): IScalaPactHttpClientBuilder[IO] = (clientTimeout: Duration, sslContextName: Option[String]) => ScalaPactHttpClient(clientTimeout, sslContextName) - implicit val resultPublisher: IResultPublisher = new ResultPublisher(Http4sClientHelper.doRequest) + implicit def resultPublisherBuilder(implicit sslContextMap: SslContextMap): IResultPublisherBuilder = + (clientTimeout: Duration, sslContextName: Option[String]) => ResultPublisher(clientTimeout, sslContextName) } diff --git a/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/ResultPublisher.scala b/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/ResultPublisher.scala index c2bb35dfb..68dce5fb2 100644 --- a/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/ResultPublisher.scala +++ b/scalapact-http4s-0-18/src/main/scala/com/itv/scalapact/http4s18/impl/ResultPublisher.scala @@ -1,22 +1,20 @@ package com.itv.scalapact.http4s18.impl import cats.effect.IO import cats.implicits._ -import com.itv.scalapact.shared.{IResultPublisher, _} +import com.itv.scalapact.shared._ import org.http4s.client.Client import com.itv.scalapact.shared.ColourOutput._ +import com.itv.scalapact.shared.typeclasses.{BrokerPublishData, IResultPublisher} import scala.concurrent.duration._ -class ResultPublisher(fetcher: (SimpleRequest, IO[Client[IO]]) => IO[SimpleResponse]) extends IResultPublisher { - - val maxTotalConnections: Int = 2 - private val clientTimeout = 10.seconds +class ResultPublisher(client: IO[Client[IO]])(fetcher: (SimpleRequest, IO[Client[IO]]) => IO[SimpleResponse]) extends IResultPublisher { override def publishResults( pactVerifyResults: List[PactVerifyResult], brokerPublishData: BrokerPublishData, pactBrokerAuthorization: Option[PactBrokerAuthorization] - )(implicit sslContextMap: SslContextMap): Unit = { + ): Unit = { pactVerifyResults .map { result => result.pact._links.flatMap(_.get("pb:publish-verification-results")).map(_.href) match { @@ -31,22 +29,16 @@ class ResultPublisher(fetcher: (SimpleRequest, IO[Client[IO]]) => IO[SimpleRespo None ) - SslContextMap(request)( - sslContext => - simpleRequestWithoutFakeHeader => { - val client = Http4sClientHelper.buildPooledBlazeHttpClient(maxTotalConnections, clientTimeout, sslContext) - fetcher(simpleRequestWithoutFakeHeader, client) - .map { response => - if (response.is2xx) { - PactLogger.message( - s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}" - ) - } else { - PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) - } - } + fetcher(request, client) + .map { response => + if (response.is2xx) { + PactLogger.message( + s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}" + ) + } else { + PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) + } } - ) case None => IO.pure( PactLogger @@ -64,3 +56,11 @@ class ResultPublisher(fetcher: (SimpleRequest, IO[Client[IO]]) => IO[SimpleRespo } } + +object ResultPublisher { + def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IResultPublisher = { + val sslContext = sslContextMap(sslContextName) + val client = Http4sClientHelper.buildPooledBlazeHttpClient(2, clientTimeout, sslContext) + new ResultPublisher(client)(Http4sClientHelper.doRequest) + } +} diff --git a/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ResultPublisherSpec.scala b/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ResultPublisherSpec.scala index c5440d790..d0b4a206a 100644 --- a/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ResultPublisherSpec.scala +++ b/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ResultPublisherSpec.scala @@ -1,6 +1,7 @@ package com.itv.scalapact.http4s18.impl import cats.effect.IO import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.BrokerPublishData import org.http4s.client.Client import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} @@ -54,7 +55,7 @@ class ResultPublisherSpec extends FunSpec with Matchers with BeforeAndAfter { IO.pure(SimpleResponse(200)) } - private val resultPublisher = new ResultPublisher(fakeCaller) + private val resultPublisher = new ResultPublisher(null)(fakeCaller) before { requests = ArrayBuffer.empty[SimpleRequest] diff --git a/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ScalaPactHttpClientSpec.scala b/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ScalaPactHttpClientSpec.scala index 731434b16..369d595f9 100644 --- a/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ScalaPactHttpClientSpec.scala +++ b/scalapact-http4s-0-18/src/test/scala/com/itv/scalapact/http4s18/impl/ScalaPactHttpClientSpec.scala @@ -1,42 +1,40 @@ -//package com.itv.scalapact.http4s18.impl -// -//import com.itv.scalapact.shared._ -//import org.http4s.client.Client -//import org.scalatest.{FunSpec, Matchers} -//import cats.effect.IO -// -//import scala.concurrent.duration._ -// -//class ScalaPactHttpClientSpec extends FunSpec with Matchers { -// -// describe("Making an interaction request") { -// -// it("should be able to make and interaction request and get an interaction response") { -// -// val requestDetails = InteractionRequest( -// method = Some("GET"), -// headers = None, -// query = None, -// path = Some("/foo"), -// body = None, -// matchingRules = None -// ) -// -// val responseDetails = InteractionResponse( -// status = Some(200), -// headers = None, -// body = None, -// matchingRules = None -// ) -// -// val fakeCaller: (SimpleRequest, IO[Client[IO]]) => IO[SimpleResponse] = (_, _) => IO.pure(SimpleResponse(200)) -// -// val result = -// new ScalaPactHttpClient(fakeCaller) -// .doInteractionRequestIO(fakeCaller, "", requestDetails, 1.second, None) -// .unsafeRunSync() -// -// result shouldEqual responseDetails -// } -// } -//} +package com.itv.scalapact.http4s18.impl + +import com.itv.scalapact.shared._ +import org.http4s.client.Client +import org.scalatest.{FunSpec, Matchers} +import cats.effect.IO + +class ScalaPactHttpClientSpec extends FunSpec with Matchers { + + describe("Making an interaction request") { + + it("should be able to make and interaction request and get an interaction response") { + + val requestDetails = InteractionRequest( + method = Some("GET"), + headers = None, + query = None, + path = Some("/foo"), + body = None, + matchingRules = None + ) + + val responseDetails = InteractionResponse( + status = Some(200), + headers = None, + body = None, + matchingRules = None + ) + + val fakeCaller: (SimpleRequest, IO[Client[IO]]) => IO[SimpleResponse] = (_, _) => IO.pure(SimpleResponse(200)) + + val result = + new ScalaPactHttpClient(null)(fakeCaller) + .doInteractionRequestIO("", requestDetails) + .unsafeRunSync() + + result shouldEqual responseDetails + } + } +} diff --git a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/Http4sClientHelper.scala b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/Http4sClientHelper.scala index 8e18cf0b8..d464f79bf 100644 --- a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/Http4sClientHelper.scala +++ b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/Http4sClientHelper.scala @@ -1,8 +1,7 @@ package com.itv.scalapact.http4s20.impl import cats.effect.{ContextShift, IO, Resource} -import com.itv.scalapact.shared.{SimpleRequest, SimpleResponse} -import javax.net.ssl.SSLContext +import com.itv.scalapact.shared.{SimpleRequest, SimpleResponse, SslContextMap} import org.http4s._ import org.http4s.client.Client import org.http4s.client.blaze.BlazeClientBuilder @@ -15,20 +14,16 @@ object Http4sClientHelper { def defaultClient: Resource[IO, Client[IO]] = buildPooledBlazeHttpClient(1, Duration(1, SECONDS), None) - def buildPooledBlazeHttpClient( - maxTotalConnections: Int, - clientTimeout: Duration, - sslContext: Option[SSLContext] - ): Resource[IO, Client[IO]] = { + def buildPooledBlazeHttpClient(maxTotalConnections: Int, + clientTimeout: Duration, + sslContextName: Option[String])(implicit sslContextMap: SslContextMap): Resource[IO, Client[IO]] = { implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) - - BlazeClientBuilder[IO](ExecutionContext.global) + val sslContext = sslContextMap(sslContextName) + val builder = BlazeClientBuilder[IO](ExecutionContext.Implicits.global) .withMaxTotalConnections(maxTotalConnections) .withRequestTimeout(clientTimeout) - .withSslContext(sslContext.getOrElse(SSLContext.getDefault)) .withUserAgentOption(Option(`User-Agent`(AgentProduct("scala-pact", Option(BuildInfo.version))))) - .withCheckEndpointAuthentication(false) - .resource + sslContext.fold(builder)(s => builder.withSslContext(s)).resource } @SuppressWarnings(Array("org.wartremover.warts.Any")) diff --git a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/HttpInstances.scala b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/HttpInstances.scala index 9bcf0b7fb..ada5cad6b 100644 --- a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/HttpInstances.scala +++ b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/HttpInstances.scala @@ -1,8 +1,8 @@ package com.itv.scalapact.http4s20.impl import cats.effect.IO -import com.itv.scalapact.shared.typeclasses.{IPactStubber, IScalaPactHttpClientBuilder} -import com.itv.scalapact.shared.{IResultPublisher, SslContextMap} +import com.itv.scalapact.shared.typeclasses.{IPactStubber, IResultPublisherBuilder, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.SslContextMap import scala.concurrent.duration.Duration @@ -16,5 +16,6 @@ trait HttpInstances { implicit def httpClientBuilder(implicit sslContextMap: SslContextMap): IScalaPactHttpClientBuilder[IO] = (clientTimeout: Duration, sslContextName: Option[String]) => ScalaPactHttpClient(clientTimeout, sslContextName) - implicit val resultPublisher: IResultPublisher = new ResultPublisher(Http4sClientHelper.doRequest) + implicit def resultPublisherBuilder(implicit sslContextMap: SslContextMap): IResultPublisherBuilder = + (clientTimeout: Duration, sslContextName: Option[String]) => ResultPublisher(clientTimeout, sslContextName) } diff --git a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ResultPublisher.scala b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ResultPublisher.scala index bd768fa00..d87257406 100644 --- a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ResultPublisher.scala +++ b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ResultPublisher.scala @@ -4,25 +4,21 @@ import cats.effect._ import cats.implicits._ import com.itv.scalapact.shared.ColourOutput._ import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.{BrokerPublishData, IResultPublisher} import org.http4s.client.Client -import org.http4s.client.blaze.BlazeClientBuilder -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.duration._ +import scala.concurrent.duration.Duration -class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse]) - extends IResultPublisher { - - private val maxTotalConnections = 2 - private val requestTimeout = 10.seconds +class ResultPublisher(client: Resource[IO, Client[IO]])(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse]) + extends IResultPublisher { override def publishResults( - pactVerifyResults: List[PactVerifyResult], - brokerPublishData: BrokerPublishData, - pactBrokerAuthorization: Option[PactBrokerAuthorization] - )(implicit sslContextMap: SslContextMap): Unit = + pactVerifyResults: List[PactVerifyResult], + brokerPublishData: BrokerPublishData, + pactBrokerAuthorization: Option[PactBrokerAuthorization] + ): Unit = pactVerifyResults - .map { result => + .traverse_ { result => result.pact._links.flatMap(_.get("pb:publish-verification-results")).map(_.href) match { case Some(link) => val success = !result.results.exists(_.result.isLeft) @@ -31,32 +27,18 @@ class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[S "", HttpMethod.POST, Map("Content-Type" -> "application/json; charset=UTF-8") ++ pactBrokerAuthorization.map(_.asHeader).toList, - body(brokerPublishData, success), + body(brokerPublishData, success).some, None ) - - SslContextMap(request)( - sslContext => - simpleRequestWithoutFakeHeader => { - fetcher( - simpleRequestWithoutFakeHeader, { - implicit val cs: ContextShift[IO] = IO.contextShift(global) - val clientPreSsl = BlazeClientBuilder[IO](global) - .withMaxTotalConnections(maxTotalConnections) - .withRequestTimeout(requestTimeout) - sslContext.fold(clientPreSsl)(s => clientPreSsl.withSslContext(s)).resource - } - ).map { response => - if (response.is2xx) { - PactLogger.message( - s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}" - ) - } else { - PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) - } - } + fetcher(request, client).map { response => + if (response.is2xx) { + PactLogger.message( + s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}" + ) + } else { + PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) } - ) + } case None => IO.pure( PactLogger @@ -64,14 +46,17 @@ class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[S ) } } - .sequence - .map(_ => ()) .unsafeRunSync() - private def body(brokerPublishData: BrokerPublishData, success: Boolean): Option[String] = { + private def body(brokerPublishData: BrokerPublishData, success: Boolean): String = { val buildUrl = brokerPublishData.buildUrl.fold("")(u => s""", "buildUrl": "$u"""") - Option( - s"""{ "success": $success, "providerApplicationVersion": "${brokerPublishData.providerVersion}"$buildUrl }""" - ) + s"""{ "success": $success, "providerApplicationVersion": "${brokerPublishData.providerVersion}"$buildUrl }""" } } + +object ResultPublisher { + def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IResultPublisher = { + val client = Http4sClientHelper.buildPooledBlazeHttpClient(2, clientTimeout, sslContextName) + new ResultPublisher(client)(Http4sClientHelper.doRequest) + } +} \ No newline at end of file diff --git a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ScalaPactHttpClient.scala b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ScalaPactHttpClient.scala index 443b9676c..31d5dfb7e 100644 --- a/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ScalaPactHttpClient.scala +++ b/scalapact-http4s-0-20/src/main/scala/com/itv/scalapact/http4s20/impl/ScalaPactHttpClient.scala @@ -4,9 +4,7 @@ import cats.effect._ import com.itv.scalapact.shared._ import com.itv.scalapact.shared.typeclasses.IScalaPactHttpClient import org.http4s.client.Client -import org.http4s.client.blaze.BlazeClientBuilder -import scala.concurrent.ExecutionContext import scala.concurrent.duration._ class ScalaPactHttpClient(client: Resource[IO, Client[IO]])(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse]) @@ -57,18 +55,8 @@ class ScalaPactHttpClient(client: Resource[IO, Client[IO]])(fetcher: (SimpleRequ } object ScalaPactHttpClient { - private val maxTotalConnections: Int = 1 - - private implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) - def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IScalaPactHttpClient[IO] = { - val sslContext = sslContextMap(sslContextName) - val client = { - val builder = BlazeClientBuilder[IO](ExecutionContext.Implicits.global) - .withMaxTotalConnections(maxTotalConnections) - .withRequestTimeout(clientTimeout) - sslContext.fold(builder)(s => builder.withSslContext(s)).resource - } + val client = Http4sClientHelper.buildPooledBlazeHttpClient(1, clientTimeout, sslContextName) new ScalaPactHttpClient(client)(Http4sClientHelper.doRequest) } } diff --git a/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ResultPublisherSpec.scala b/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ResultPublisherSpec.scala index ed778b04a..fc02e0590 100644 --- a/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ResultPublisherSpec.scala +++ b/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ResultPublisherSpec.scala @@ -3,6 +3,7 @@ package com.itv.scalapact.http4s.http4s20.impl import cats.effect.{IO, Resource} import com.itv.scalapact.http4s20.impl.ResultPublisher import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.BrokerPublishData import org.http4s.client.Client import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} @@ -56,7 +57,7 @@ class ResultPublisherSpec extends FunSpec with Matchers with BeforeAndAfter { IO.pure(SimpleResponse(200)) } - private val resultPublisher = new ResultPublisher(fakeCaller) + private val resultPublisher = new ResultPublisher(null)(fakeCaller) before { requests = ArrayBuffer.empty[SimpleRequest] diff --git a/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ScalaPactHttpClientSpec.scala b/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ScalaPactHttpClientSpec.scala index 64736c070..ad8c0848a 100644 --- a/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ScalaPactHttpClientSpec.scala +++ b/scalapact-http4s-0-20/src/test/scala/com/itv/scalapact/http4s/http4s20/impl/ScalaPactHttpClientSpec.scala @@ -1,44 +1,42 @@ -//package com.itv.scalapact.http4s.http4s20.impl -// -//import cats.effect.{IO, Resource} -//import com.itv.scalapact.http4s20.impl.ScalaPactHttpClient -//import com.itv.scalapact.shared._ -//import org.http4s.client.Client -//import org.scalatest.{FunSpec, Matchers} -// -//import scala.concurrent.duration._ -// -//class ScalaPactHttpClientSpec extends FunSpec with Matchers { -// -// describe("Making an interaction request") { -// -// it("should be able to make and interaction request and get an interaction response") { -// -// val requestDetails = InteractionRequest( -// method = Some("GET"), -// headers = None, -// query = None, -// path = Some("/foo"), -// body = None, -// matchingRules = None -// ) -// -// val responseDetails = InteractionResponse( -// status = Some(200), -// headers = None, -// body = None, -// matchingRules = None -// ) -// -// val fakeCaller: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse] = -// (_, _) => IO.pure(SimpleResponse(200)) -// -// val result = -// new ScalaPactHttpClient(fakeCaller) -// .doInteractionRequestIO(fakeCaller, "", requestDetails, 1.second, None) -// .unsafeRunSync() -// -// result shouldEqual responseDetails -// } -// } -//} +package com.itv.scalapact.http4s.http4s20.impl + +import cats.effect.{IO, Resource} +import com.itv.scalapact.http4s20.impl.ScalaPactHttpClient +import com.itv.scalapact.shared._ +import org.http4s.client.Client +import org.scalatest.{FunSpec, Matchers} + +class ScalaPactHttpClientSpec extends FunSpec with Matchers { + + describe("Making an interaction request") { + + it("should be able to make and interaction request and get an interaction response") { + + val requestDetails = InteractionRequest( + method = Some("GET"), + headers = None, + query = None, + path = Some("/foo"), + body = None, + matchingRules = None + ) + + val responseDetails = InteractionResponse( + status = Some(200), + headers = None, + body = None, + matchingRules = None + ) + + val fakeCaller: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse] = + (_, _) => IO.pure(SimpleResponse(200)) + + val result = + new ScalaPactHttpClient(null)(fakeCaller) + .doInteractionRequestIO("", requestDetails) + .unsafeRunSync() + + result shouldEqual responseDetails + } + } +} diff --git a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/Http4sClientHelper.scala b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/Http4sClientHelper.scala index 2a754ff31..2f08979a3 100644 --- a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/Http4sClientHelper.scala +++ b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/Http4sClientHelper.scala @@ -1,8 +1,7 @@ package com.itv.scalapact.http4s21.impl import cats.effect.{ContextShift, IO, Resource} -import com.itv.scalapact.shared.{SimpleRequest, SimpleResponse} -import javax.net.ssl.SSLContext +import com.itv.scalapact.shared.{SimpleRequest, SimpleResponse, SslContextMap} import org.http4s._ import org.http4s.client.Client import org.http4s.client.blaze.BlazeClientBuilder @@ -18,16 +17,14 @@ object Http4sClientHelper { def buildPooledBlazeHttpClient(maxTotalConnections: Int, clientTimeout: Duration, - sslContext: Option[SSLContext]): Resource[IO, Client[IO]] = { + sslContextName: Option[String])(implicit sslContextMap: SslContextMap): Resource[IO, Client[IO]] = { implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) - - BlazeClientBuilder[IO](ExecutionContext.global) + val sslContext = sslContextMap(sslContextName) + val builder = BlazeClientBuilder[IO](ExecutionContext.Implicits.global) .withMaxTotalConnections(maxTotalConnections) .withRequestTimeout(clientTimeout) - .withSslContext(sslContext.getOrElse(SSLContext.getDefault)) .withUserAgentOption(Option(`User-Agent`(AgentProduct("scala-pact", Option(BuildInfo.version))))) - .withCheckEndpointAuthentication(false) - .resource + sslContext.fold(builder)(s => builder.withSslContext(s)).resource } def doRequest(request: SimpleRequest, httpClient: Resource[IO, Client[IO]]): IO[SimpleResponse] = diff --git a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/HttpInstances.scala b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/HttpInstances.scala index 1ad1e7e8e..1fe52208f 100644 --- a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/HttpInstances.scala +++ b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/HttpInstances.scala @@ -1,8 +1,8 @@ package com.itv.scalapact.http4s21.impl import cats.effect.IO -import com.itv.scalapact.shared.{IResultPublisher, SslContextMap} -import com.itv.scalapact.shared.typeclasses.{IPactStubber, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.SslContextMap +import com.itv.scalapact.shared.typeclasses.{IPactStubber, IResultPublisherBuilder, IScalaPactHttpClientBuilder} import scala.concurrent.duration.Duration @@ -16,5 +16,7 @@ trait HttpInstances { implicit def httpClientBuilder(implicit sslContextMap: SslContextMap): IScalaPactHttpClientBuilder[IO] = (clientTimeout: Duration, sslContextName: Option[String]) => ScalaPactHttpClient(clientTimeout, sslContextName) - implicit val resultPublisher: IResultPublisher = new ResultPublisher(Http4sClientHelper.doRequest) + implicit def resultPublisherBuilder(implicit sslContextMap: SslContextMap): IResultPublisherBuilder = + (clientTimeout: Duration, sslContextName: Option[String]) => ResultPublisher(clientTimeout, sslContextName) + } diff --git a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ResultPublisher.scala b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ResultPublisher.scala index 9024856b9..7ca826cf0 100644 --- a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ResultPublisher.scala +++ b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ResultPublisher.scala @@ -4,25 +4,21 @@ import cats.effect._ import cats.implicits._ import com.itv.scalapact.shared.ColourOutput._ import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.{BrokerPublishData, IResultPublisher} import org.http4s.client.Client -import org.http4s.client.blaze.BlazeClientBuilder -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.duration._ +import scala.concurrent.duration.Duration -class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse]) +class ResultPublisher(client: Resource[IO, Client[IO]])(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse]) extends IResultPublisher { - private val maxTotalConnections = 2 - private val requestTimeout = 10.seconds - override def publishResults( pactVerifyResults: List[PactVerifyResult], brokerPublishData: BrokerPublishData, pactBrokerAuthorization: Option[PactBrokerAuthorization] - )(implicit sslContextMap: SslContextMap): Unit = + ): Unit = pactVerifyResults - .map { result => + .traverse_ { result => result.pact._links.flatMap(_.get("pb:publish-verification-results")).map(_.href) match { case Some(link) => val success = !result.results.exists(_.result.isLeft) @@ -34,29 +30,15 @@ class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[S body(brokerPublishData, success).some, None ) - - SslContextMap(request)( - sslContext => - simpleRequestWithoutFakeHeader => { - fetcher( - simpleRequestWithoutFakeHeader, { - implicit val cs: ContextShift[IO] = IO.contextShift(global) - val clientPreSsl = BlazeClientBuilder[IO](global) - .withMaxTotalConnections(maxTotalConnections) - .withRequestTimeout(requestTimeout) - sslContext.fold(clientPreSsl)(s => clientPreSsl.withSslContext(s)).resource - } - ).map { response => - if (response.is2xx) { - PactLogger.message( - s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}" - ) - } else { - PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) - } - } + fetcher(request, client).map { response => + if (response.is2xx) { + PactLogger.message( + s"Verification results published for provider ${result.pact.provider} and consumer ${result.pact.consumer}" + ) + } else { + PactLogger.error(s"Publish verification results failed with ${response.statusCode}".red) } - ) + } case None => IO.pure( PactLogger @@ -64,7 +46,6 @@ class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[S ) } } - .sequence_ .unsafeRunSync() private def body(brokerPublishData: BrokerPublishData, success: Boolean): String = { @@ -72,3 +53,10 @@ class ResultPublisher(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[S s"""{ "success": $success, "providerApplicationVersion": "${brokerPublishData.providerVersion}"$buildUrl }""" } } + +object ResultPublisher { + def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IResultPublisher = { + val client = Http4sClientHelper.buildPooledBlazeHttpClient(2, clientTimeout, sslContextName) + new ResultPublisher(client)(Http4sClientHelper.doRequest) + } +} \ No newline at end of file diff --git a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ScalaPactHttpClient.scala b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ScalaPactHttpClient.scala index 34a356a62..a4eeca8cf 100644 --- a/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ScalaPactHttpClient.scala +++ b/scalapact-http4s-0-21/src/main/scala/com/itv/scalapact/http4s21/impl/ScalaPactHttpClient.scala @@ -4,9 +4,7 @@ import cats.effect._ import com.itv.scalapact.shared._ import com.itv.scalapact.shared.typeclasses.IScalaPactHttpClient import org.http4s.client.Client -import org.http4s.client.blaze.BlazeClientBuilder -import scala.concurrent.ExecutionContext import scala.concurrent.duration._ class ScalaPactHttpClient(client: Resource[IO, Client[IO]])(fetcher: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse]) @@ -57,18 +55,8 @@ class ScalaPactHttpClient(client: Resource[IO, Client[IO]])(fetcher: (SimpleRequ } object ScalaPactHttpClient { - private val maxTotalConnections: Int = 1 - - private implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) - def apply(clientTimeout: Duration, sslContextName: Option[String])(implicit sslContextMap: SslContextMap): IScalaPactHttpClient[IO] = { - val sslContext = sslContextMap(sslContextName) - val client = { - val builder = BlazeClientBuilder[IO](ExecutionContext.Implicits.global) - .withMaxTotalConnections(maxTotalConnections) - .withRequestTimeout(clientTimeout) - sslContext.fold(builder)(s => builder.withSslContext(s)).resource - } + val client = Http4sClientHelper.buildPooledBlazeHttpClient(1, clientTimeout, sslContextName) new ScalaPactHttpClient(client)(Http4sClientHelper.doRequest) } } diff --git a/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ResultPublisherSpec.scala b/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ResultPublisherSpec.scala index a4e0475c7..4a9dde23d 100644 --- a/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ResultPublisherSpec.scala +++ b/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ResultPublisherSpec.scala @@ -3,6 +3,7 @@ package com.itv.scalapact.http4s.http4s21.impl import cats.effect.{IO, Resource} import com.itv.scalapact.http4s21.impl.ResultPublisher import com.itv.scalapact.shared._ +import com.itv.scalapact.shared.typeclasses.BrokerPublishData import org.http4s.client.Client import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} @@ -56,7 +57,7 @@ class ResultPublisherSpec extends FunSpec with Matchers with BeforeAndAfter { IO.pure(SimpleResponse(200)) } - private val resultPublisher = new ResultPublisher(fakeCaller) + private val resultPublisher = new ResultPublisher(null)(fakeCaller) before { requests = ArrayBuffer.empty[SimpleRequest] diff --git a/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ScalaPactHttpClientSpec.scala b/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ScalaPactHttpClientSpec.scala index 6e4880dd2..2a6976b89 100644 --- a/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ScalaPactHttpClientSpec.scala +++ b/scalapact-http4s-0-21/src/test/scala/com/itv/scalapact/http4s/http4s21/impl/ScalaPactHttpClientSpec.scala @@ -1,44 +1,42 @@ -//package com.itv.scalapact.http4s.http4s21.impl -// -//import cats.effect.{IO, Resource} -//import com.itv.scalapact.http4s21.impl.ScalaPactHttpClient -//import com.itv.scalapact.shared._ -//import org.http4s.client.Client -//import org.scalatest.{FunSpec, Matchers} -// -//import scala.concurrent.duration._ -// -//class ScalaPactHttpClientSpec extends FunSpec with Matchers { -// -// describe("Making an interaction request") { -// -// it("should be able to make and interaction request and get an interaction response") { -// -// val requestDetails = InteractionRequest( -// method = Some("GET"), -// headers = None, -// query = None, -// path = Some("/foo"), -// body = None, -// matchingRules = None -// ) -// -// val responseDetails = InteractionResponse( -// status = Some(200), -// headers = None, -// body = None, -// matchingRules = None -// ) -// -// val fakeCaller: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse] = -// (_, _) => IO.pure(SimpleResponse(200)) -// -// val result = -// new ScalaPactHttpClient(fakeCaller) -// .doInteractionRequestIO(fakeCaller, "", requestDetails, 1.second, None) -// .unsafeRunSync() -// -// result shouldEqual responseDetails -// } -// } -//} +package com.itv.scalapact.http4s.http4s21.impl + +import cats.effect.{IO, Resource} +import com.itv.scalapact.http4s21.impl.ScalaPactHttpClient +import com.itv.scalapact.shared._ +import org.http4s.client.Client +import org.scalatest.{FunSpec, Matchers} + +class ScalaPactHttpClientSpec extends FunSpec with Matchers { + + describe("Making an interaction request") { + + it("should be able to make and interaction request and get an interaction response") { + + val requestDetails = InteractionRequest( + method = Some("GET"), + headers = None, + query = None, + path = Some("/foo"), + body = None, + matchingRules = None + ) + + val responseDetails = InteractionResponse( + status = Some(200), + headers = None, + body = None, + matchingRules = None + ) + + val fakeCaller: (SimpleRequest, Resource[IO, Client[IO]]) => IO[SimpleResponse] = + (_, _) => IO.pure(SimpleResponse(200)) + + val result = + new ScalaPactHttpClient(null)(fakeCaller) + .doInteractionRequestIO("", requestDetails) + .unsafeRunSync() + + result shouldEqual responseDetails + } + } +} diff --git a/scalapact-scalatest/src/main/scala/com/itv/scalapact/ScalaPactVerify.scala b/scalapact-scalatest/src/main/scala/com/itv/scalapact/ScalaPactVerify.scala index a241be001..2997a6ab2 100644 --- a/scalapact-scalatest/src/main/scala/com/itv/scalapact/ScalaPactVerify.scala +++ b/scalapact-scalatest/src/main/scala/com/itv/scalapact/ScalaPactVerify.scala @@ -7,7 +7,7 @@ import java.io.{BufferedWriter, File, FileWriter} import com.itv.scalapact.shared._ import scala.concurrent.duration._ -import com.itv.scalapact.shared.typeclasses.{IPactReader, IPactWriter, IScalaPactHttpClientBuilder} +import com.itv.scalapact.shared.typeclasses.{BrokerPublishData, IPactReader, IPactWriter, IResultPublisherBuilder, IScalaPactHttpClientBuilder} import com.itv.scalapact.shared.ProviderStateResult import com.itv.scalapact.shared.ProviderStateResult.SetupProviderState @@ -35,63 +35,63 @@ trait ScalaPactVerifyDsl { ) { def runStrictVerificationAgainst[F[_]]( port: Int - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification("http", "localhost", port, defaultClientTimeout, strict = true) def runStrictVerificationAgainst[F[_]]( port: Int, clientTimeout: Duration - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification("http", "localhost", port, clientTimeout, strict = true) def runStrictVerificationAgainst[F[_]]( host: String, port: Int - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification("http", host, port, defaultClientTimeout, strict = true) def runStrictVerificationAgainst[F[_]](host: String, port: Int, clientTimeout: Duration)( implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher + publisher: IResultPublisherBuilder ): Unit = doVerification("http", host, port, clientTimeout, strict = true) def runStrictVerificationAgainst[F[_]](protocol: String, host: String, port: Int)( implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher + publisher: IResultPublisherBuilder ): Unit = doVerification(protocol, host, port, defaultClientTimeout, strict = true) def runStrictVerificationAgainst[F[_]]( target: VerifyTargetConfig - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification(target.protocol, target.host, target.port, target.clientTimeout, strict = true) def runVerificationAgainst[F[_]]( port: Int - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification("http", "localhost", port, defaultClientTimeout, strict = false) def runVerificationAgainst[F[_]]( port: Int, clientTimeout: Duration - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification("http", "localhost", port, clientTimeout, strict = false) def runVerificationAgainst[F[_]]( host: String, port: Int - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification("http", host, port, defaultClientTimeout, strict = false) def runVerificationAgainst[F[_]](host: String, port: Int, clientTimeout: Duration)( implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher + publisher: IResultPublisherBuilder ): Unit = doVerification("http", host, port, clientTimeout, strict = false) @@ -99,7 +99,7 @@ trait ScalaPactVerifyDsl { implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher + publisher: IResultPublisherBuilder ): Unit = doVerification(protocol, host, port, defaultClientTimeout, strict = false) @@ -107,13 +107,13 @@ trait ScalaPactVerifyDsl { implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], - publisher: IResultPublisher + publisher: IResultPublisherBuilder ): Unit = doVerification(protocol, host, port, clientTimeout, strict = false) def runVerificationAgainst[F[_]]( target: VerifyTargetConfig - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = doVerification(target.protocol, target.host, target.port, target.clientTimeout, strict = false) private def doVerification[F[_]]( @@ -122,7 +122,7 @@ trait ScalaPactVerifyDsl { port: Int, clientTimeout: Duration, strict: Boolean - )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisher): Unit = { + )(implicit pactReader: IPactReader, pactWriter: IPactWriter, httpClientBuilder: IScalaPactHttpClientBuilder[F], publisher: IResultPublisherBuilder): Unit = { val providerStateFunc: SetupProviderState = given diff --git a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/ScalaPactSettings.scala b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/ScalaPactSettings.scala index 09a2f6682..fe4c28ef3 100644 --- a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/ScalaPactSettings.scala +++ b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/ScalaPactSettings.scala @@ -1,5 +1,7 @@ package com.itv.scalapact.shared +import com.itv.scalapact.shared.typeclasses.BrokerPublishData + import scala.concurrent.duration.{Duration, SECONDS} import scala.util.Properties diff --git a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/IResultPublisher.scala b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisher.scala similarity index 68% rename from scalapact-shared/src/main/scala/com/itv/scalapact/shared/IResultPublisher.scala rename to scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisher.scala index 01e98fbc9..1c0fd715c 100644 --- a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/IResultPublisher.scala +++ b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisher.scala @@ -1,11 +1,13 @@ -package com.itv.scalapact.shared +package com.itv.scalapact.shared.typeclasses + +import com.itv.scalapact.shared.{PactBrokerAuthorization, PactVerifyResult} trait IResultPublisher { def publishResults( pactVerifyResults: List[PactVerifyResult], brokerPublishData: BrokerPublishData, pactBrokerAuthorization: Option[PactBrokerAuthorization] - )(implicit sslContextMap: SslContextMap): Unit + ): Unit } case class BrokerPublishData(providerVersion: String, buildUrl: Option[String]) diff --git a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisherBuilder.scala b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisherBuilder.scala new file mode 100644 index 000000000..2bb62e3b8 --- /dev/null +++ b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/typeclasses/IResultPublisherBuilder.scala @@ -0,0 +1,7 @@ +package com.itv.scalapact.shared.typeclasses + +import scala.concurrent.duration.Duration + +trait IResultPublisherBuilder { + def build(clientTimeout: Duration, sslContextName: Option[String]): IResultPublisher +}