diff --git a/README.md b/README.md index 063fce0..bc1f08f 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,9 @@ original request. | `To` | This property identifies the logical address of the intended receiver of the message | | `Body.CoD.EventTimestamp` | A timestamp indicating when the error was recorded | +### Response +HTTP Status: 202 (ACCEPTED) with an empty body + ### Confirmation of exception request ### Request headers | Name | Description | @@ -164,6 +167,19 @@ original request. | `Body.CoE.Severity` | One of Critical, Emergency, Error, Warning, Info in descending order of impact | | `Body.CoE.EventTimestamp` | A timestamp indicating when the error was recorded | | `Body.CoE.Payload` | A structure containing a standard SOAP1.2 Fault element | -### License +### Response +HTTP Status: 202 (ACCEPTED) with an empty body + +### Error scenarios (both request types) +| Scenario | HTTP Status | +| --- | --- | +| request body cannot be parsed as XML | `400` | +| `RelatesTo` element missing from request body | `400` | +| `RelatesTo` element is blank or contains only whitespace in request body | `400` | +| `x-soap-action` header missing | `400` | +| `x-soap-action` header is blank or contains only whitespace | `400` | +| message ID supplied in `RelatesTo` element in request body does not match that of any message stored in the database | `404` | + +### License This code is open source software licensed under the [Apache 2.0 License]("http://www.apache.org/licenses/LICENSE-2.0.html"). diff --git a/app/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationController.scala b/app/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationController.scala index 51b041f..4b2ee99 100644 --- a/app/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationController.scala +++ b/app/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationController.scala @@ -42,7 +42,7 @@ class ConfirmationController @Inject()(cc: ControllerComponents, def callService(deliveryStatus: DeliveryStatus, id: String): Future[Result] = { if(id.trim.nonEmpty) { confirmationService.processConfirmation(xml, id.trim, deliveryStatus) map { - case NoContentUpdateResult => NoContent + case UpdateSuccessResult => Accepted case _ => logger.warn(s"No message found with global ID [$id]. Request is ${xml}") NotFound diff --git a/app/uk/gov/hmrc/apiplatformoutboundsoap/models/common/requestsAndResponses.scala b/app/uk/gov/hmrc/apiplatformoutboundsoap/models/common/requestsAndResponses.scala index 62902b7..568b06d 100644 --- a/app/uk/gov/hmrc/apiplatformoutboundsoap/models/common/requestsAndResponses.scala +++ b/app/uk/gov/hmrc/apiplatformoutboundsoap/models/common/requestsAndResponses.scala @@ -20,7 +20,7 @@ sealed trait UpdateResult case object MessageIdNotFoundResult extends UpdateResult -case object NoContentUpdateResult extends UpdateResult +case object UpdateSuccessResult extends UpdateResult diff --git a/app/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationService.scala b/app/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationService.scala index 5bd8004..9bea91f 100644 --- a/app/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationService.scala +++ b/app/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationService.scala @@ -18,7 +18,7 @@ package uk.gov.hmrc.apiplatformoutboundsoap.services import uk.gov.hmrc.apiplatformoutboundsoap.connectors.NotificationCallbackConnector import uk.gov.hmrc.apiplatformoutboundsoap.models._ -import uk.gov.hmrc.apiplatformoutboundsoap.models.common.{MessageIdNotFoundResult, NoContentUpdateResult, UpdateResult} +import uk.gov.hmrc.apiplatformoutboundsoap.models.common.{MessageIdNotFoundResult, UpdateSuccessResult, UpdateResult} import uk.gov.hmrc.apiplatformoutboundsoap.repositories.OutboundMessageRepository import uk.gov.hmrc.http.HeaderCarrier @@ -32,10 +32,10 @@ class ConfirmationService @Inject()(outboundMessageRepository: OutboundMessageRe (implicit val ec: ExecutionContext) { def processConfirmation(confRqst: NodeSeq, msgId: String, delStatus: DeliveryStatus)(implicit hc: HeaderCarrier): Future[UpdateResult] = { - def doUpdate(id: String, status: DeliveryStatus, body: String): Future[NoContentUpdateResult.type] = { + def doUpdate(id: String, status: DeliveryStatus, body: String): Future[UpdateSuccessResult.type] = { outboundMessageRepository.updateConfirmationStatus(id, status, body) map { maybeOutboundSoapMessage => maybeOutboundSoapMessage.map(outboundSoapMessage => notificationCallbackConnector.sendNotification(outboundSoapMessage))} map { - case _ => NoContentUpdateResult + case _ => UpdateSuccessResult } } diff --git a/test/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationControllerSpec.scala b/test/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationControllerSpec.scala index e2c4d5f..57d6f1c 100644 --- a/test/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationControllerSpec.scala +++ b/test/uk/gov/hmrc/apiplatformoutboundsoap/controllers/ConfirmationControllerSpec.scala @@ -26,7 +26,7 @@ import play.api.test.Helpers._ import play.api.test.{FakeRequest, Helpers} import uk.gov.hmrc.apiplatformoutboundsoap.controllers.actionBuilders.ValidateConfirmationTypeAction import uk.gov.hmrc.apiplatformoutboundsoap.models.DeliveryStatus -import uk.gov.hmrc.apiplatformoutboundsoap.models.common.{MessageIdNotFoundResult, NoContentUpdateResult} +import uk.gov.hmrc.apiplatformoutboundsoap.models.common.{MessageIdNotFoundResult, UpdateSuccessResult} import uk.gov.hmrc.apiplatformoutboundsoap.services.ConfirmationService import scala.concurrent.ExecutionContext.Implicits.global @@ -127,10 +127,10 @@ class ConfirmationControllerSpec extends AnyWordSpec with Matchers with GuiceOne val confirmationTypeCaptor = ArgumentCaptor.forClass(classOf[DeliveryStatus]) val requestBodyXml: Elem = XML.loadString(createCodMessage("1234abcd")) when(confirmationServiceMock.processConfirmation(confirmationXmlRequestCaptor.capture, msgIdCaptor.capture(), confirmationTypeCaptor.capture)(*)) - .thenReturn(Future.successful(NoContentUpdateResult)) + .thenReturn(Future.successful(UpdateSuccessResult)) val result: Future[Result] = underTest.message()(fakeRequest.withBody(requestBodyXml) .withHeaders("ContentType" -> "text/xml", "x-soap-action" -> "CCN2.Service.Platform.AcknowledgementService/CoD")) - status(result) shouldBe NO_CONTENT + status(result) shouldBe ACCEPTED confirmationXmlRequestCaptor.getValue shouldBe requestBodyXml msgIdCaptor.getValue shouldBe msgIdCod confirmationTypeCaptor.getValue shouldBe DeliveryStatus.COD @@ -162,10 +162,10 @@ class ConfirmationControllerSpec extends AnyWordSpec with Matchers with GuiceOne val confirmationTypeCaptor = ArgumentCaptor.forClass(classOf[DeliveryStatus]) val requestBodyXml: Elem = XML.loadString(coeMessage) when(confirmationServiceMock.processConfirmation(confirmationXmlRequestCaptor.capture, msgIdCaptor.capture(), confirmationTypeCaptor.capture)(*)) - .thenReturn(Future.successful(NoContentUpdateResult)) + .thenReturn(Future.successful(UpdateSuccessResult)) val result: Future[Result] = underTest.message()(fakeRequest.withBody(requestBodyXml) .withHeaders("ContentType" -> "text/xml", "x-soap-action" -> "CCN2.Service.Platform.AcknowledgementService/CoE")) - status(result) shouldBe NO_CONTENT + status(result) shouldBe ACCEPTED confirmationXmlRequestCaptor.getValue shouldBe requestBodyXml msgIdCaptor.getValue shouldBe msgIdCoe confirmationTypeCaptor.getValue shouldBe DeliveryStatus.COE diff --git a/test/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationServiceSpec.scala b/test/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationServiceSpec.scala index 4feea20..8835ea1 100644 --- a/test/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationServiceSpec.scala +++ b/test/uk/gov/hmrc/apiplatformoutboundsoap/services/ConfirmationServiceSpec.scala @@ -28,7 +28,7 @@ import play.api.test.Helpers._ import uk.gov.hmrc.apiplatformoutboundsoap.config.AppConfig import uk.gov.hmrc.apiplatformoutboundsoap.connectors.{NotificationCallbackConnector, OutboundConnector} import uk.gov.hmrc.apiplatformoutboundsoap.models._ -import uk.gov.hmrc.apiplatformoutboundsoap.models.common.{MessageIdNotFoundResult, NoContentUpdateResult, UpdateResult} +import uk.gov.hmrc.apiplatformoutboundsoap.models.common.{MessageIdNotFoundResult, UpdateSuccessResult, UpdateResult} import uk.gov.hmrc.apiplatformoutboundsoap.repositories.OutboundMessageRepository import uk.gov.hmrc.http.HeaderCarrier @@ -84,7 +84,7 @@ class ConfirmationServiceSpec extends AnyWordSpec with Matchers with GuiceOneApp when(outboundMessageRepositoryMock.findById(*)).thenReturn(successful(Some(outboundSoapMessage))) when(outboundMessageRepositoryMock.updateConfirmationStatus(*,*,*)).thenReturn(successful(Some(outboundSoapMessage))) val result: UpdateResult = await(underTest.processConfirmation(confirmationRequestCod, msgId, DeliveryStatus.COD)) - result shouldBe NoContentUpdateResult + result shouldBe UpdateSuccessResult verify(outboundMessageRepositoryMock).findById("abcd1234") verify(outboundMessageRepositoryMock).updateConfirmationStatus("abcd1234", DeliveryStatus.COD, confirmationRequestCod.toString()) } @@ -93,7 +93,7 @@ class ConfirmationServiceSpec extends AnyWordSpec with Matchers with GuiceOneApp when(outboundMessageRepositoryMock.findById(*)).thenReturn(successful(Some(outboundSoapMessage))) when(outboundMessageRepositoryMock.updateConfirmationStatus(*,*,*)).thenReturn(successful(Some(outboundSoapMessage))) val result: UpdateResult = await(underTest.processConfirmation(confirmationRequestCod, msgId, DeliveryStatus.COE)) - result shouldBe NoContentUpdateResult + result shouldBe UpdateSuccessResult verify(outboundMessageRepositoryMock).updateConfirmationStatus("abcd1234", DeliveryStatus.COE, confirmationRequestCod.toString()) }