Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Add OpenAPI support #302

Merged
merged 8 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from 5 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
20 changes: 10 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ lazy val V = new {
val circe: String = "0.13.0"
val kindProjector: String = "0.11.0"
val paradise: String = "2.1.1"
val scala: String = "2.13.1"
val scala: String = "2.13.2"
val skeumorph: String = "0.0.22"
val specs2: String = "4.10.0"
val enumeratum: String = "1.6.1"
Expand Down Expand Up @@ -90,15 +90,19 @@ lazy val commonSettings = Seq(
crossScalaVersions := Seq(scalaVersion.value),
ThisBuild / scalacOptions -= "-Xplugin-require:macroparadise",
libraryDependencies ++= Seq(
%%("cats-core", V.cats),
%%("cats-effect", V.catsEffect),
"org.typelevel" %% "mouse" % V.mouse,
%%("shapeless", V.shapeless),
%%("pureconfig", V.pureConfig),
"com.github.pureconfig" %% "pureconfig-generic" % V.pureConfig,
"com.github.pureconfig" %% "pureconfig-cats-effect" % V.pureConfig,
"com.github.pureconfig" %% "pureconfig-enumeratum" % V.pureConfig,
"io.higherkindness" %% "skeuomorph" % V.skeumorph,
"org.tpolecat" %% "doobie-refined" % V.doobie,
"com.beachape" %% "enumeratum" % V.enumeratum,
"com.beachape" %% "enumeratum-circe" % V.enumeratumCirce,
"org.flywaydb" % "flyway-core" % V.flyway,
"org.typelevel" %% "mouse" % V.mouse,
%%("cats-core", V.cats),
%%("cats-effect", V.catsEffect),
%%("shapeless", V.shapeless),
%%("pureconfig", V.pureConfig),
%%("http4s-dsl", V.http4s),
%%("http4s-blaze-server", V.http4s),
%%("http4s-circe", V.http4s),
Expand All @@ -107,10 +111,6 @@ lazy val commonSettings = Seq(
%%("doobie-core", V.doobie),
%%("doobie-postgres", V.doobie),
%%("doobie-hikari", V.doobie),
"org.tpolecat" %% "doobie-refined" % V.doobie,
"com.beachape" %% "enumeratum" % V.enumeratum,
"com.beachape" %% "enumeratum-circe" % V.enumeratumCirce,
"org.flywaydb" % "flyway-core" % V.flyway,
%%("specs2-core", V.specs2) % Test,
%%("specs2-scalacheck", V.specs2) % Test,
%%("doobie-specs2", V.doobie) % Test,
Expand Down
12 changes: 12 additions & 0 deletions src/main/resources/db/migration/metadata/V2__update_idl_types.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ALTER TYPE idl ADD VALUE 'openapiyaml';
ALTER TYPE idl ADD VALUE 'openapijson';
fedefernandez marked this conversation as resolved.
Show resolved Hide resolved

UPDATE metaprotocols SET idl_name = 'openapiyaml' WHERE idl_name = 'openapi'
fedefernandez marked this conversation as resolved.
Show resolved Hide resolved

ALTER TYPE idl RENAME TO idl_old;

CREATE TYPE idl as ENUM('avro', 'protobuf', 'mu', 'openapiyaml', 'openapijson', 'scala');

ALTER TABLE metaprotocols ALTER COLUMN idl_name TYPE idl USING idl_name::text::idl;

DROP TYPE idl_old;
48 changes: 42 additions & 6 deletions src/main/scala/higherkindness/compendium/core/ProtocolUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import cats.implicits._
import higherkindness.compendium.models.{IdlName, Protocol}
import higherkindness.compendium.models.transformer.types.SchemaParseException
import higherkindness.droste.data.Mu
import higherkindness.skeuomorph.openapi.{JsonSchemaF, ParseOpenApi}
import higherkindness.skeuomorph.openapi.ParseOpenApi.{JsonSource, YamlSource}
import higherkindness.skeuomorph.openapi.schema.OpenApi
import higherkindness.skeuomorph.protobuf.{ProtobufF, Protocol => ProtobufProtocol}
import higherkindness.skeuomorph.protobuf.ParseProto._
import org.apache.avro.Schema
Expand All @@ -37,25 +40,42 @@ object ProtocolUtils {

private def parserAvro: Schema.Parser = new Schema.Parser()

private def parserProtobuf[F[_]: Sync](raw: String): F[ProtobufProtocol[Mu[ProtobufF]]] = {
private def parserProtobuf[F[_]: Sync](raw: String): F[ProtobufProtocol[Mu[ProtobufF]]] =
for {
tmpFile <- writeTempFile(raw)
tmpFile <- writeTempFile(raw, "protoTempFile", ".proto")
p <- parseProto[F, Mu[ProtobufF]].parse(
ProtoSource(
tmpFile.file.getName,
tmpFile.file.getAbsolutePath.replaceAll(tmpFile.file.getName, "")
)
)
} yield p
}

private def writeTempFile[F[_]: Sync](msg: String): F[FilePrintWriter] =
private def parserOpenAPIYaml[F[_]: Sync](raw: String): F[OpenApi[Mu[JsonSchemaF]]] =
for {
tmpFile <- writeTempFile(raw, "OpenAPITempFile", ".yaml")
p <- ParseOpenApi.parseYamlOpenApi[F, Mu[JsonSchemaF]].parse(YamlSource(tmpFile.file))
} yield p

private def parserOpenAPIJson[F[_]: Sync](raw: String): F[OpenApi[Mu[JsonSchemaF]]] =
for {
tmpFile <- writeTempFile(raw, "OpenAPITempFile", ".json")
p <- ParseOpenApi.parseJsonOpenApi[F, Mu[JsonSchemaF]].parse(JsonSource(tmpFile.file))
} yield p

private def writeTempFile[F[_]: Sync](
msg: String,
prefix: String,
suffix: String
): F[FilePrintWriter] =
Resource
.make(F.delay {
val file = File.createTempFile("protoTempFile", ".proto")
val file = File.createTempFile(prefix, suffix)
file.deleteOnExit()
FilePrintWriter(file, new PrintWriter(file))
}) { fpw: FilePrintWriter => F.delay(fpw.pw.close()) }
}) { fpw: FilePrintWriter =>
F.delay(fpw.pw.close())
}
.use((fpw: FilePrintWriter) => F.delay(fpw.pw.write(msg)).as(fpw))

def impl[F[_]: Sync]: ProtocolUtils[F] =
Expand All @@ -82,6 +102,22 @@ object ProtocolUtils {
SchemaParseException("Protobuf schema provided not valid. " + e.getMessage)
)
)
case IdlName.OpenAPIYaml =>
parserOpenAPIYaml(protocol.raw)
.map(_ => protocol)
.handleErrorWith(e =>
F.raiseError(
SchemaParseException("OpenAPI YAML schema provided not valid. " + e.getMessage)
)
)
case IdlName.OpenAPIJson =>
parserOpenAPIJson(protocol.raw)
.map(_ => protocol)
.handleErrorWith(e =>
F.raiseError(
SchemaParseException("OpenAPI JSON schema provided not valid. " + e.getMessage)
)
)
case _ => F.raiseError(SchemaParseException(s"$schema type not implemented yet"))
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/main/scala/higherkindness/compendium/models/IdlName.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ sealed trait IdlName extends EnumEntry
object IdlName extends Enum[IdlName] with CirceEnum[IdlName] {
val values = findValues

case object Avro extends IdlName with Lowercase
case object Protobuf extends IdlName with Lowercase
case object Mu extends IdlName with Lowercase
case object OpenApi extends IdlName with Lowercase
case object Scala extends IdlName with Lowercase
case object Avro extends IdlName with Lowercase
case object Protobuf extends IdlName with Lowercase
case object Mu extends IdlName with Lowercase
case object OpenAPIYaml extends IdlName with Lowercase
case object OpenAPIJson extends IdlName with Lowercase
case object Scala extends IdlName with Lowercase
}
Loading