Skip to content

Commit

Permalink
PIN-4332 Resolved PR issues
Browse files Browse the repository at this point in the history
  • Loading branch information
nttdata-rtorsoli committed Jan 10, 2024
1 parent ab21e8c commit b604ec3
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ final case class PurposeApiServiceImpl(
purposeUUID <- purposeId.toFutureUUID
purpose <- purposeManagementService.getPurposeById(purposeUUID)
_ <- assertOrganizationIsAConsumer(organizationId, purpose.consumerId)
_ <- assertDailyCallsIsDifferentThanBefore(purpose, seed.dailyCalls)
version <- purposeManagementService.createPurposeVersion(purposeUUID, seed.toManagement)
published <- publish(organizationId, purpose, version.toPersistent)
} yield published.toApi
Expand All @@ -230,7 +231,6 @@ final case class PurposeApiServiceImpl(
eService => if (eService.mode == Deliver) Future.unit else Future.failed(EServiceNotInDeliverMode(eService.id)),
seed.isFreeOfCharge,
seed.freeOfChargeReason,
seed.dailyCalls,
(_, tenantKind) =>
seed
.toManagement(schemaOnlyValidation = true)(tenantKind)
Expand All @@ -253,7 +253,6 @@ final case class PurposeApiServiceImpl(
eService => if (eService.mode == Receive) Future.unit else Future.failed(EServiceNotInReceiveMode(eService.id)),
seed.isFreeOfCharge,
seed.freeOfChargeReason,
seed.dailyCalls,
(purpose, tenantKind) =>
seed
.toManagement(schemaOnlyValidation = true, purpose.riskAnalysisForm.map(_.toApi))(tenantKind)
Expand All @@ -268,15 +267,13 @@ final case class PurposeApiServiceImpl(
eServiceModeCheck: CatalogItem => Future[Unit],
isFreeOfCharge: Boolean,
freeOfChargeReason: Option[String],
dailyCalls: Int,
payload: (PersistentPurpose, PersistentTenantKind) => Future[PurposeManagementDependency.PurposeUpdateContent]
)(implicit contexts: Seq[(String, String)]): Future[Purpose] = for {
requesterOrgId <- getOrganizationIdFutureUUID(contexts)
purposeUUID <- purposeId.toFutureUUID
purpose <- purposeManagementService.getPurposeById(purposeUUID)
_ <- assertOrganizationIsAConsumer(requesterOrgId, purpose.consumerId)
_ <- assertPurposeIsInDraftState(purpose)
_ <- assertDailyCallsIsDifferentThanBefore(purpose, dailyCalls)
eService <- catalogManagementService.getEServiceById(purpose.eserviceId)
_ <- eServiceModeCheck(eService)
_ <- checkFreeOfCharge(isFreeOfCharge, freeOfChargeReason)
Expand Down Expand Up @@ -619,6 +616,21 @@ final case class PurposeApiServiceImpl(
dailyCalls = dailyCalls
)

def getDailyCalls(versions: Seq[PersistentPurposeVersion]): Int = {

val ordering: Ordering[OffsetDateTime] = Ordering(Ordering.by[OffsetDateTime, Long](_.toEpochSecond).reverse)

val latestNoWaiting: Option[Int] = versions
.filterNot(_.state == WaitingForApproval)
.sortBy(_.createdAt)(ordering)
.map(_.dailyCalls)
.headOption

val latestAll: Option[Int] = versions.sortBy(_.createdAt)(ordering).map(_.dailyCalls).headOption

latestNoWaiting.getOrElse(latestAll.getOrElse(0))
}

val result: Future[Purpose] = for {
organizationId <- getOrganizationIdFutureUUID(contexts)
tenant <- tenantManagementService.getTenantById(organizationId)
Expand All @@ -637,21 +649,6 @@ final case class PurposeApiServiceImpl(
onComplete(result) { clonePurposeResponse[Purpose](operationLabel)(clonePurpose200) }
}

private def getDailyCalls(versions: Seq[PersistentPurposeVersion]): Int = {

val ordering: Ordering[OffsetDateTime] = Ordering(Ordering.by[OffsetDateTime, Long](_.toEpochSecond).reverse)

val latestNoWaiting: Option[Int] = versions
.filterNot(_.state == WaitingForApproval)
.sortBy(_.createdAt)(ordering)
.map(_.dailyCalls)
.headOption

val latestAll: Option[Int] = versions.sortBy(_.createdAt)(ordering).map(_.dailyCalls).headOption

latestNoWaiting.getOrElse(latestAll.getOrElse(0))
}

override def retrieveLatestRiskAnalysisConfiguration(tenantKind: Option[String])(implicit
contexts: Seq[(String, String)],
toEntityMarshallerRiskAnalysisFormConfigResponse: ToEntityMarshaller[RiskAnalysisFormConfigResponse],
Expand Down Expand Up @@ -739,10 +736,12 @@ final case class PurposeApiServiceImpl(
}

private def assertDailyCallsIsDifferentThanBefore(purpose: PersistentPurpose, dailyCalls: Int): Future[Unit] = {
val previousDailyCalls = getDailyCalls(purpose.versions)
if (previousDailyCalls != dailyCalls)
Future.successful(())
else Future.failed(DailyCallsEqualThanBefore(purpose.id))
val ordering: Ordering[OffsetDateTime] = Ordering(Ordering.by[OffsetDateTime, Long](_.toEpochSecond).reverse)
val previousDailyCalls = purpose.versions.sortBy(_.createdAt)(ordering).map(_.dailyCalls).headOption
previousDailyCalls match {
case Some(x) if x != dailyCalls => Future.successful(())
case _ => Future.failed(DailyCallsEqualThanBefore(purpose.id))
}
}

private def isRiskAnalysisFormValid(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ object ResponseHandlers extends AkkaResponses {
)(result: Try[T])(implicit contexts: Seq[(String, String)], logger: LoggerTakingImplicit[ContextFieldsToLog]): Route =
result match {
case Success(s) => success(s)
case Failure(ex: DailyCallsEqualThanBefore) => badRequest(ex, logMessage)
case Failure(ex: OrganizationIsNotTheConsumer) => forbidden(ex, logMessage)
case Failure(ex: PurposeNotFound) => notFound(ex, logMessage)
case Failure(ex: PurposeVersionConflict) => conflict(ex, logMessage)
Expand All @@ -92,7 +93,6 @@ object ResponseHandlers extends AkkaResponses {
case Failure(ex: EServiceNotInDeliverMode) => badRequest(ex, logMessage)
case Failure(ex: TenantNotFound) => badRequest(ex, logMessage)
case Failure(ex: AgreementNotFound) => badRequest(ex, logMessage)
case Failure(ex: DailyCallsEqualThanBefore) => badRequest(ex, logMessage)
case Failure(ex: OrganizationIsNotTheConsumer) => forbidden(ex, logMessage)
case Failure(ex: PurposeNotInDraftState) => forbidden(ex, logMessage)
case Failure(ex: PurposeNotFound) => notFound(ex, logMessage)
Expand All @@ -111,7 +111,6 @@ object ResponseHandlers extends AkkaResponses {
case Failure(ex: EServiceNotInReceiveMode) => badRequest(ex, logMessage)
case Failure(ex: TenantNotFound) => badRequest(ex, logMessage)
case Failure(ex: AgreementNotFound) => badRequest(ex, logMessage)
case Failure(ex: DailyCallsEqualThanBefore) => badRequest(ex, logMessage)
case Failure(ex: OrganizationIsNotTheConsumer) => forbidden(ex, logMessage)
case Failure(ex: PurposeNotInDraftState) => forbidden(ex, logMessage)
case Failure(ex: PurposeNotFound) => notFound(ex, logMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1431,35 +1431,6 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
status shouldEqual StatusCodes.OK
}
}
"fail if daily calls attribute has the same value of previous version" in {

val purposeId = UUID.randomUUID()
val eserviceId = UUID.randomUUID()
val consumerId = UUID.randomUUID()
val purposeUpdateContent =
PurposeUpdateContent(
title = "A title",
description = "A description",
isFreeOfCharge = false,
riskAnalysisForm = None,
dailyCalls = 1000
)

val purpose =
SpecData.purpose.copy(eserviceId = eserviceId, consumerId = consumerId, versions = Seq(SpecData.purposeVersion))

implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> consumerId.toString)

mockPurposeRetrieve(purposeId, purpose)

Post() ~> service.updatePurpose(purposeId.toString, purposeUpdateContent) ~> check {
status shouldEqual StatusCodes.BadRequest
val problem = responseAs[Problem]
problem.status shouldBe StatusCodes.BadRequest.intValue
problem.errors.head.code shouldBe "012-0028"
}
}
"fail if case of eService with Receive mode" in {

val purposeId = UUID.randomUUID()
Expand Down Expand Up @@ -1630,35 +1601,6 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
status shouldEqual StatusCodes.OK
}
}
"fail if daily calls attribute has the same value of previous version" in {

val purposeId = UUID.randomUUID()
val eserviceId = UUID.randomUUID()
val consumerId = UUID.randomUUID()

val reversePurposeUpdateContent =
ReversePurposeUpdateContent(
title = "A title",
description = "A description",
isFreeOfCharge = false,
dailyCalls = 1000
)

val purpose =
SpecData.purpose.copy(eserviceId = eserviceId, consumerId = consumerId, versions = Seq(SpecData.purposeVersion))

implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> consumerId.toString)

mockPurposeRetrieve(purposeId, purpose)

Post() ~> service.updateReversePurpose(purposeId.toString, reversePurposeUpdateContent) ~> check {
status shouldEqual StatusCodes.BadRequest
val problem = responseAs[Problem]
problem.status shouldBe StatusCodes.BadRequest.intValue
problem.errors.head.code shouldBe "012-0028"
}
}
"fail if case of eService with Deliver mode" in {

val purposeId = UUID.randomUUID()
Expand Down Expand Up @@ -2214,19 +2156,20 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> consumerId.toString)

val version2_1 = SpecData.purposeVersion.copy(id = UUID.randomUUID(), state = Active, dailyCalls = 1000)
val version2_1 = SpecData.purposeVersion.copy(id = UUID.randomUUID(), state = Active, dailyCalls = 1002)
val purpose2 = SpecData.purpose.copy(eserviceId = eserviceId, consumerId = consumerId, versions = Seq(version2_1))

val path: String = "/here/there/foo/bar.pdf"
val document: PersistentPurposeVersionDocument =
PersistentPurposeVersionDocument(documentId, "application/pdf", path, SpecData.timestamp)

val version1_1 = SpecData.purposeVersion.copy(id = purposeVersionId1, state = Active)
val version1_1 = SpecData.purposeVersion.copy(id = purposeVersionId1, state = Active, dailyCalls = 1000)
val version1_2 = SpecData.purposeVersion.copy(
id = purposeVersionId2,
state = WaitingForApproval,
riskAnalysis = Some(document),
firstActivationAt = Some(SpecData.timestamp)
firstActivationAt = Some(SpecData.timestamp),
dailyCalls = 1001
)

val purpose =
Expand All @@ -2238,15 +2181,15 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
)

val purposes = Seq(purpose, purpose2)
val seed: PurposeVersionSeed = PurposeVersionSeed(dailyCalls = 1000)
val seed: PurposeVersionSeed = PurposeVersionSeed(dailyCalls = 2000)

val purposeVersion = PersistentPurposeVersion(
id = purposeVersionId3,
state = Active,
createdAt = SpecData.timestamp,
updatedAt = None,
expectedApprovalDate = None,
dailyCalls = seed.dailyCalls,
dailyCalls = 2000,
riskAnalysis = Some(document),
firstActivationAt = Some(SpecData.timestamp),
suspendedAt = None
Expand Down Expand Up @@ -2274,7 +2217,8 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
riskAnalysis = Some(
PurposeManagementDependency.PurposeVersionDocument(documentId, "application/pdf", path, SpecData.timestamp)
),
firstActivationAt = Some(SpecData.timestamp)
firstActivationAt = Some(SpecData.timestamp),
dailyCalls = 2000
)

mockVersionFirstActivation(purposeId, purposeVersionId3, eService.producerId, purpose.consumerId, updatedVersion)
Expand Down Expand Up @@ -2306,7 +2250,7 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> consumerId.toString)

val version2_1 = SpecData.purposeVersion.copy(id = UUID.randomUUID(), state = Active, dailyCalls = 1000)
val version2_1 = SpecData.purposeVersion.copy(id = UUID.randomUUID(), state = Active, dailyCalls = 1002)
val purpose2 = SpecData.purpose.copy(eserviceId = eserviceId, consumerId = consumerId, versions = Seq(version2_1))

val path: String = "/here/there/foo/bar.pdf"
Expand All @@ -2318,7 +2262,8 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
id = purposeVersionId2,
state = WaitingForApproval,
riskAnalysis = Some(document),
firstActivationAt = Some(SpecData.timestamp)
firstActivationAt = Some(SpecData.timestamp),
dailyCalls = 1001
)

val purpose =
Expand All @@ -2330,15 +2275,15 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
)

val purposes = Seq(purpose, purpose2)
val seed: PurposeVersionSeed = PurposeVersionSeed(dailyCalls = 1000)
val seed: PurposeVersionSeed = PurposeVersionSeed(dailyCalls = 2000)

val purposeVersion = PersistentPurposeVersion(
id = purposeVersionId3,
state = WaitingForApproval,
createdAt = SpecData.timestamp,
updatedAt = None,
expectedApprovalDate = None,
dailyCalls = seed.dailyCalls,
dailyCalls = 2000,
riskAnalysis = None,
firstActivationAt = Some(SpecData.timestamp),
suspendedAt = None
Expand All @@ -2364,7 +2309,8 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
id = purposeVersionId3,
state = PurposeManagementDependency.PurposeVersionState.WAITING_FOR_APPROVAL,
riskAnalysis = None,
firstActivationAt = Some(SpecData.timestamp)
firstActivationAt = Some(SpecData.timestamp),
dailyCalls = 2000
)

val payload = PurposeManagementDependency.StateChangeDetails(
Expand All @@ -2383,7 +2329,51 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate
responseAs[PurposeVersion] shouldEqual expected
}
}
"fail in case of version with the same dailyCalls than previous version" in {

val consumerId = UUID.randomUUID()
val documentId = UUID.randomUUID()
val purposeId = UUID.randomUUID()
val purposeVersionId1 = UUID.randomUUID()
val purposeVersionId2 = UUID.randomUUID()
val eserviceId = UUID.randomUUID()

implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> consumerId.toString)

val path: String = "/here/there/foo/bar.pdf"
val document: PersistentPurposeVersionDocument =
PersistentPurposeVersionDocument(documentId, "application/pdf", path, SpecData.timestamp)

val version1_1 = SpecData.purposeVersion.copy(id = purposeVersionId1, state = Draft, dailyCalls = 1000)
val version1_2 = SpecData.purposeVersion.copy(
id = purposeVersionId2,
state = WaitingForApproval,
riskAnalysis = Some(document),
firstActivationAt = None,
createdAt = SpecData.timestamp.plusDays(1),
dailyCalls = 1001
)

val purpose =
SpecData.purpose.copy(
id = purposeId,
versions = Seq(version1_1, version1_2),
consumerId = consumerId,
eserviceId = eserviceId
)

val seed: PurposeVersionSeed = PurposeVersionSeed(dailyCalls = 1001)

mockPurposeRetrieve(purposeId, purpose)

Get() ~> service.createPurposeVersion(purposeId.toString, seed) ~> check {
status shouldEqual StatusCodes.BadRequest
val problem = responseAs[Problem]
problem.status shouldBe StatusCodes.BadRequest.intValue
problem.errors.head.code shouldBe "012-0028"
}
}
"fail if Purpose does not exist" in {

val purposeId = UUID.randomUUID()
Expand Down

0 comments on commit b604ec3

Please sign in to comment.