Skip to content

Commit

Permalink
Merge pull request #27 from hmrc/APID-85
Browse files Browse the repository at this point in the history
APID-85: Store records with status insead of _type as discriminator
  • Loading branch information
jameshall1999 authored Mar 3, 2021
2 parents c59411f + 813c561 commit 630b05e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.joda.time.DateTime

import java.util.UUID
import scala.collection.immutable
import scala.reflect.classTag

sealed trait OutboundSoapMessage {
val globalId: UUID
Expand All @@ -32,6 +33,22 @@ sealed trait OutboundSoapMessage {
val ccnHttpStatus: Int
}

object OutboundSoapMessage {

def typeToStatus (fullyQualifiedName: String): SendingStatus = {

if (fullyQualifiedName == classTag[SentOutboundSoapMessage].runtimeClass.getCanonicalName) {
SendingStatus.SENT
} else if (fullyQualifiedName == classTag[FailedOutboundSoapMessage].runtimeClass.getCanonicalName) {
SendingStatus.FAILED
} else if (fullyQualifiedName == classTag[RetryingOutboundSoapMessage].runtimeClass.getCanonicalName) {
SendingStatus.RETRYING
} else {
throw new IllegalArgumentException
}
}
}

case class SentOutboundSoapMessage(globalId: UUID,
messageId: Option[String],
soapMessage: String,
Expand Down Expand Up @@ -63,23 +80,15 @@ case class RetryingOutboundSoapMessage(globalId: UUID,
def toSent = SentOutboundSoapMessage(globalId, messageId, soapMessage, createDateTime, ccnHttpStatus, notificationUrl)
}

sealed trait SendingStatus extends EnumEntry {
val soapMessageType: String
}
sealed trait SendingStatus extends EnumEntry

object SendingStatus extends Enum[SendingStatus] with PlayJsonEnum[SendingStatus] {
val values: immutable.IndexedSeq[SendingStatus] = findValues

case object SENT extends SendingStatus {
override val soapMessageType: String = "uk.gov.hmrc.apiplatformoutboundsoap.models.SentOutboundSoapMessage"
}
case object SENT extends SendingStatus

case object FAILED extends SendingStatus {
override val soapMessageType: String = "uk.gov.hmrc.apiplatformoutboundsoap.models.FailedOutboundSoapMessage"
}
case object FAILED extends SendingStatus

case object RETRYING extends SendingStatus {
override val soapMessageType: String = "uk.gov.hmrc.apiplatformoutboundsoap.models.RetryingOutboundSoapMessage"
}
case object RETRYING extends SendingStatus

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@
package uk.gov.hmrc.apiplatformoutboundsoap.repositories

import org.joda.time.DateTime
import play.api.libs.json.{Format, Json, OFormat}
import play.api.libs.json.{Format, Json, JsonConfiguration, JsonNaming, OFormat}
import uk.gov.hmrc.apiplatformoutboundsoap.models.{FailedOutboundSoapMessage, OutboundSoapMessage, RetryingOutboundSoapMessage, SentOutboundSoapMessage}
import uk.gov.hmrc.mongo.json.ReactiveMongoFormats

private[repositories] object MongoFormatter {

implicit val cfg = JsonConfiguration(
discriminator = "status",

typeNaming = JsonNaming { fullName =>
OutboundSoapMessage.typeToStatus(fullName).entryName
})

implicit val dateFormat: Format[DateTime] = ReactiveMongoFormats.dateTimeFormats
implicit val outboundSoapMessageFormatter: OFormat[OutboundSoapMessage] = Json.format[OutboundSoapMessage]
implicit val retryingSoapMessageFormatter: OFormat[RetryingOutboundSoapMessage] = Json.format[RetryingOutboundSoapMessage]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class OutboundMessageRepository @Inject()(mongoComponent: ReactiveMongoComponent
import uk.gov.hmrc.apiplatformoutboundsoap.repositories.MongoFormatter.retryingSoapMessageFormatter

collection
.find(Json.obj("_type" -> SendingStatus.RETRYING.soapMessageType,
.find(Json.obj("status" -> SendingStatus.RETRYING.entryName,
"retryDateTime" -> Json.obj("$lte" -> now(UTC))), Option.empty[OutboundSoapMessage])
.sort(Json.obj("retryDateTime" -> 1))
.cursor[RetryingOutboundSoapMessage](ReadPreference.primaryPreferred)
Expand All @@ -80,7 +80,7 @@ class OutboundMessageRepository @Inject()(mongoComponent: ReactiveMongoComponent

def updateStatus(globalId: UUID, newStatus: SendingStatus): Future[Option[OutboundSoapMessage]] = {
findAndUpdate(Json.obj("globalId" -> globalId),
Json.obj("$set" -> Json.obj("_type" -> newStatus.soapMessageType)), fetchNewObject = true)
Json.obj("$set" -> Json.obj("status" -> newStatus.entryName)), fetchNewObject = true)
.map(_.result[OutboundSoapMessage])
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import org.scalatest.wordspec.AnyWordSpec
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.json.{JsObject, Json}
import play.api.test.Helpers.contentAsJson
import reactivemongo.api.ReadPreference
import reactivemongo.bson.BSONLong
import reactivemongo.core.errors.DatabaseException
import uk.gov.hmrc.apiplatformoutboundsoap.models.{FailedOutboundSoapMessage, RetryingOutboundSoapMessage, SendingStatus, SentOutboundSoapMessage}
import uk.gov.hmrc.mongo.RepositoryPreparation
import reactivemongo.play.json.ImplicitBSONHandlers.JsObjectDocumentWriter

import java.util.UUID.randomUUID

Expand All @@ -36,13 +39,18 @@ class OutboundMessageRepositoryISpec extends AnyWordSpec with Matchers with Repo
}

val retryingMessage = RetryingOutboundSoapMessage(randomUUID, Some("MessageId-A1"), "<IE4N03>payload</IE4N03>", DateTime.now(UTC), DateTime.now(UTC), ccnHttpStatus)
val sentMessage = SentOutboundSoapMessage(randomUUID, Some("MessageId-A1"), "<IE4N03>payload</IE4N03>", DateTime.now(UTC), ccnHttpStatus)
val sentMessage = SentOutboundSoapMessage(randomUUID, Some("MessageId-A2"), "<IE4N03>payload</IE4N03>", DateTime.now(UTC), ccnHttpStatus)
val failedMessage = FailedOutboundSoapMessage(randomUUID, Some("MessageId-A3"), "<IE4N03>payload</IE4N03>", DateTime.now(UTC), ccnHttpStatus)
"persist" should {

"insert a retrying message when it does not exist" in {
await(repo.persist(retryingMessage))

val fetchedRecords = await(repo.findAll(ReadPreference.primaryPreferred))
val Some(jsonRecord) = await(repo.collection.find(Json.obj()).one[JsObject])
(jsonRecord \ "status").as[String] shouldBe "RETRYING"


fetchedRecords.size shouldBe 1
fetchedRecords.head shouldBe retryingMessage
}
Expand All @@ -51,10 +59,24 @@ class OutboundMessageRepositoryISpec extends AnyWordSpec with Matchers with Repo
await(repo.persist(sentMessage))

val fetchedRecords = await(repo.findAll(ReadPreference.primaryPreferred))
val Some(jsonRecord) = await(repo.collection.find(Json.obj()).one[JsObject])
(jsonRecord \ "status").as[String] shouldBe "SENT"

fetchedRecords.size shouldBe 1
fetchedRecords.head shouldBe sentMessage
}

"insert a failed message when it does not exist" in {
await(repo.persist(failedMessage))

val fetchedRecords = await(repo.findAll(ReadPreference.primaryPreferred))
val Some(jsonRecord) = await(repo.collection.find(Json.obj()).one[JsObject])
(jsonRecord \ "status").as[String] shouldBe "FAILED"

fetchedRecords.size shouldBe 1
fetchedRecords.head shouldBe failedMessage
}

"message is persisted with TTL" in {
await(repo.persist(sentMessage))

Expand Down

0 comments on commit 630b05e

Please sign in to comment.