Skip to content

Commit

Permalink
API-7747 - Updating to use HttpClientV2 (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
peteslater-ee authored Aug 7, 2024
1 parent 6c035ee commit 6b2f185
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ package uk.gov.hmrc.apiplatform.modules.gkauth.connectors
import javax.inject.{Inject, Singleton}

import uk.gov.hmrc.auth.core._
import uk.gov.hmrc.http.HttpClient
import uk.gov.hmrc.http.client.HttpClientV2

object StrideAuthConnector {
case class Config(strideAuthBaseUrl: String)
}

@Singleton
class StrideAuthConnector @Inject() (val http: HttpClient, config: StrideAuthConnector.Config) extends PlayAuthConnector {
class StrideAuthConnector @Inject() (val httpClientV2: HttpClientV2, config: StrideAuthConnector.Config) extends PlayAuthConnector {
lazy val serviceUrl = config.strideAuthBaseUrl
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@

package uk.gov.hmrc.thirdpartyapplication.connector

import java.net.URL
import javax.inject.Inject
import scala.concurrent.{ExecutionContext, Future}

import play.api.libs.json.Json
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient}
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, StringContextOps}

import uk.gov.hmrc.apiplatform.modules.common.services.ApplicationLogger
import uk.gov.hmrc.apiplatform.modules.events.applications.domain.models._
Expand All @@ -30,7 +33,7 @@ object ApiPlatformEventsConnector {
case class Config(baseUrl: String, enabled: Boolean)
}

class ApiPlatformEventsConnector @Inject() (http: HttpClient, config: ApiPlatformEventsConnector.Config)(implicit val ec: ExecutionContext) extends ResponseUtils
class ApiPlatformEventsConnector @Inject() (http: HttpClientV2, config: ApiPlatformEventsConnector.Config)(implicit val ec: ExecutionContext) extends ResponseUtils
with ApplicationLogger {

val serviceBaseUrl: String = s"${config.baseUrl}"
Expand All @@ -42,24 +45,25 @@ class ApiPlatformEventsConnector @Inject() (http: HttpClient, config: ApiPlatfor
implicit val headersWithoutAuthorization: HeaderCarrier = hc.copy(authorization = None)

if (config.enabled) {
http.POST[ApplicationEvent, ErrorOr[Unit]](
addEventURI(uri),
event
).map {
case Right(_) =>
logger.info(s"calling platform event service for application ${event.applicationId.value}")
true
case Left(e) =>
logger.warn(s"calling platform event service failed for application ${event.applicationId.value} $e")
false
}
http.post(addEventURI(uri))
.withBody(Json.toJson(event))
.execute[ErrorOr[Unit]]
.map {
case Right(_) =>
logger.info(s"calling platform event service for application ${event.applicationId.value}")
true
case Left(e) =>
logger.warn(s"calling platform event service failed for application ${event.applicationId.value} $e")
false
}
} else {
logger.info("call to platform events disabled")
Future.successful(true)
}
}

private def addEventURI(path: String): String = {
serviceBaseUrl + path
private def addEventURI(path: String): URL = {
val x = s"$serviceBaseUrl$path"
url"$x"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import scala.concurrent.{ExecutionContext, Future}

import play.api.http.Status._
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient, UpstreamErrorResponse}
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, StringContextOps, UpstreamErrorResponse}

import uk.gov.hmrc.apiplatform.modules.common.domain.models.ClientId
import uk.gov.hmrc.thirdpartyapplication.models.HasSucceeded
Expand All @@ -31,10 +32,11 @@ object ApiSubscriptionFieldsConnector {
}

@Singleton
class ApiSubscriptionFieldsConnector @Inject() (httpClient: HttpClient, config: ApiSubscriptionFieldsConnector.Config)(implicit val ec: ExecutionContext) extends ResponseUtils {
class ApiSubscriptionFieldsConnector @Inject() (httpClient: HttpClientV2, config: ApiSubscriptionFieldsConnector.Config)(implicit val ec: ExecutionContext) extends ResponseUtils {

def deleteSubscriptions(clientId: ClientId)(implicit hc: HeaderCarrier): Future[HasSucceeded] = {
httpClient.DELETE[ErrorOr[Unit]](s"${config.baseUrl}/field/application/${clientId.value}")
httpClient.delete(url"${config.baseUrl}/field/application/${clientId.value}")
.execute[ErrorOr[Unit]]
.map {
case Right(_) => HasSucceeded
case Left(UpstreamErrorResponse(_, NOT_FOUND, _, _)) => HasSucceeded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@

package uk.gov.hmrc.thirdpartyapplication.connector

import java.net.URL
import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

import play.api.http.ContentTypes.JSON
import play.api.http.HeaderNames.CONTENT_TYPE
import play.api.libs.json.{JsPath, OWrites, Reads}
import play.api.libs.json.{JsPath, Json, OWrites, Reads}
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient}
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, StringContextOps}

import uk.gov.hmrc.apiplatform.modules.common.services.ApplicationLogger
import uk.gov.hmrc.apiplatform.modules.applications.core.domain.models.RateLimitTier
Expand All @@ -46,25 +48,24 @@ object AwsApiGatewayConnector extends ApplicationLogger {
}

@Singleton
class AwsApiGatewayConnector @Inject() (http: HttpClient, config: AwsApiGatewayConnector.Config)(implicit val ec: ExecutionContext) {
class AwsApiGatewayConnector @Inject() (http: HttpClientV2, config: AwsApiGatewayConnector.Config)(implicit val ec: ExecutionContext) {
import AwsApiGatewayConnector._

val serviceBaseUrl: String = s"${config.baseUrl}/v1/application"
val awsApiKey: String = config.awsApiKey
val apiKeyHeaderName = "x-api-key"

private def updateUsagePlanURL(rateLimitTier: RateLimitTier): String = s"${config.baseUrl}/v1/usage-plans/$rateLimitTier/api-keys"
private def deleteAPIKeyURL(applicationName: String): String = s"${config.baseUrl}/v1/api-keys/$applicationName"
private def updateUsagePlanURL(rateLimitTier: RateLimitTier): URL = url"${config.baseUrl}/v1/usage-plans/$rateLimitTier/api-keys"
private def deleteAPIKeyURL(applicationName: String): URL = url"${config.baseUrl}/v1/api-keys/$applicationName"

def createOrUpdateApplication(applicationName: String, serverToken: String, usagePlan: RateLimitTier)(hc: HeaderCarrier): Future[HasSucceeded] = {
implicit val headersWithoutAuthorization: HeaderCarrier = hc
.copy(authorization = None)
.withExtraHeaders(apiKeyHeaderName -> awsApiKey, CONTENT_TYPE -> JSON)

http.POST[UpdateApplicationUsagePlanRequest, RequestId](
updateUsagePlanURL(usagePlan),
UpdateApplicationUsagePlanRequest(applicationName, serverToken)
)
http.post(updateUsagePlanURL(usagePlan))
.withBody(Json.toJson(UpdateApplicationUsagePlanRequest(applicationName, serverToken)))
.execute[RequestId]
.map { requestId =>
logger.info(s"Successfully created or updated application '$applicationName' in AWS API Gateway with request ID ${requestId.value}")
HasSucceeded
Expand All @@ -76,9 +77,11 @@ class AwsApiGatewayConnector @Inject() (http: HttpClient, config: AwsApiGatewayC
.copy(authorization = None)
.withExtraHeaders(apiKeyHeaderName -> awsApiKey)

http.DELETE[RequestId](deleteAPIKeyURL(applicationName)).map(requestId => {
logger.info(s"Successfully deleted application '$applicationName' from AWS API Gateway with request ID ${requestId.value}")
HasSucceeded
})
http.delete(deleteAPIKeyURL(applicationName))
.execute[RequestId]
.map(requestId => {
logger.info(s"Successfully deleted application '$applicationName' from AWS API Gateway with request ID ${requestId.value}")
HasSucceeded
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import scala.util.{Failure, Success, Try}

import play.api.libs.json.{Json, OFormat}
import play.mvc.Http.Status._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient, HttpResponse}
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse, StringContextOps}

import uk.gov.hmrc.apiplatform.modules.common.domain.models.{ApplicationId, LaxEmailAddress}
import uk.gov.hmrc.apiplatform.modules.common.services.ApplicationLogger
Expand All @@ -49,7 +50,7 @@ object EmailConnector {
}

@Singleton
class EmailConnector @Inject() (httpClient: HttpClient, config: EmailConnector.Config)(implicit val ec: ExecutionContext) extends ApplicationLogger {
class EmailConnector @Inject() (httpClient: HttpClientV2, config: EmailConnector.Config)(implicit val ec: ExecutionContext) extends ApplicationLogger {
import EmailConnector._

val serviceUrl = config.baseUrl
Expand Down Expand Up @@ -475,7 +476,10 @@ class EmailConnector @Inject() (httpClient: HttpClient, config: EmailConnector.C
def makeCall() = {
import uk.gov.hmrc.http.HttpReads.Implicits._

httpClient.POST[SendEmailRequest, HttpResponse](url, payload)
httpClient
.post(url"$url")
.withBody(Json.toJson(payload))
.execute[HttpResponse]
.map { response =>
logger.info(s"Sent '${payload.templateId}' with response: ${response.status}")
response.status match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient}
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, StringContextOps}

import uk.gov.hmrc.apiplatform.modules.common.domain.models.ClientId
import uk.gov.hmrc.thirdpartyapplication.models.HasSucceeded
Expand All @@ -30,9 +31,12 @@ object ThirdPartyDelegatedAuthorityConnector {
}

@Singleton
class ThirdPartyDelegatedAuthorityConnector @Inject() (httpClient: HttpClient, config: ThirdPartyDelegatedAuthorityConnector.Config)(implicit val ec: ExecutionContext) {
class ThirdPartyDelegatedAuthorityConnector @Inject() (httpClient: HttpClientV2, config: ThirdPartyDelegatedAuthorityConnector.Config)(implicit val ec: ExecutionContext) {

def revokeApplicationAuthorities(clientId: ClientId)(implicit hc: HeaderCarrier): Future[HasSucceeded] = {
httpClient.DELETE[Option[Unit]](s"${config.baseUrl}/authority/${clientId.value}") map (_ => HasSucceeded)
httpClient
.delete(url"${config.baseUrl}/authority/${clientId.value}")
.execute[Option[Unit]]
.map(_ => HasSucceeded)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal

import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient, UpstreamErrorResponse}
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, StringContextOps, UpstreamErrorResponse}

import uk.gov.hmrc.thirdpartyapplication.models.Totp

Expand All @@ -30,15 +31,17 @@ object TotpConnector {
}

@Singleton
class TotpConnector @Inject() (httpClient: HttpClient, config: TotpConnector.Config)(implicit val ec: ExecutionContext) {
class TotpConnector @Inject() (httpClient: HttpClientV2, config: TotpConnector.Config)(implicit val ec: ExecutionContext) {

def generateTotp()(implicit hc: HeaderCarrier): Future[Totp] = {
val url = s"${config.baseUrl}/time-based-one-time-password/secret"
val postUrl = url"${config.baseUrl}/time-based-one-time-password/secret"

httpClient.POSTEmpty[Totp](url)
httpClient
.post(postUrl)
.execute[Totp]
.recover {
case e: UpstreamErrorResponse => throw new RuntimeException(s"Unexpected response from $url: (${e.statusCode}, ${e.message})")
case NonFatal(e) => throw new RuntimeException(s"Error response from $url: ${e.getMessage}")
case e: UpstreamErrorResponse => throw new RuntimeException(s"Unexpected response from $postUrl: (${e.statusCode}, ${e.message})")
case NonFatal(e) => throw new RuntimeException(s"Error response from $postUrl: ${e.getMessage}")
}
}
}
20 changes: 3 additions & 17 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import uk.gov.hmrc.DefaultBuildSettings._

lazy val appName = "third-party-application"

lazy val playSettings: Seq[Setting[_]] = Seq.empty
Global / bloopAggregateSourceDependencies := true
Global / bloopExportJarClassifiers := Some(Set("sources"))

ThisBuild / scalaVersion := "2.13.12"
ThisBuild / majorVersion := 0
Expand All @@ -17,15 +18,10 @@ ThisBuild / semanticdbVersion := scalafixSemanticdb.revision
lazy val microservice = Project(appName, file("."))
.enablePlugins(PlayScala, SbtDistributablesPlugin)
.disablePlugins(JUnitXmlReportPlugin)
.settings(playSettings: _*)
.settings(scalaSettings: _*)
.settings(defaultSettings(): _*)
.settings(ScoverageSettings())
.settings(
name := appName,
libraryDependencies ++= AppDependencies(),
retrieveManaged := true,
routesGenerator := InjectedRoutesGenerator,
scalacOptions += "-Wconf:src=routes/.*:s",
routesImport ++= Seq(
"uk.gov.hmrc.apiplatform.modules.common.domain.models._",
Expand All @@ -34,22 +30,14 @@ lazy val microservice = Project(appName, file("."))
"uk.gov.hmrc.apiplatform.modules.submissions.domain.models._"
)
)
.settings(
addCompilerPlugin("org.typelevel" % "kind-projector" % "0.13.2" cross CrossVersion.full)
)
.settings(
Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-eT"),
Test / fork := false,
Test / unmanagedSourceDirectories ++= Seq(baseDirectory.value / "test", baseDirectory.value / "shared-test"),
Test / parallelExecution := false
)
.settings(
scalacOptions ++= Seq(
"-Wconf:cat=unused&src=views/.*\\.scala:s",
"-Wconf:cat=unused&src=.*RoutesPrefix\\.scala:s",
"-Wconf:cat=unused&src=.*Routes\\.scala:s",
"-Wconf:cat=unused&src=.*ReverseRoutes\\.scala:s"
)
addCompilerPlugin("org.typelevel" % "kind-projector" % "0.13.2" cross CrossVersion.full)
)

lazy val it = (project in file("it"))
Expand All @@ -61,8 +49,6 @@ lazy val it = (project in file("it"))
DefaultBuildSettings.itSettings()
)

Global / bloopAggregateSourceDependencies := true

commands ++= Seq(
Command.command("cleanAll") { state => "clean" :: "it/clean" :: state },
Command.command("fmtAll") { state => "scalafmtAll" :: "it/scalafmtAll" :: state },
Expand Down
2 changes: 1 addition & 1 deletion conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ play.http.errorHandler = "uk.gov.hmrc.play.bootstrap.backend.http.JsonErrorHandl

# Define additional modules used here
play.modules.enabled += "uk.gov.hmrc.mongo.play.PlayMongoModule"
play.modules.enabled += "uk.gov.hmrc.play.bootstrap.HttpClientModule"
play.modules.enabled += "uk.gov.hmrc.play.bootstrap.HttpClientV2Module"
play.modules.enabled += "uk.gov.hmrc.thirdpartyapplication.config.ConfigurationModule"
play.modules.enabled += "uk.gov.hmrc.apiplatform.modules.gkauth.config.StrideConfigurationModule"
play.modules.enabled += "uk.gov.hmrc.thirdpartyapplication.config.SchedulerModule"
Expand Down
9 changes: 5 additions & 4 deletions project/AppDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import org.apache.ivy.core.module.descriptor.ExcludeRule
object AppDependencies {
def apply(): Seq[ModuleID] = compileDeps ++ testDeps

lazy val bootstrapVersion = "8.4.0"
lazy val bootstrapVersion = "9.2.0"
lazy val hmrcMongoVersion = "1.7.0"
lazy val commonDomainVersion = "0.13.0"
lazy val commonDomainVersion = "0.15.0"
lazy val applicationEventVersion = "0.63.0"

private lazy val compileDeps = Seq(
Expand All @@ -15,8 +15,9 @@ object AppDependencies {
"commons-net" % "commons-net" % "3.6",
"com.github.t3hnar" %% "scala-bcrypt" % "4.1",
"commons-validator" % "commons-validator" % "1.7",
"uk.gov.hmrc" %% "internal-auth-client-play-30" % "1.10.0",
"uk.gov.hmrc" %% "api-platform-application-events" % applicationEventVersion
"uk.gov.hmrc" %% "internal-auth-client-play-30" % "3.0.0",
"uk.gov.hmrc" %% "api-platform-application-events" % applicationEventVersion,
"com.iheart" %% "ficus" % "1.5.2"
)

private lazy val testDeps = Seq(
Expand Down
8 changes: 4 additions & 4 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ resolvers += "Typesafe Releases" at "https://repo.typesafe.com/typesafe/releases

addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.22.0")
addSbtPlugin("uk.gov.hmrc" % "sbt-distributables" % "2.5.0")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.1")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.4")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9")
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.13")
addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0")
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.15")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.1")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1")

ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import scala.concurrent.ExecutionContext.Implicits.global
import com.github.tomakehurst.wiremock.client.WireMock._

import play.api.http.Status._
import uk.gov.hmrc.http.{HeaderCarrier, HttpClient}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.http.test.HttpClientV2Support

import uk.gov.hmrc.apiplatform.modules.common.domain.models.LaxEmailAddress.StringSyntax
import uk.gov.hmrc.apiplatform.modules.common.domain.models.{Actors, ApplicationId}
Expand All @@ -45,14 +46,12 @@ class ApiPlatformEventsConnectorSpec extends ConnectorSpec {
requestingAdminEmail = "[email protected]".toLaxEmail
)

abstract class Setup(enabled: Boolean = true) {
abstract class Setup(enabled: Boolean = true) extends HttpClientV2Support {
import uk.gov.hmrc.apiplatform.modules.events.applications.domain.services.EventsInterServiceCallJsonFormatters._

val http: HttpClient = app.injector.instanceOf[HttpClient]

val config: ApiPlatformEventsConnector.Config = ApiPlatformEventsConnector.Config(wireMockUrl, enabled)

val underTest = new ApiPlatformEventsConnector(http, config)
lazy val underTest = new ApiPlatformEventsConnector(httpClientV2, config)

def apiApplicationEventWillReturnCreated(request: ApplicationEvent) =
stubFor(
Expand Down
Loading

0 comments on commit 6b2f185

Please sign in to comment.