Skip to content

Commit

Permalink
fix: openAPI mutability #1115 (#1494)
Browse files Browse the repository at this point in the history
Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
  • Loading branch information
yshyn-iohk authored Jan 15, 2025
1 parent ec6caa5 commit 1e19b04
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ case class ErrorResponse(
)

object ErrorResponse {
val example = ErrorResponse(
404,
"NotFound",
"Not Found",
Some("The requested resource was not found"),
INSTANCE_URI_PREFIX + UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479")
)

given encoder: zio.json.JsonEncoder[ErrorResponse] = DeriveJsonEncoder.gen[ErrorResponse]

given decoder: zio.json.JsonDecoder[ErrorResponse] = DeriveJsonDecoder.gen[ErrorResponse]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import org.hyperledger.identus.connect.controller.http.Connection.annotations
import org.hyperledger.identus.connect.controller.http.Connection.annotations.goalcode
import org.hyperledger.identus.connect.core.model
import org.hyperledger.identus.connect.core.model.ConnectionRecord.Role
import org.hyperledger.identus.shared.models.{FailureInfo, StatusCode}
import sttp.model.Uri
import sttp.tapir.{Schema, Validator}
import sttp.tapir.Schema.annotations.{description, encodedExample, validate}
Expand Down Expand Up @@ -207,8 +206,7 @@ object Connection {
object metaLastFailure
extends Annotation[ErrorResponse](
description = "The last failure if any.",
example =
ErrorResponse.failureToErrorResponseConversion(FailureInfo("Error", StatusCode.NotFound, "Not Found"))
example = ErrorResponse.example
)

object self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ object StatusListCredential {
object issuanceDate
extends Annotation[Instant](
description = "Issuance timestamp of status list credential",
example = Instant.now()
example = Instant.parse("2025-01-01T22:40:34.560891Z")
)

object credentialSubject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import org.hyperledger.identus.api.http.{Annotation, ErrorResponse}
import org.hyperledger.identus.issue.controller.http.IssueCredentialRecord.annotations
import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, Base64}
import org.hyperledger.identus.pollux.core.model.IssueCredentialRecord as PolluxIssueCredentialRecord
import org.hyperledger.identus.shared.models.{FailureInfo, StatusCode}
import sttp.tapir.{Schema, Validator}
import sttp.tapir.json.zio.schemaForZioJsonValue
import sttp.tapir.Schema.annotations.{description, encodedExample, validate}
Expand Down Expand Up @@ -195,7 +194,7 @@ object IssueCredentialRecord {
object createdAt
extends Annotation[OffsetDateTime](
description = "The date and time when the issue credential record was created.",
example = OffsetDateTime.now()
example = OffsetDateTime.parse("2023-01-01T00:00:00Z")
)

object updatedAt
Expand Down Expand Up @@ -299,8 +298,7 @@ object IssueCredentialRecord {
object metaLastFailure
extends Annotation[ErrorResponse](
description = "The last failure if any.",
example =
ErrorResponse.failureToErrorResponseConversion(FailureInfo("Error", StatusCode.NotFound, "Not Found"))
example = ErrorResponse.example
)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, Base64, Json
import org.hyperledger.identus.mercury.protocol.presentproof.{Presentation, RequestPresentation}
import org.hyperledger.identus.pollux.core.model.PresentationRecord
import org.hyperledger.identus.presentproof.controller.http.PresentationStatus.annotations
import org.hyperledger.identus.shared.models.{FailureInfo, StatusCode}
import sttp.tapir.{Schema, Validator}
import sttp.tapir.json.zio.schemaForZioJsonValue
import sttp.tapir.Schema.annotations.{description, encodedExample, validate}
Expand Down Expand Up @@ -196,8 +195,7 @@ object PresentationStatus {
object metaLastFailure
extends Annotation[ErrorResponse](
description = "The last failure if any.",
example =
ErrorResponse.failureToErrorResponseConversion(FailureInfo("Error", StatusCode.NotFound, "Not Found"))
example = ErrorResponse.example
)

object goalcode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import org.hyperledger.identus.presentproof.controller.PresentProofController
import org.hyperledger.identus.system.controller.SystemController
import org.hyperledger.identus.verification.controller.VcVerificationController
import org.scalatestplus.mockito.MockitoSugar.*
import sttp.apispec.openapi.circe.yaml.*
import sttp.apispec.openapi.OpenAPI
import sttp.tapir.docs.openapi.OpenAPIDocsInterpreter
import zio.{Scope, ZIO, ZIOAppArgs, ZIOAppDefault, ZLayer}
import zio.{Config, IO, Scope, ZIO, ZIOAppArgs, ZIOAppDefault, ZLayer}
import zio.config.typesafe.TypesafeConfigProvider

import java.nio.charset.StandardCharsets
Expand All @@ -34,43 +36,48 @@ import scala.util.Using
object Tapir2StaticOAS extends ZIOAppDefault {

@main override def run: ZIO[Any & ZIOAppArgs & Scope, Any, Any] = {
val effect = for {
for {
args <- getArgs
_ <- ZIO.when(args.length != 2)(ZIO.fail("Usage: Tapir2StaticOAS <output file> <server url>"))
allEndpoints <- AgentHttpServer.agentRESTServiceEndpoints
model <- OpenAPISpecificationGenerator.generate
} yield {
import sttp.apispec.openapi.circe.yaml.*
val model = DocModels.customiseDocsModel(OpenAPIDocsInterpreter().toOpenAPI(allEndpoints.map(_.endpoint), "", ""))
val yaml = model.info(model.info.copy(version = args(1))).toYaml3_0_3
val path = Path.of(args.head)
Using(Files.newBufferedWriter(path, StandardCharsets.UTF_8)) { writer => writer.write(yaml) }
}
val configLayer = ZLayer.fromZIO(
TypesafeConfigProvider
.fromTypesafeConfig(ConfigFactory.load())
.load(AppConfig.config)
)
effect.provideSomeLayer(
ZLayer.succeed(mock[ConnectionController]) ++
ZLayer.succeed(mock[CredentialDefinitionController]) ++
ZLayer.succeed(mock[CredentialSchemaController]) ++
ZLayer.succeed(mock[CredentialStatusController]) ++
ZLayer.succeed(mock[VerificationPolicyController]) ++
ZLayer.succeed(mock[DIDRegistrarController]) ++
ZLayer.succeed(mock[PresentProofController]) ++
ZLayer.succeed(mock[VcVerificationController]) ++
ZLayer.succeed(mock[IssueController]) ++
ZLayer.succeed(mock[DIDController]) ++
ZLayer.succeed(mock[SystemController]) ++
ZLayer.succeed(mock[EntityController]) ++
ZLayer.succeed(mock[WalletManagementController]) ++
ZLayer.succeed(mock[DefaultAuthenticator]) ++
ZLayer.succeed(mock[EventController]) ++
ZLayer.succeed(mock[CredentialIssuerController]) ++
ZLayer.succeed(mock[PresentationExchangeController]) ++
ZLayer.succeed(mock[Oid4vciAuthenticatorFactory]) ++
configLayer
)
}
}

object OpenAPISpecificationGenerator {
def generate: IO[Config.Error, OpenAPI] =
for {
allEndpoints <- AgentHttpServer.agentRESTServiceEndpoints provideSomeLayer layers
openApi = DocModels.customiseDocsModel(OpenAPIDocsInterpreter().toOpenAPI(allEndpoints.map(_.endpoint), "", ""))
} yield openApi

private val configLayer = ZLayer.fromZIO(
TypesafeConfigProvider
.fromTypesafeConfig(ConfigFactory.load())
.load(AppConfig.config)
)

private def layers = ZLayer.succeed(mock[ConnectionController]) ++
ZLayer.succeed(mock[CredentialDefinitionController]) ++
ZLayer.succeed(mock[CredentialSchemaController]) ++
ZLayer.succeed(mock[CredentialStatusController]) ++
ZLayer.succeed(mock[VerificationPolicyController]) ++
ZLayer.succeed(mock[DIDRegistrarController]) ++
ZLayer.succeed(mock[PresentProofController]) ++
ZLayer.succeed(mock[VcVerificationController]) ++
ZLayer.succeed(mock[IssueController]) ++
ZLayer.succeed(mock[DIDController]) ++
ZLayer.succeed(mock[SystemController]) ++
ZLayer.succeed(mock[EntityController]) ++
ZLayer.succeed(mock[WalletManagementController]) ++
ZLayer.succeed(mock[DefaultAuthenticator]) ++
ZLayer.succeed(mock[EventController]) ++
ZLayer.succeed(mock[CredentialIssuerController]) ++
ZLayer.succeed(mock[PresentationExchangeController]) ++
ZLayer.succeed(mock[Oid4vciAuthenticatorFactory]) ++
configLayer
}

0 comments on commit 1e19b04

Please sign in to comment.