Skip to content

Commit f61fbe7

Browse files
fix #2117, fix #2118
1 parent d2baa5b commit f61fbe7

3 files changed

Lines changed: 53 additions & 4 deletions

File tree

otoroshi/app/api/api.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ case class ResourceVersion(
7979
schema.getOrElse {
8080
Try(
8181
Json.parse(
82-
org.json4s.jackson.JsonMethods.pretty(fi.oph.scalaschema.SchemaFactory.default.createSchema(clazz).toJson)
82+
org.json4s.jackson.JsonMethods.pretty(
83+
fi.oph.scalaschema.SchemaFactory.default.createSchema(clazz).toJson
84+
)
8385
)
8486
) match {
8587
case Failure(e) => {
@@ -2471,7 +2473,7 @@ class GenericApiController(ApiAction: ApiAction, cc: ControllerComponents)(impli
24712473
}
24722474

24732475
def openapi() = Action { req =>
2474-
val body = otoroshi.api.OpenApi.generate(env, req.getQueryString("version"))
2476+
val body = otoroshi.api.OpenApi.generate(env, req.getQueryString("version"), req.getQueryString("extension_group"))
24752477
Ok(body).as("application/json").withHeaders("Access-Control-Allow-Origin" -> "*")
24762478
}
24772479
}

otoroshi/app/api/openapi.scala

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -885,10 +885,10 @@ object OpenApi {
885885
finalSchemas
886886
}
887887

888-
def generate(env: Env, version: Option[String]): String = {
888+
def generate(env: Env, version: Option[String], extensionGroup: Option[String]): String = {
889889
// TODO: missing live metrics api
890890
// TODO: missing analytics api
891-
if (env.isDev) {
891+
val finalDoc = if (env.isDev) {
892892
val additionalPathsFile = env.environment.resourceAsStream("/schemas/additionalPaths.json").get
893893
val additionalPathsRaw = new String(additionalPathsFile.readAllBytes(), StandardCharsets.UTF_8)
894894
val additionalPathsJson = Json.parse(additionalPathsRaw).asObject
@@ -978,5 +978,52 @@ object OpenApi {
978978
}
979979
)
980980
}
981+
982+
extensionGroup match {
983+
case None => finalDoc
984+
case Some(group) => {
985+
cache.getOrElseUpdate(
986+
group, {
987+
988+
env.logger.info(s"Compute sub openapi.json document for group: '${group}'")
989+
990+
def findNeededComponents(js: JsValue): Set[String] = {
991+
js.stringify.split("#/components/schemas/").map(str => str.split(""""""").head).toSet
992+
}
993+
994+
def buildFilteredComponentsSchema(initialObj: JsValue, componentsSchema: JsObject): JsObject = {
995+
var previousNeededComponents: Set[String] = Set.empty
996+
var previousComponents: JsValue = Json.obj("paths" -> initialObj, "schemas" -> Json.obj())
997+
var run = true
998+
while (run) {
999+
val neededComponents = findNeededComponents(previousComponents)
1000+
if (neededComponents.size == previousNeededComponents.size) {
1001+
run = false
1002+
} else {
1003+
previousComponents = Json.obj("paths" -> initialObj, "schemas" -> JsObject(componentsSchema.value.filter {
1004+
case (key, _) if neededComponents.contains(key) => true
1005+
case _ => false
1006+
}))
1007+
previousNeededComponents = neededComponents
1008+
}
1009+
}
1010+
previousComponents.select("schemas").asObject
1011+
}
1012+
1013+
val json = Json.parse(finalDoc).asObject
1014+
val paths = json.select("paths").asObject
1015+
val tags = json.select("tags").asArray
1016+
val components = json.select("components").asObject
1017+
val componentsSchema = json.select("components").select("schemas").asObject
1018+
val filteredPaths = JsObject(paths.value.filter(_._1.startsWith(s"/apis/${group}")))
1019+
val filteredTags = JsArray(tags.value.filter(_.select("name").asString.startsWith(group)))
1020+
val filteredComponentsSchema = buildFilteredComponentsSchema(filteredPaths, componentsSchema)
1021+
val customComponents = components ++ Json.obj("schemas" -> filteredComponentsSchema)
1022+
val customDoc = json ++ Json.obj("tags" -> filteredTags, "paths" -> filteredPaths, "components" -> customComponents)
1023+
customDoc.prettify
1024+
}
1025+
)
1026+
}
1027+
}
9811028
}
9821029
}
887 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)