-
Notifications
You must be signed in to change notification settings - Fork 1
DTR-896: AddressLookup journey integration #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Changes from all commits
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
3b59e40
DTR-896: initial set of changes;
avelx fef0778
DTR-896: current set of changes:: create dummy controller to test Add…
avelx 9f375f6
DTR-896: working prototype in local env
avelx e9fc51e
DTR-896: attempt to extract address details at the end of the journey…
avelx ff3a2dc
DTR-896: fix bug with extracting Address;
avelx 0dfce2a
DTR-896: working E2E prototype which save AddressDetails into user se…
avelx 2dc8848
DTR-896: start work on the AddressLookupConnectorISpec
avelx 148d031
DTR-896: AddressLookupConnectorISpec / partially implemented
avelx 6ee92b7
DTR-896:
avelx 16b4cb1
DTR-896:
avelx 8c68464
Merge branch 'main' into DTR-896
avelx 6621c4a
DTR-896:
avelx 1c2dd84
DTR-896:
avelx 9d0f282
DTR-896:
avelx 9b5573c
DTR-896:
avelx 5b3c985
DTR-896:
avelx eea66a5
DTR-896:
avelx aa4bb71
Merge branch 'main' into DTR-896
avelx 2701ea9
DTR-896:
avelx 3f2d74d
Merge branch 'main' into DTR-896
avelx 2316522
DTR-896:
avelx d3a88f3
Merge branch 'main' into DTR-896
avelx 2f7d50c
DTR-896:
avelx 7a15c51
DTR-896:
avelx 7e6f5c1
DTR-896:
avelx 8c080c5
DTR-896:
avelx d9b3dd4
DTR-896:
avelx b8d4f37
DTR-896:
avelx 747fcc0
Merge branch 'main' into DTR-896
avelx 6bf382d
DTR-896:
avelx 68048b2
DTR-896:
avelx 82d2cc1
DTR-896:
avelx 23b1eca
DTR-896:
avelx 57e0998
DTR-896:
avelx ea2fbca
DTR-896:
avelx b7d1f05
DTR-896:
avelx bb52f13
DTR-896:
avelx 976ce54
Merge branch 'main' into DTR-896
avelx 5fc28fa
DTR-896:
avelx 136abf1
DTR-896:
avelx cf7ae7f
DTR-896:
avelx 287df93
DTR-896:
avelx 04118b9
DTR-896:
avelx 1c4d71f
DTR-896:
avelx 2de6aa1
DTR-896:
avelx 9bf699e
DTR-896:
avelx 3ad27a1
DTR-896:
avelx 1b1b718
Merge branch 'main' into DTR-896
avelx dbd36f6
DTR-896:
avelx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,185 @@ | ||
| /* | ||
| * Copyright 2025 HM Revenue & Customs | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package connectors | ||
|
|
||
| import config.FrontendAppConfig | ||
| import jakarta.inject.Singleton | ||
| import models.NormalMode | ||
| import models.responses.addresslookup.JourneyInitResponse.AddressLookupResponse | ||
| import models.responses.addresslookup.JourneyOutcomeResponse.AddressLookupJourneyOutcome | ||
| import play.api.i18n.{Lang, Messages, MessagesApi} | ||
| import play.api.libs.json.* | ||
| import uk.gov.hmrc.http.client.HttpClientV2 | ||
| import uk.gov.hmrc.http.{HeaderCarrier, StringContextOps} | ||
|
|
||
| import javax.inject.Inject | ||
| import scala.concurrent.{ExecutionContext, Future} | ||
| import play.api.Logger | ||
|
|
||
| @Singleton | ||
| class AddressLookupConnector @Inject()(val appConfig: FrontendAppConfig, | ||
| http: HttpClientV2, | ||
| val messagesApi: MessagesApi)(implicit ec: ExecutionContext) { | ||
|
|
||
| private val baseUrl: String = appConfig.addressLookupBaseUrl | ||
| val addressLookupInitializeUrl : String = s"$baseUrl/api/v2/init" | ||
| val addressLookupOutcomeUrl: String => String = (id: String) => s"$baseUrl/api/v2/confirmed?id=$id" | ||
|
|
||
| private val sessionTimeout: Long = appConfig.sessionTimeOut | ||
| private val addressLookupTimeoutUrl: String = appConfig.addressLookupTimeoutUrl | ||
|
|
||
| private val langResourcePrefix : String = "manageAgents.addressLookup" | ||
|
|
||
| private val continueUrl = appConfig.loginContinueUrl + | ||
| controllers.manageAgents.routes.AddressLookupController.onSubmit(NormalMode).url | ||
|
|
||
| private def setJourneyOptions(): Seq[(String, JsValue)] = { | ||
| Seq( | ||
| "continueUrl" -> JsString(continueUrl), | ||
|
|
||
| "ukMode" -> JsBoolean(true), | ||
| // TODO: we expect Welsh translation to be disabled / not working as expected | ||
| "disableTranslations" -> JsBoolean(true), | ||
|
|
||
| "showPhaseBanner" -> JsBoolean(true), | ||
| "alphaPhase" -> JsBoolean(true), | ||
|
|
||
| "includeHMRCBranding" -> JsBoolean(true), | ||
|
|
||
| "selectPageConfig" -> JsObject( | ||
| Seq( | ||
| "proposalListLimit" -> JsNumber(30), | ||
| "showSearchLinkAgain" -> JsBoolean(true) | ||
| ) | ||
| ), | ||
| "confirmPageConfig" -> JsObject( | ||
| Seq( | ||
| "showChangeLink" -> JsBoolean(true), | ||
| "showSubHeadingAndInfo" -> JsBoolean(false), | ||
| "showSearchAgainLink" -> JsBoolean(false), | ||
| "showConfirmChangeText" -> JsBoolean(false), | ||
| ) | ||
| ), | ||
| "manualAddressEntryConfig" -> JsObject( | ||
| Seq( | ||
| "line1MaxLength" -> JsNumber(255), | ||
| "line2MaxLength" -> JsNumber(255), | ||
| "line3MaxLength" -> JsNumber(255), | ||
| "townMaxLength" -> JsNumber(255) | ||
| ) | ||
| ), | ||
| "timeoutConfig" -> JsObject( | ||
| Seq( | ||
| "timeoutAmount" -> JsNumber(sessionTimeout), | ||
| "timeoutUrl" -> JsString(addressLookupTimeoutUrl) | ||
| ) | ||
| ), | ||
| "pageHeadingStyle" -> JsString("govuk-heading-l") | ||
| ) | ||
| } | ||
|
|
||
| private def setLabels(agentName: Option[String], lang : Lang) | ||
| (implicit messages: Messages): Seq[(String, JsObject)] = { | ||
| Seq( | ||
| "appLevelLabels" -> JsObject( | ||
| Seq( | ||
| "navTitle" -> JsString(messagesApi.preferred( Seq( lang ) )(s"$langResourcePrefix.header.title")) | ||
| ) | ||
| ), | ||
| "selectPageLabels" -> JsObject( | ||
| Seq( | ||
| "heading" -> JsString( | ||
| messages( | ||
| s"$langResourcePrefix.select.heading", agentName.getOrElse("") | ||
| ) | ||
| ) | ||
| ) | ||
| ), | ||
| "lookupPageLabels" -> JsObject( | ||
| Seq( | ||
| "heading" -> JsString( | ||
| messages( | ||
| s"$langResourcePrefix.lookup.heading", agentName.getOrElse("") | ||
| ) | ||
| ) | ||
| ) | ||
| ), | ||
| "confirmPageLabels" -> JsObject( | ||
| Seq( | ||
| "heading" -> JsString( | ||
| messages( | ||
| s"$langResourcePrefix.confirm.heading", agentName.getOrElse("") | ||
| ) | ||
| ), | ||
| "changeLinkText" -> JsString( | ||
| messages( | ||
| s"$langResourcePrefix.confirm.changeLinkText", agentName.getOrElse("") | ||
| ) | ||
| ), | ||
| ) | ||
| ), | ||
| "editPageLabels" -> JsObject( | ||
| Seq( | ||
| "heading" -> | ||
| JsString( | ||
| messages( | ||
| s"$langResourcePrefix.edit.heading", agentName.getOrElse("") | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| private def buildConfig(agentName: Option[String]) | ||
| (implicit messages: Messages): JsValue = { | ||
| JsObject( | ||
| Seq( | ||
| "version" -> JsNumber(2), | ||
| "options" -> JsObject( | ||
| setJourneyOptions() | ||
| ), | ||
| "labels" -> JsObject( | ||
| Seq( | ||
| "en" -> JsObject( | ||
| setLabels(agentName, Lang("en") ) | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| // Step 1: Journey start/init | ||
| def initJourney(agentName: Option[String]) | ||
| (implicit hc: HeaderCarrier, messages: Messages): Future[AddressLookupResponse] = { | ||
| import play.api.libs.ws.writeableOf_JsValue | ||
| val payload: JsValue = buildConfig(agentName) | ||
| Logger("application").info(s"[AddressLookupConnector] - body: ${Json.stringify(payload)}") | ||
| http.post(url"$addressLookupInitializeUrl") | ||
| .withBody(payload) | ||
| .execute[AddressLookupResponse] | ||
| } | ||
|
|
||
| // Step 2: Extract journey result/outcome | ||
| def getJourneyOutcome(id: String) | ||
| (implicit hc: HeaderCarrier): Future[AddressLookupJourneyOutcome] = { | ||
| Logger("application").info(s"[AddressLookupConnector] - Extract address: ${addressLookupOutcomeUrl(id)}") | ||
| http.get(url"${addressLookupOutcomeUrl(id)}").execute[AddressLookupJourneyOutcome] | ||
| } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
app/models/responses/addresslookup/JourneyInitResponse.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /* | ||
| * Copyright 2025 HM Revenue & Customs | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package models.responses.addresslookup | ||
|
|
||
| import play.api.http.Status.ACCEPTED | ||
| import uk.gov.hmrc.http.{HttpReads, HttpResponse} | ||
| import play.api.Logger | ||
|
|
||
| object JourneyInitResponse { | ||
|
|
||
| case class JourneyInitSuccessResponse(location: Option[String]) | ||
|
|
||
| case class JourneyInitFailureResponse(status: Int) extends Throwable | ||
|
|
||
| type AddressLookupResponse = Either[JourneyInitFailureResponse, JourneyInitSuccessResponse] | ||
|
|
||
| implicit def postAddressLookupHttpReads: HttpReads[AddressLookupResponse] = | ||
| new HttpReads[AddressLookupResponse] { | ||
|
|
||
| override def read(method: String, url: String, response: HttpResponse): AddressLookupResponse = { | ||
| response.status match { | ||
| case ACCEPTED => Right( | ||
| if (response.header(key = "location").isEmpty) { | ||
| JourneyInitSuccessResponse(response.header(key = "Location")) | ||
| } else { | ||
| JourneyInitSuccessResponse(response.header(key = "location")) | ||
| } | ||
| ) | ||
| case status => | ||
| Logger("application").error(s"[JourneyInitResponse] - ${response.body}") | ||
| Left(JourneyInitFailureResponse(status)) | ||
| } | ||
| } | ||
|
|
||
| } | ||
| } |
50 changes: 50 additions & 0 deletions
50
app/models/responses/addresslookup/JourneyOutcomeResponse.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /* | ||
| * Copyright 2025 HM Revenue & Customs | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package models.responses.addresslookup | ||
|
|
||
| import play.api.http.Status.{NOT_FOUND, OK} | ||
| import play.api.libs.json.JsSuccess | ||
| import uk.gov.hmrc.http.HttpReads | ||
|
|
||
|
|
||
| object JourneyOutcomeResponse { | ||
|
|
||
| type AddressLookupJourneyOutcome = Either[JourneyResultFailure, Option[JourneyResultAddressModel]] | ||
|
|
||
| implicit def getAddressLookupDetailsHttpReads: HttpReads[AddressLookupJourneyOutcome] = HttpReads { (_, _, response) => | ||
| response.status match { | ||
| case OK => | ||
| response.json.validate[JourneyResultAddressModel] match { | ||
| case JsSuccess(value, _) => | ||
| Right(Some(value)) | ||
| case _ => | ||
| Left(InvalidJson) | ||
| } | ||
| case NOT_FOUND => | ||
| Right(None) | ||
| case status => | ||
| Left(UnexpectedGetStatusFailure(status)) | ||
| } | ||
| } | ||
|
|
||
| sealed trait JourneyResultFailure extends Throwable | ||
|
|
||
| private case object InvalidJson extends JourneyResultFailure | ||
|
|
||
| case class UnexpectedGetStatusFailure(status: Int) extends JourneyResultFailure | ||
|
|
||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.