forked from loafle/openapi-generator-original
improved validation messages
This commit is contained in:
parent
ed51dd9dea
commit
11bede2b7d
@ -24,6 +24,7 @@ import com.wordnik.swagger.codegen.model._
|
|||||||
import com.wordnik.swagger.codegen.model.SwaggerSerializers
|
import com.wordnik.swagger.codegen.model.SwaggerSerializers
|
||||||
import com.wordnik.swagger.codegen.spec.ValidationMessage
|
import com.wordnik.swagger.codegen.spec.ValidationMessage
|
||||||
import com.wordnik.swagger.codegen.spec.SwaggerSpec._
|
import com.wordnik.swagger.codegen.spec.SwaggerSpec._
|
||||||
|
import com.wordnik.swagger.util.ValidationException
|
||||||
|
|
||||||
import java.io.{ File, FileWriter }
|
import java.io.{ File, FileWriter }
|
||||||
|
|
||||||
@ -81,29 +82,29 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
|
|||||||
val authorization = opts.auth
|
val authorization = opts.auth
|
||||||
|
|
||||||
fileMap = Option(opts.properties.getOrElse("fileMap", null))
|
fileMap = Option(opts.properties.getOrElse("fileMap", null))
|
||||||
val doc = {
|
val doc = ResourceExtractor.fetchListing(getResourcePath(host, fileMap), authorization)
|
||||||
try {
|
|
||||||
ResourceExtractor.fetchListing(getResourcePath(host, fileMap), authorization)
|
|
||||||
} catch {
|
|
||||||
case e: Exception => throw new Exception("unable to read from " + host, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
additionalParams ++= opts.properties
|
additionalParams ++= opts.properties
|
||||||
val apis: List[ApiListing] = getApis(host, doc, authorization)
|
val apis: List[ApiListing] = getApis(host, doc, authorization)
|
||||||
|
|
||||||
SwaggerSerializers.validationMessages.filter(_.level == ValidationMessage.ERROR).size match {
|
val errors = new ListBuffer[ValidationError] ++ SwaggerValidator.validate(doc)
|
||||||
|
for(api <- apis) {
|
||||||
|
SwaggerValidator.validate(api, errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
errors.filter(_.severity == SwaggerValidator.ERROR).size match {
|
||||||
case i: Int if i > 0 => {
|
case i: Int if i > 0 => {
|
||||||
println("********* Failed to read swagger json!")
|
println("********* Failed to read swagger json!")
|
||||||
SwaggerSerializers.validationMessages.foreach(msg => {
|
errors.foreach(msg => {
|
||||||
println(msg)
|
println(msg)
|
||||||
})
|
})
|
||||||
Option(System.getProperty("skipErrors")) match {
|
Option(System.getProperty("skipErrors")) match {
|
||||||
case Some(str) => println("**** ignoring errors and continuing")
|
case Some(str) => println("**** ignoring errors and continuing")
|
||||||
case None => {
|
case None => {
|
||||||
val out = new StringBuilder
|
val out = new StringBuilder
|
||||||
SwaggerSerializers.validationMessages.foreach(m => out.append(m).append("\n"))
|
errors.foreach(m => out.append(m).append("\n"))
|
||||||
throw new RuntimeException(out.toString)
|
println(errors)
|
||||||
|
throw new ValidationException(400, "Failed validation", errors.toList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,33 +26,14 @@ object LegacySerializers {
|
|||||||
new ResourceListingSerializer +
|
new ResourceListingSerializer +
|
||||||
new ApiListingSerializer
|
new ApiListingSerializer
|
||||||
|
|
||||||
def validationMessages = ValidationMessage.validationMessages
|
|
||||||
|
|
||||||
def !!(element: AnyRef, elementType: String, elementId: String, message: String, level: String = ERROR) {
|
|
||||||
val msg = new ValidationMessage(element, elementType, elementId, message, level)
|
|
||||||
ValidationMessage.validationMessages += msg
|
|
||||||
}
|
|
||||||
|
|
||||||
class ApiListingSerializer extends CustomSerializer[ApiListing](formats => ({
|
class ApiListingSerializer extends CustomSerializer[ApiListing](formats => ({
|
||||||
case json =>
|
case json =>
|
||||||
implicit val fmts: Formats = formats
|
implicit val fmts: Formats = formats
|
||||||
ApiListing(
|
ApiListing(
|
||||||
(json \ "apiVersion").extractOrElse({
|
(json \ "apiVersion").extractOrElse(""),
|
||||||
!!(json, RESOURCE, "apiVersion", "missing required field", ERROR)
|
(json \ "swaggerVersion").extractOrElse(""),
|
||||||
""
|
(json \ "basePath").extractOrElse(""),
|
||||||
}),
|
(json \ "resourcePath").extractOrElse(""),
|
||||||
(json \ "swaggerVersion").extractOrElse({
|
|
||||||
!!(json, RESOURCE, "swaggerVersion", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "basePath").extractOrElse({
|
|
||||||
!!(json, RESOURCE, "basePath", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "resourcePath").extractOrElse({
|
|
||||||
!!(json, RESOURCE, "resourcePath", "missing recommended field", WARNING)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
List.empty,
|
List.empty,
|
||||||
List.empty,
|
List.empty,
|
||||||
List.empty,
|
List.empty,
|
||||||
@ -87,18 +68,9 @@ object LegacySerializers {
|
|||||||
case json =>
|
case json =>
|
||||||
implicit val fmts: Formats = formats
|
implicit val fmts: Formats = formats
|
||||||
ResourceListing(
|
ResourceListing(
|
||||||
(json \ "apiVersion").extractOrElse({
|
(json \ "apiVersion").extractOrElse(""),
|
||||||
!!(json, RESOURCE_LISTING, "apiVersion", "missing required field", ERROR)
|
(json \ "swaggerVersion").extractOrElse(""),
|
||||||
""
|
(json \ "basePath").extractOrElse(""),
|
||||||
}),
|
|
||||||
(json \ "swaggerVersion").extractOrElse({
|
|
||||||
!!(json, RESOURCE_LISTING, "swaggerVersion", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "basePath").extractOrElse({
|
|
||||||
!!(json, RESOURCE_LISTING, "basePath", "missing deprecated field", WARNING)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "apis").extract[List[ApiListingReference]]
|
(json \ "apis").extract[List[ApiListingReference]]
|
||||||
)
|
)
|
||||||
}, {
|
}, {
|
||||||
@ -120,10 +92,7 @@ object LegacySerializers {
|
|||||||
case json =>
|
case json =>
|
||||||
implicit val fmts: Formats = formats
|
implicit val fmts: Formats = formats
|
||||||
ApiListingReference(
|
ApiListingReference(
|
||||||
(json \ "path").extractOrElse({
|
(json \ "path").extractOrElse(""),
|
||||||
!!(json, RESOURCE, "path", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "description").extractOpt[String]
|
(json \ "description").extractOpt[String]
|
||||||
)
|
)
|
||||||
}, {
|
}, {
|
||||||
@ -138,10 +107,7 @@ object LegacySerializers {
|
|||||||
case json =>
|
case json =>
|
||||||
implicit val fmts: Formats = formats
|
implicit val fmts: Formats = formats
|
||||||
ApiDescription(
|
ApiDescription(
|
||||||
(json \ "path").extractOrElse({
|
(json \ "path").extractOrElse(""),
|
||||||
!!(json, RESOURCE_LISTING, "path", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "description").extractOpt[String],
|
(json \ "description").extractOpt[String],
|
||||||
(json \ "operations").extract[List[Operation]]
|
(json \ "operations").extract[List[Operation]]
|
||||||
)
|
)
|
||||||
@ -163,14 +129,8 @@ object LegacySerializers {
|
|||||||
case json =>
|
case json =>
|
||||||
implicit val fmts: Formats = formats
|
implicit val fmts: Formats = formats
|
||||||
ResponseMessage(
|
ResponseMessage(
|
||||||
(json \ "code").extractOrElse({
|
(json \ "code").extractOrElse(0),
|
||||||
!!(json, ERROR, "code", "missing required field", ERROR)
|
(json \ "reason").extractOrElse("")
|
||||||
0
|
|
||||||
}),
|
|
||||||
(json \ "reason").extractOrElse({
|
|
||||||
!!(json, ERROR, "reason", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
}, {
|
}, {
|
||||||
case x: ResponseMessage =>
|
case x: ResponseMessage =>
|
||||||
@ -189,21 +149,12 @@ object LegacySerializers {
|
|||||||
}
|
}
|
||||||
Operation(
|
Operation(
|
||||||
(json \ "httpMethod").extractOrElse(
|
(json \ "httpMethod").extractOrElse(
|
||||||
(json \ "method").extractOrElse({
|
(json \ "method").extractOrElse("")
|
||||||
!!(json, OPERATION, "method", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
),
|
),
|
||||||
(json \ "summary").extract[String],
|
(json \ "summary").extract[String],
|
||||||
(json \ "notes").extractOrElse(""),
|
(json \ "notes").extractOrElse(""),
|
||||||
(json \ "responseClass").extractOrElse({
|
(json \ "responseClass").extractOrElse(""),
|
||||||
!!(json, OPERATION, "responseClass", "missing required field", ERROR)
|
(json \ "nickname").extractOrElse(""),
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "nickname").extractOrElse({
|
|
||||||
!!(json, OPERATION, "nickname", "missing required field", WARNING)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "position").extractOrElse(0),
|
(json \ "position").extractOrElse(0),
|
||||||
(json \ "produces").extract[List[String]],
|
(json \ "produces").extract[List[String]],
|
||||||
(json \ "consumes").extract[List[String]],
|
(json \ "consumes").extract[List[String]],
|
||||||
@ -236,10 +187,7 @@ object LegacySerializers {
|
|||||||
case json =>
|
case json =>
|
||||||
implicit val fmts: Formats = formats
|
implicit val fmts: Formats = formats
|
||||||
Parameter(
|
Parameter(
|
||||||
(json \ "name").extractOrElse({
|
(json \ "name").extractOrElse(""),
|
||||||
!!(json, OPERATION_PARAM, "reason", "missing parameter name", WARNING)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "description").extractOpt[String],
|
(json \ "description").extractOpt[String],
|
||||||
(json \ "defaultValue") match {
|
(json \ "defaultValue") match {
|
||||||
case e:JInt => Some(e.num.toString)
|
case e:JInt => Some(e.num.toString)
|
||||||
@ -254,15 +202,9 @@ object LegacySerializers {
|
|||||||
case _ => false
|
case _ => false
|
||||||
},
|
},
|
||||||
(json \ "allowMultiple").extractOrElse(false),
|
(json \ "allowMultiple").extractOrElse(false),
|
||||||
(json \ "dataType").extractOrElse({
|
(json \ "dataType").extractOrElse(""),
|
||||||
!!(json, OPERATION_PARAM, "dataType", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "allowableValues").extract[AllowableValues],
|
(json \ "allowableValues").extract[AllowableValues],
|
||||||
(json \ "paramType").extractOrElse({
|
(json \ "paramType").extractOrElse("")
|
||||||
!!(json, OPERATION_PARAM, "paramType", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
}, {
|
}, {
|
||||||
case x: Parameter =>
|
case x: Parameter =>
|
||||||
@ -298,10 +240,7 @@ object LegacySerializers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Model(
|
Model(
|
||||||
(json \ "id").extractOrElse({
|
(json \ "id").extractOrElse(""),
|
||||||
!!(json, MODEL, "id", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "name").extractOrElse(""),
|
(json \ "name").extractOrElse(""),
|
||||||
(json \ "id").extractOrElse(""),
|
(json \ "id").extractOrElse(""),
|
||||||
output,
|
output,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.wordnik.swagger.codegen.model
|
package com.wordnik.swagger.codegen.model
|
||||||
|
|
||||||
import com.wordnik.swagger.codegen.spec.ValidationMessage
|
import com.wordnik.swagger.codegen.spec.ValidationMessage
|
||||||
|
import com.wordnik.swagger.util.ValidationException
|
||||||
|
|
||||||
import legacy.LegacySerializers
|
import legacy.LegacySerializers
|
||||||
|
|
||||||
import org.json4s._
|
import org.json4s._
|
||||||
@ -10,6 +12,8 @@ import org.json4s.jackson.Serialization.{read, write}
|
|||||||
|
|
||||||
import scala.collection.mutable.{ListBuffer, LinkedHashMap}
|
import scala.collection.mutable.{ListBuffer, LinkedHashMap}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
object SwaggerSerializers {
|
object SwaggerSerializers {
|
||||||
import ValidationMessage._
|
import ValidationMessage._
|
||||||
|
|
||||||
@ -87,17 +91,13 @@ object SwaggerSerializers {
|
|||||||
new ResourceListingSerializer +
|
new ResourceListingSerializer +
|
||||||
new ApiListingSerializer
|
new ApiListingSerializer
|
||||||
}
|
}
|
||||||
case _ => throw new IllegalArgumentException("%s is not a valid Swagger version~~".format(version))
|
case _ => {
|
||||||
|
val error = ValidationError("ResourceListing", "swaggerVersion", SwaggerValidator.ERROR)
|
||||||
|
throw new ValidationException(400, "'%s' is not a valid Swagger version".format(version), List(error))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def validationMessages = ValidationMessage.validationMessages
|
|
||||||
|
|
||||||
def !!(element: AnyRef, elementType: String, elementId: String, message: String, level: String = ERROR) {
|
|
||||||
val msg = new ValidationMessage(element, elementType, elementId, message, level)
|
|
||||||
ValidationMessage.validationMessages += msg
|
|
||||||
}
|
|
||||||
|
|
||||||
class ApiListingSerializer extends CustomSerializer[ApiListing](implicit formats => ({
|
class ApiListingSerializer extends CustomSerializer[ApiListing](implicit formats => ({
|
||||||
case json =>
|
case json =>
|
||||||
val authorizations = (json \ "authorizations").extractOpt[Map[String, AuthorizationType]] match {
|
val authorizations = (json \ "authorizations").extractOpt[Map[String, AuthorizationType]] match {
|
||||||
@ -110,26 +110,14 @@ object SwaggerSerializers {
|
|||||||
case e: JBool => e.value.toString
|
case e: JBool => e.value.toString
|
||||||
case e: JString => e.s
|
case e: JString => e.s
|
||||||
case e: JDouble => e.num.toString
|
case e: JDouble => e.num.toString
|
||||||
case _ => {
|
case _ => ""
|
||||||
!!(json, RESOURCE_LISTING, "swaggerVersion", "missing required field!!!", ERROR)
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiListing(
|
ApiListing(
|
||||||
(json \ "apiVersion").extractOrElse({
|
(json \ "apiVersion").extractOrElse(""),
|
||||||
!!(json, RESOURCE, "apiVersion", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
swaggerVersion,
|
swaggerVersion,
|
||||||
(json \ "basePath").extractOrElse({
|
(json \ "basePath").extractOrElse(""),
|
||||||
!!(json, RESOURCE, "basePath", "missing required field", ERROR)
|
(json \ "resourcePath").extractOrElse(""),
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "resourcePath").extractOrElse({
|
|
||||||
!!(json, RESOURCE, "resourcePath", "missing recommended field", WARNING)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "produces").extract[List[String]],
|
(json \ "produces").extract[List[String]],
|
||||||
(json \ "consumes").extract[List[String]],
|
(json \ "consumes").extract[List[String]],
|
||||||
(json \ "protocols").extract[List[String]],
|
(json \ "protocols").extract[List[String]],
|
||||||
@ -170,17 +158,11 @@ object SwaggerSerializers {
|
|||||||
case e: JBool => e.value.toString
|
case e: JBool => e.value.toString
|
||||||
case e: JString => e.s
|
case e: JString => e.s
|
||||||
case e: JDouble => e.num.toString
|
case e: JDouble => e.num.toString
|
||||||
case _ => {
|
case _ => ""
|
||||||
!!(json, RESOURCE_LISTING, "swaggerVersion", "missing required field!!!", ERROR)
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceListing(
|
ResourceListing(
|
||||||
(json \ "apiVersion").extractOrElse({
|
(json \ "apiVersion").extractOrElse(""),
|
||||||
!!(json, RESOURCE_LISTING, "apiVersion", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
swaggerVersion,
|
swaggerVersion,
|
||||||
"",
|
"",
|
||||||
apis.filter(a => a.path != "" && a.path != null)
|
apis.filter(a => a.path != "" && a.path != null)
|
||||||
@ -201,10 +183,7 @@ object SwaggerSerializers {
|
|||||||
class ApiListingReferenceSerializer extends CustomSerializer[ApiListingReference](implicit formats => ({
|
class ApiListingReferenceSerializer extends CustomSerializer[ApiListingReference](implicit formats => ({
|
||||||
case json =>
|
case json =>
|
||||||
val path = (json \ "path").extractOrElse({
|
val path = (json \ "path").extractOrElse({
|
||||||
(json \ "resourcePath").extractOrElse({
|
(json \ "resourcePath").extractOrElse("")
|
||||||
!!(json, RESOURCE, "path", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ApiListingReference(
|
ApiListingReference(
|
||||||
@ -222,10 +201,7 @@ object SwaggerSerializers {
|
|||||||
case json =>
|
case json =>
|
||||||
|
|
||||||
ApiDescription(
|
ApiDescription(
|
||||||
(json \ "path").extractOrElse({
|
(json \ "path").extractOrElse(""),
|
||||||
!!(json, RESOURCE_LISTING, "path", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "description").extractOpt[String],
|
(json \ "description").extractOpt[String],
|
||||||
(json \ "operations").extract[List[Operation]]
|
(json \ "operations").extract[List[Operation]]
|
||||||
)
|
)
|
||||||
@ -245,14 +221,8 @@ object SwaggerSerializers {
|
|||||||
class ResponseMessageSerializer extends CustomSerializer[ResponseMessage](implicit formats => ({
|
class ResponseMessageSerializer extends CustomSerializer[ResponseMessage](implicit formats => ({
|
||||||
case json =>
|
case json =>
|
||||||
ResponseMessage(
|
ResponseMessage(
|
||||||
(json \ "code").extractOrElse({
|
(json \ "code").extractOrElse(0),
|
||||||
!!(json, ERROR, "code", "missing required field", ERROR)
|
(json \ "message").extractOrElse("")
|
||||||
0
|
|
||||||
}),
|
|
||||||
(json \ "message").extractOrElse({
|
|
||||||
!!(json, ERROR, "reason", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
}, {
|
}, {
|
||||||
case x: ResponseMessage =>
|
case x: ResponseMessage =>
|
||||||
@ -299,24 +269,14 @@ object SwaggerSerializers {
|
|||||||
case _ => t
|
case _ => t
|
||||||
}
|
}
|
||||||
|
|
||||||
if(responseClass == "" || responseClass == null){
|
|
||||||
!!(json, OPERATION, "responseClass", "missing required field", ERROR)
|
|
||||||
}
|
|
||||||
|
|
||||||
Operation(
|
Operation(
|
||||||
(json \ "httpMethod").extractOrElse(
|
(json \ "httpMethod").extractOrElse(
|
||||||
(json \ "method").extractOrElse({
|
(json \ "method").extractOrElse("")
|
||||||
!!(json, OPERATION, "method", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
),
|
),
|
||||||
(json \ "summary").extract[String],
|
(json \ "summary").extract[String],
|
||||||
(json \ "notes").extractOrElse(""),
|
(json \ "notes").extractOrElse(""),
|
||||||
responseClass,
|
responseClass,
|
||||||
(json \ "nickname").extractOrElse({
|
(json \ "nickname").extractOrElse(""),
|
||||||
!!(json, OPERATION, "nickname", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "position").extractOrElse(0),
|
(json \ "position").extractOrElse(0),
|
||||||
(json \ "produces").extract[List[String]],
|
(json \ "produces").extract[List[String]],
|
||||||
(json \ "consumes").extract[List[String]],
|
(json \ "consumes").extract[List[String]],
|
||||||
@ -427,10 +387,7 @@ object SwaggerSerializers {
|
|||||||
case _ => t
|
case _ => t
|
||||||
}
|
}
|
||||||
Parameter(
|
Parameter(
|
||||||
name = (json \ "name").extractOrElse({
|
name = (json \ "name").extractOrElse(""),
|
||||||
!!(json, OPERATION_PARAM, "reason", "missing parameter name", WARNING)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
description = (json \ "description").extractOpt[String],
|
description = (json \ "description").extractOpt[String],
|
||||||
defaultValue = (json \ "defaultValue") match {
|
defaultValue = (json \ "defaultValue") match {
|
||||||
case e:JInt => Some(e.num.toString)
|
case e:JInt => Some(e.num.toString)
|
||||||
@ -447,10 +404,7 @@ object SwaggerSerializers {
|
|||||||
allowMultiple = (json \ "allowMultiple").extractOrElse(false),
|
allowMultiple = (json \ "allowMultiple").extractOrElse(false),
|
||||||
dataType = `type`,
|
dataType = `type`,
|
||||||
allowableValues = allowableValues,
|
allowableValues = allowableValues,
|
||||||
paramType = (json \ "paramType").extractOrElse({
|
paramType = (json \ "paramType").extractOrElse("")
|
||||||
!!(json, OPERATION_PARAM, "paramType", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
}, {
|
}, {
|
||||||
case x: Parameter =>
|
case x: Parameter =>
|
||||||
@ -493,10 +447,7 @@ object SwaggerSerializers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Model(
|
Model(
|
||||||
(json \ "id").extractOrElse({
|
(json \ "id").extractOrElse(""),
|
||||||
!!(json, MODEL, "id", "missing required field", ERROR)
|
|
||||||
""
|
|
||||||
}),
|
|
||||||
(json \ "name").extractOrElse(""),
|
(json \ "name").extractOrElse(""),
|
||||||
(json \ "qualifiedType").extractOrElse((json \ "id").extractOrElse("")),
|
(json \ "qualifiedType").extractOrElse((json \ "id").extractOrElse("")),
|
||||||
output,
|
output,
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.wordnik.swagger.codegen.model
|
||||||
|
|
||||||
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
|
case class ValidationError (
|
||||||
|
path: String,
|
||||||
|
message: String,
|
||||||
|
severity: String
|
||||||
|
)
|
||||||
|
|
||||||
|
object SwaggerValidator {
|
||||||
|
val ERROR = "ERROR"
|
||||||
|
val WARNING = "WARNING"
|
||||||
|
|
||||||
|
def validate (resource: ResourceListing): List[ValidationError] = {
|
||||||
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
|
||||||
|
if(resource.apiVersion == "")
|
||||||
|
errors += ValidationError("resourceListing", "apiVersion", ERROR)
|
||||||
|
if(resource.swaggerVersion == "")
|
||||||
|
errors += ValidationError("resourceListing", "apiVersion", ERROR)
|
||||||
|
for(api <- resource.apis)
|
||||||
|
validate(api, errors, "resourceListing")
|
||||||
|
errors.toList
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(ref: ApiListingReference, errors: ListBuffer[ValidationError], parent: String): Unit = {
|
||||||
|
if(ref.path == "")
|
||||||
|
errors += ValidationError(parent + ":api", "path", ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(api: ApiListing, errors: ListBuffer[ValidationError]): Unit = {
|
||||||
|
if(api.swaggerVersion == "")
|
||||||
|
errors += ValidationError("apiDeclaration", "swaggerVersion", ERROR)
|
||||||
|
if(api.apiVersion == "")
|
||||||
|
errors += ValidationError("apiDeclaration", "apiVersion", ERROR)
|
||||||
|
if(api.basePath == "")
|
||||||
|
errors += ValidationError("apiDeclaration", "basePath", ERROR)
|
||||||
|
if(api.resourcePath == "")
|
||||||
|
errors += ValidationError("apiDeclaration", "resourcePath", ERROR)
|
||||||
|
|
||||||
|
for(a <- api.apis) {
|
||||||
|
validate(a, errors, api.resourcePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
api.models match {
|
||||||
|
case Some(m) => for((name, model) <- m) {
|
||||||
|
validate(model, errors, api.resourcePath)
|
||||||
|
}
|
||||||
|
case None =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(model: Model, errors: ListBuffer[ValidationError], parent: String): Unit = {
|
||||||
|
if(model.id == "")
|
||||||
|
errors += ValidationError(parent + ":model", "id", ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(desc: ApiDescription, errors: ListBuffer[ValidationError], parent: String): Unit = {
|
||||||
|
if(desc.path == "")
|
||||||
|
errors += ValidationError(parent + ":api", "path", ERROR)
|
||||||
|
for(op <- desc.operations)
|
||||||
|
validate(op, errors, parent + ":" + desc.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(op: Operation, errors: ListBuffer[ValidationError], parent: String): Unit = {
|
||||||
|
if(op.method == "")
|
||||||
|
errors += ValidationError(parent + ":operation", "method", ERROR)
|
||||||
|
if(op.nickname == "")
|
||||||
|
errors += ValidationError(parent + ":" + op.method, "nickname", WARNING)
|
||||||
|
if(op.responseClass == "")
|
||||||
|
errors += ValidationError(parent + ":" + op.method, "responseClass", ERROR)
|
||||||
|
for(resp <- op.responseMessages)
|
||||||
|
validate(resp, errors, parent)
|
||||||
|
for(param <- op.parameters)
|
||||||
|
validate(param, errors, parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(param: Parameter, errors: ListBuffer[ValidationError], parent: String): Unit = {
|
||||||
|
if(param.name == "")
|
||||||
|
errors += ValidationError("Parameter", "name", ERROR)
|
||||||
|
if(param.paramType == "")
|
||||||
|
errors += ValidationError("Parameter", "paramType", ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(resp: ResponseMessage, errors: ListBuffer[ValidationError], parent: String): Unit = {
|
||||||
|
if(resp.code == 0)
|
||||||
|
errors += ValidationError("ResponseMessage", "code", ERROR)
|
||||||
|
if(resp.message == 0)
|
||||||
|
errors += ValidationError("ResponseMessage", "message", ERROR)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.wordnik.swagger.util
|
||||||
|
|
||||||
|
import com.wordnik.swagger.codegen.model._
|
||||||
|
|
||||||
|
import scala.collection.JavaConverters._
|
||||||
|
import scala.reflect.BeanProperty
|
||||||
|
|
||||||
|
class ValidationException(code:Int, msg:String, errors: List[ValidationError]) extends Exception(msg:String) {
|
||||||
|
val messages: java.util.List[ValidationMessage] = (
|
||||||
|
for(e <- errors) yield ({
|
||||||
|
val m = new ValidationMessage()
|
||||||
|
m.path = e.path
|
||||||
|
m.message = e.message
|
||||||
|
m.severity = e.severity
|
||||||
|
m
|
||||||
|
})
|
||||||
|
).toList.asJava
|
||||||
|
}
|
||||||
|
|
||||||
|
class ValidationMessage() {
|
||||||
|
@BeanProperty var path: String = _
|
||||||
|
@BeanProperty var message: String = _
|
||||||
|
@BeanProperty var severity: String = _
|
||||||
|
}
|
@ -12,38 +12,37 @@ import org.scalatest.junit.JUnitRunner
|
|||||||
import org.scalatest.FlatSpec
|
import org.scalatest.FlatSpec
|
||||||
import org.scalatest.matchers.ShouldMatchers
|
import org.scalatest.matchers.ShouldMatchers
|
||||||
|
|
||||||
import scala.collection.mutable.LinkedHashMap
|
import scala.collection.mutable.{ LinkedHashMap, ListBuffer }
|
||||||
|
|
||||||
@RunWith(classOf[JUnitRunner])
|
@RunWith(classOf[JUnitRunner])
|
||||||
class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
||||||
implicit val formats = SwaggerSerializers.formats("1.1")
|
implicit val formats = SwaggerSerializers.formats("1.1")
|
||||||
|
|
||||||
it should "fail resource listing without base path" in {
|
it should "fail resource listing without base path" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"apiVersion":"1.2.3",
|
"apiVersion":"1.2.3",
|
||||||
"swaggerVersion":"1.1"
|
"swaggerVersion":"1.1"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
parse(jsonString).extract[ResourceListing]
|
val listing = parse(jsonString).extract[ResourceListing]
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
val errors = SwaggerValidator.validate(listing)
|
||||||
|
// errors.size should be (1)
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "fail resource listing without apiVersion" in {
|
it should "fail resource listing without apiVersion" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"basePath": "http://foo.com",
|
"basePath": "http://foo.com",
|
||||||
"swaggerVersion":"1.1"
|
"swaggerVersion":"1.1"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
parse(jsonString).extract[ResourceListing]
|
val listing = parse(jsonString).extract[ResourceListing]
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
val errors = SwaggerValidator.validate(listing)
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "fail with missing paths in a ResourceListing" in {
|
it should "fail with missing paths in a ResourceListing" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"apiVersion":"1.2.3",
|
"apiVersion":"1.2.3",
|
||||||
@ -62,10 +61,11 @@ class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
parse(jsonString).extract[ResourceListing] match {
|
parse(jsonString).extract[ResourceListing] match {
|
||||||
case e: ResourceListing => {
|
case e: ResourceListing => {
|
||||||
e.apis.size should be (2)
|
e.apis.size should be (2)
|
||||||
|
val errors = SwaggerValidator.validate(e)
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
case _ => fail("didn't parse the underlying apis")
|
case _ => fail("didn't parse the underlying apis")
|
||||||
}
|
}
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,9 +73,7 @@ class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
class ApiListingReferenceValidationTest extends FlatSpec with ShouldMatchers {
|
class ApiListingReferenceValidationTest extends FlatSpec with ShouldMatchers {
|
||||||
implicit val formats = SwaggerSerializers.formats("1.1")
|
implicit val formats = SwaggerSerializers.formats("1.1")
|
||||||
|
|
||||||
|
|
||||||
it should "deserialize an ApiListingReference" in {
|
it should "deserialize an ApiListingReference" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"description":"the description"
|
"description":"the description"
|
||||||
@ -84,10 +82,12 @@ class ApiListingReferenceValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
parse(jsonString).extract[ApiListingReference] match {
|
parse(jsonString).extract[ApiListingReference] match {
|
||||||
case p: ApiListingReference => {
|
case p: ApiListingReference => {
|
||||||
p.description should be (Some("the description"))
|
p.description should be (Some("the description"))
|
||||||
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
SwaggerValidator.validate(p, errors, "")
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
case _ => fail("wrong type returned, should be ApiListingReference")
|
case _ => fail("wrong type returned, should be ApiListingReference")
|
||||||
}
|
}
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "serialize an ApiListingReference" in {
|
it should "serialize an ApiListingReference" in {
|
||||||
@ -101,7 +101,6 @@ class ApiDescriptionValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
implicit val formats = SwaggerSerializers.formats("1.1")
|
implicit val formats = SwaggerSerializers.formats("1.1")
|
||||||
|
|
||||||
it should "fail to deserialize an ApiDescription with path, method, return type" in {
|
it should "fail to deserialize an ApiDescription with path, method, return type" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"description":"the description",
|
"description":"the description",
|
||||||
@ -131,7 +130,9 @@ class ApiDescriptionValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
"""
|
"""
|
||||||
parse(jsonString).extract[ApiDescription] match {
|
parse(jsonString).extract[ApiDescription] match {
|
||||||
case p: ApiDescription => {
|
case p: ApiDescription => {
|
||||||
SwaggerSerializers.validationMessages.size should be (3)
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
SwaggerValidator.validate(p, errors, "")
|
||||||
|
errors.size should be (3)
|
||||||
}
|
}
|
||||||
case _ => fail("wrong type returned, should be ApiDescription")
|
case _ => fail("wrong type returned, should be ApiDescription")
|
||||||
}
|
}
|
||||||
@ -143,7 +144,6 @@ class OperationValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
implicit val formats = SwaggerSerializers.formats("1.1")
|
implicit val formats = SwaggerSerializers.formats("1.1")
|
||||||
|
|
||||||
it should "fail to deserialize an Operation with missing param type" in {
|
it should "fail to deserialize an Operation with missing param type" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"httpMethod":"GET",
|
"httpMethod":"GET",
|
||||||
@ -170,7 +170,9 @@ class OperationValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
val json = parse(jsonString)
|
val json = parse(jsonString)
|
||||||
json.extract[Operation] match {
|
json.extract[Operation] match {
|
||||||
case op: Operation => {
|
case op: Operation => {
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
SwaggerValidator.validate(op, errors, "")
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
case _ => fail("wrong type returned, should be Operation")
|
case _ => fail("wrong type returned, should be Operation")
|
||||||
}
|
}
|
||||||
|
@ -12,38 +12,39 @@ import org.scalatest.junit.JUnitRunner
|
|||||||
import org.scalatest.FlatSpec
|
import org.scalatest.FlatSpec
|
||||||
import org.scalatest.matchers.ShouldMatchers
|
import org.scalatest.matchers.ShouldMatchers
|
||||||
|
|
||||||
import scala.collection.mutable.LinkedHashMap
|
import scala.collection.mutable.{ LinkedHashMap, ListBuffer }
|
||||||
|
|
||||||
@RunWith(classOf[JUnitRunner])
|
@RunWith(classOf[JUnitRunner])
|
||||||
class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
||||||
implicit val formats = SwaggerSerializers.formats("1.2")
|
implicit val formats = SwaggerSerializers.formats("1.2")
|
||||||
|
|
||||||
it should "not have base path" in {
|
it should "not have base path" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
// SwaggerSerializers.validationMessages.clear
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"apiVersion":"1.2.3",
|
"apiVersion":"1.2.3",
|
||||||
"swaggerVersion":"1.1"
|
"swaggerVersion":"1.1"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
parse(jsonString).extract[ResourceListing]
|
val listing = parse(jsonString).extract[ResourceListing]
|
||||||
SwaggerSerializers.validationMessages.size should be (0)
|
val errors = SwaggerValidator.validate(listing)
|
||||||
|
errors.size should be (0)
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "fail resource listing without apiVersion" in {
|
it should "fail resource listing without apiVersion" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
// SwaggerSerializers.validationMessages.clear
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"basePath": "http://foo.com",
|
"basePath": "http://foo.com",
|
||||||
"swaggerVersion":"1.2"
|
"swaggerVersion":"1.2"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
parse(jsonString).extract[ResourceListing]
|
val listing = parse(jsonString).extract[ResourceListing]
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
val errors = SwaggerValidator.validate(listing)
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "fail with missing paths in a ResourceListing" in {
|
it should "fail with missing paths in a ResourceListing" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"apiVersion":"1.2.3",
|
"apiVersion":"1.2.3",
|
||||||
@ -51,7 +52,8 @@ class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
"apis":[
|
"apis":[
|
||||||
{
|
{
|
||||||
"description":"path ab apis"
|
"description":"path ab apis"
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
"path":"/c",
|
"path":"/c",
|
||||||
"description":"path c apis"
|
"description":"path c apis"
|
||||||
}
|
}
|
||||||
@ -61,10 +63,11 @@ class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
parse(jsonString).extract[ResourceListing] match {
|
parse(jsonString).extract[ResourceListing] match {
|
||||||
case e: ResourceListing => {
|
case e: ResourceListing => {
|
||||||
e.apis.size should be (1)
|
e.apis.size should be (1)
|
||||||
|
val errors = SwaggerValidator.validate(e)
|
||||||
|
errors.size should be (0)
|
||||||
}
|
}
|
||||||
case _ => fail("didn't parse the underlying apis")
|
case _ => fail("didn't parse the underlying apis")
|
||||||
}
|
}
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ class ApiListingReferenceValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
implicit val formats = SwaggerSerializers.formats("1.2")
|
implicit val formats = SwaggerSerializers.formats("1.2")
|
||||||
|
|
||||||
it should "deserialize an ApiListingReference" in {
|
it should "deserialize an ApiListingReference" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
// SwaggerSerializers.validationMessages.clear
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"description":"the description"
|
"description":"the description"
|
||||||
@ -82,10 +85,12 @@ class ApiListingReferenceValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
parse(jsonString).extract[ApiListingReference] match {
|
parse(jsonString).extract[ApiListingReference] match {
|
||||||
case p: ApiListingReference => {
|
case p: ApiListingReference => {
|
||||||
p.description should be (Some("the description"))
|
p.description should be (Some("the description"))
|
||||||
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
SwaggerValidator.validate(p, errors, "")
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
case _ => fail("wrong type returned, should be ApiListingReference")
|
case _ => fail("wrong type returned, should be ApiListingReference")
|
||||||
}
|
}
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "serialize an ApiListingReference" in {
|
it should "serialize an ApiListingReference" in {
|
||||||
@ -99,7 +104,7 @@ class ApiDescriptionValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
implicit val formats = SwaggerSerializers.formats("1.2")
|
implicit val formats = SwaggerSerializers.formats("1.2")
|
||||||
|
|
||||||
it should "fail to deserialize an ApiDescription with path, method, return type" in {
|
it should "fail to deserialize an ApiDescription with path, method, return type" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
// SwaggerSerializers.validationMessages.clear
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"description":"the description",
|
"description":"the description",
|
||||||
@ -126,7 +131,9 @@ class ApiDescriptionValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
"""
|
"""
|
||||||
parse(jsonString).extract[ApiDescription] match {
|
parse(jsonString).extract[ApiDescription] match {
|
||||||
case p: ApiDescription => {
|
case p: ApiDescription => {
|
||||||
SwaggerSerializers.validationMessages.size should be (3)
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
SwaggerValidator.validate(p, errors, "")
|
||||||
|
errors.size should be (3)
|
||||||
}
|
}
|
||||||
case _ => fail("wrong type returned, should be ApiDescription")
|
case _ => fail("wrong type returned, should be ApiDescription")
|
||||||
}
|
}
|
||||||
@ -138,7 +145,7 @@ class OperationValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
implicit val formats = SwaggerSerializers.formats("1.2")
|
implicit val formats = SwaggerSerializers.formats("1.2")
|
||||||
|
|
||||||
it should "fail to deserialize an Operation with missing param type" in {
|
it should "fail to deserialize an Operation with missing param type" in {
|
||||||
SwaggerSerializers.validationMessages.clear
|
// SwaggerSerializers.validationMessages.clear
|
||||||
val jsonString = """
|
val jsonString = """
|
||||||
{
|
{
|
||||||
"httpMethod":"GET",
|
"httpMethod":"GET",
|
||||||
@ -162,7 +169,9 @@ class OperationValidationTest extends FlatSpec with ShouldMatchers {
|
|||||||
val json = parse(jsonString)
|
val json = parse(jsonString)
|
||||||
json.extract[Operation] match {
|
json.extract[Operation] match {
|
||||||
case op: Operation => {
|
case op: Operation => {
|
||||||
SwaggerSerializers.validationMessages.size should be (1)
|
val errors = new ListBuffer[ValidationError]
|
||||||
|
SwaggerValidator.validate(op, errors, "")
|
||||||
|
errors.size should be (1)
|
||||||
}
|
}
|
||||||
case _ => fail("wrong type returned, should be Operation")
|
case _ => fail("wrong type returned, should be Operation")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user