-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from hmrc/API-7262
API-7262 - Implement Acknowledge forwarding
- Loading branch information
Showing
15 changed files
with
474 additions
and
28 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
app/uk/gov/hmrc/apiplatforminboundsoap/config/ConfigurationProviders.scala
This file contains 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,46 @@ | ||
/* | ||
* Copyright 2023 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 uk.gov.hmrc.apiplatforminboundsoap.config | ||
|
||
import javax.inject.{Inject, Provider, Singleton} | ||
|
||
import play.api.inject.{Binding, Module} | ||
import play.api.{Configuration, Environment} | ||
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig | ||
|
||
import uk.gov.hmrc.apiplatforminboundsoap.connectors.ApiPlatformOutboundSoapConnector | ||
|
||
class ConfigurationModule extends Module { | ||
|
||
override def bindings(environment: Environment, configuration: Configuration): List[Binding[_]] = { | ||
|
||
List( | ||
bind[ApiPlatformOutboundSoapConnector.Config].toProvider[ApiPlatformOutboundSoapConnectorConfigProvider] | ||
) | ||
} | ||
} | ||
|
||
@Singleton | ||
class ApiPlatformOutboundSoapConnectorConfigProvider @Inject() (val configuration: Configuration) | ||
extends ServicesConfig(configuration) | ||
with Provider[ApiPlatformOutboundSoapConnector.Config] { | ||
|
||
override def get(): ApiPlatformOutboundSoapConnector.Config = { | ||
val url = baseUrl("api-platform-outbound-soap") | ||
ApiPlatformOutboundSoapConnector.Config(url) | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
app/uk/gov/hmrc/apiplatforminboundsoap/connectors/ApiPlatformOutboundSoapConnector.scala
This file contains 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,65 @@ | ||
/* | ||
* Copyright 2023 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 uk.gov.hmrc.apiplatforminboundsoap.connectors | ||
|
||
import java.net.URL | ||
import javax.inject.{Inject, Singleton} | ||
import scala.concurrent.{ExecutionContext, Future} | ||
import scala.util.control.NonFatal | ||
import scala.xml.NodeSeq | ||
|
||
import play.api.Logging | ||
import play.api.http.Status | ||
import uk.gov.hmrc.http.HttpReads.Implicits._ | ||
import uk.gov.hmrc.http.client.HttpClientV2 | ||
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse, UpstreamErrorResponse} | ||
|
||
import uk.gov.hmrc.apiplatforminboundsoap.models.{SendFail, SendResult, SendSuccess} | ||
import uk.gov.hmrc.apiplatforminboundsoap.xml.XmlHelper | ||
|
||
object ApiPlatformOutboundSoapConnector { | ||
case class Config(baseUrl: String) | ||
} | ||
|
||
@Singleton | ||
class ApiPlatformOutboundSoapConnector @Inject() (httpClientV2: HttpClientV2, appConfig: ApiPlatformOutboundSoapConnector.Config)(implicit ec: ExecutionContext) | ||
extends Logging with XmlHelper { | ||
|
||
def postMessage(soapRequest: NodeSeq)(implicit hc: HeaderCarrier): Future[SendResult] = { | ||
|
||
val newHeaders: Seq[(String, String)] = List("x-soap-action" -> getSoapAction(soapRequest).getOrElse("")) | ||
|
||
postHttpRequest(soapRequest, appConfig.baseUrl, newHeaders).map { | ||
case Right(_) => SendSuccess | ||
case Left(UpstreamErrorResponse(_, statusCode, _, _)) => | ||
logger.warn(s"Sending message failed with status code $statusCode") | ||
SendFail(statusCode) | ||
} | ||
.recoverWith { | ||
case NonFatal(e) => | ||
logger.warn(s"NonFatal error ${e.getMessage} while forwarding message", e) | ||
Future.successful(SendFail(Status.INTERNAL_SERVER_ERROR)) | ||
} | ||
} | ||
|
||
private def postHttpRequest(soapEnvelope: NodeSeq, baseUrl: String, headers: Seq[(String, String)])(implicit hc: HeaderCarrier): Future[Either[UpstreamErrorResponse, HttpResponse]] = { | ||
httpClientV2.post(new URL(baseUrl)) | ||
.withBody(soapEnvelope) | ||
.transform(_.addHttpHeaders(headers: _*)) | ||
.execute[Either[UpstreamErrorResponse, HttpResponse]] | ||
} | ||
} |
This file contains 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 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 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 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
17 changes: 17 additions & 0 deletions
17
it/test/resources/acknowledgement-requests/cod_request.xml
This file contains 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,17 @@ | ||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ccn2="http://ccn2.ec.eu/CCN2.Service.Platform.Acknowledgement.Schema"> | ||
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> | ||
<wsa:Action>CCN2.Service.Platform.AcknowledgementService/CoD</wsa:Action> | ||
<wsa:From> | ||
<wsa:Address>theEU</wsa:Address> | ||
</wsa:From> | ||
<wsa:RelatesTo RelationshipType="http://ccn2.ec.eu/addressing/ack">5d3a71e3-2a1a-43f1-a246-831dff41e9a1 | ||
</wsa:RelatesTo> | ||
<wsa:MessageID>0316250e-0873-49bc-a74e-f6f5efa892c7</wsa:MessageID> | ||
<wsa:To>HMRC</wsa:To> | ||
</soap:Header> | ||
<soap:Body> | ||
<ccn2:CoD> | ||
<ccn2:EventTimestamp>2021-03-10T09:30:10Z</ccn2:EventTimestamp> | ||
</ccn2:CoD> | ||
</soap:Body> | ||
</soap:Envelope> |
98 changes: 98 additions & 0 deletions
98
...uk/gov/hmrc/apiplatforminboundsoap/connectors/ApiPlatformOutboundSoapConnectorISpec.scala
This file contains 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,98 @@ | ||
/* | ||
* Copyright 2023 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 uk.gov.hmrc.apiplatforminboundsoap.connectors | ||
|
||
import scala.io.Source | ||
import scala.xml.{Elem, XML} | ||
|
||
import com.github.tomakehurst.wiremock.http.Fault | ||
import org.scalatest.matchers.should.Matchers | ||
import org.scalatest.wordspec.AnyWordSpec | ||
import org.scalatestplus.play.guice.GuiceOneAppPerSuite | ||
|
||
import play.api.Application | ||
import play.api.inject.guice.GuiceApplicationBuilder | ||
import play.api.test.Helpers._ | ||
import uk.gov.hmrc.http.HeaderCarrier | ||
import uk.gov.hmrc.http.test.ExternalWireMockSupport | ||
|
||
import uk.gov.hmrc.apiplatforminboundsoap.models.{SendFail, SendResult, SendSuccess} | ||
import uk.gov.hmrc.apiplatforminboundsoap.stubs.ApiPlatformOutboundSoapStub | ||
import uk.gov.hmrc.apiplatforminboundsoap.xml.XmlHelper | ||
|
||
class ApiPlatformOutboundSoapConnectorISpec extends AnyWordSpec with Matchers with GuiceOneAppPerSuite | ||
with ExternalWireMockSupport with ApiPlatformOutboundSoapStub with XmlHelper { | ||
override implicit lazy val app: Application = appBuilder.build() | ||
implicit val hc: HeaderCarrier = HeaderCarrier() | ||
|
||
protected def appBuilder: GuiceApplicationBuilder = | ||
new GuiceApplicationBuilder() | ||
.configure( | ||
"metrics.enabled" -> false, | ||
"auditing.enabled" -> false, | ||
"microservice.services.api-platform-outbound-soap.host" -> externalWireMockHost, | ||
"microservice.services.api-platform-outbound-soap.port" -> externalWireMockPort | ||
) | ||
|
||
trait Setup { | ||
val underTest: ApiPlatformOutboundSoapConnector = app.injector.instanceOf[ApiPlatformOutboundSoapConnector] | ||
|
||
def readFromFile(fileName: String) = { | ||
XML.load(Source.fromResource(fileName).bufferedReader()) | ||
} | ||
|
||
val codRequestBody: Elem = readFromFile("acknowledgement-requests/cod_request.xml") | ||
|
||
def forwardedHeaders(xmlBody: Elem) = Seq[(String, String)]("x-soap-action" -> getSoapAction(xmlBody).getOrElse("")) | ||
val expectedHeaders = forwardedHeaders(codRequestBody) | ||
|
||
} | ||
|
||
"postMessage" should { | ||
|
||
"return success status (for COD) when returned by the outbound soap service" in new Setup { | ||
primeStubForSuccess(codRequestBody, OK) | ||
|
||
val result: SendResult = await(underTest.postMessage(codRequestBody)) | ||
|
||
result shouldBe SendSuccess | ||
verifyRequestBody(codRequestBody) | ||
verifyHeader(expectedHeaders.head._1, expectedHeaders.head._2) | ||
} | ||
|
||
"return error status returned by the outbound soap service" in new Setup { | ||
val expectedStatus: Int = INTERNAL_SERVER_ERROR | ||
primeStubForSuccess(codRequestBody, expectedStatus) | ||
|
||
val result: SendResult = await(underTest.postMessage(codRequestBody)) | ||
|
||
result shouldBe SendFail(expectedStatus) | ||
verifyHeader(expectedHeaders.head._1, expectedHeaders.head._2) | ||
} | ||
|
||
"return error status when soap fault is returned by the outbound soap service" in new Setup { | ||
val responseBody = "<Envelope><Body>foobar</Body></Envelope>" | ||
Seq(Fault.CONNECTION_RESET_BY_PEER, Fault.EMPTY_RESPONSE, Fault.MALFORMED_RESPONSE_CHUNK, Fault.RANDOM_DATA_THEN_CLOSE) foreach { fault => | ||
primeStubForFault(codRequestBody, responseBody, fault) | ||
|
||
val result: SendResult = await(underTest.postMessage(codRequestBody)) | ||
|
||
result shouldBe SendFail(INTERNAL_SERVER_ERROR) | ||
} | ||
} | ||
} | ||
} |
This file contains 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 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
Oops, something went wrong.