Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: openAPI mutability #1115 #1494

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
Loading