Closed grahamj closed 10 years ago
PS the site it's connecting to is node / Express / swagger-jack and as far as I can tell renders proper Swagger 1.2 JSON. Would the above error occur if it was a matter of simply not meeting 1.2 specs? I would expect the validator to give more meaningful messages than Java exceptions if so!
@grahamj that is correct. My guess is that if you look at the JSON that lives here:
http://172.17.42.1:3080/api/1/api-docs.json/users
you have something like this:
"consumes": "application/json"
but the spec (and the codegen) expects this:
"consumes": [
"application/json"
]
You can either try to fix it in swagger-jack (I don't know the author of that project personally) or you can tell the codegen to skip errors with a system property:
-DskipErrors
I'll keep skipErrors in mind once I get to the codegen step, thanks.
For now I'm just trying to get through the validator. The consumes thing alone seems to have cleaned things up considerably. I'm glad you responded because I would never have known that's what it meant!
Now I'm getting:
missing models: Set()
----------
java.nio.charset.MalformedInputException: Input length = 1
Looks like SwaggerSpecValidator.scala line 99 is looking in the wrong place for the report template. Fixed that, now I'm getting a NullPointerException. Fun!
No, that template location is fine--it's reading it from the jar file.
As you can see from running the sample, the code works:
./bin/validate.sh http://petstore.swagger.wordnik.com/api/api-docs "special-key" out.html
Ya I gave up running your bash scripts as the scala version checks are borked (2.10.4 vs 2.10)
Anyway decided to set the validator aside for a moment and ran the generator just for kicks. It actually seems to be doing the validation but it complaining about things that don't seem be a problem, such as:
ValidationError(/apps:/apps:POST,responseClass is required,ERROR)
Whereas responseClass does appear to be in there:
"apis": [
{
"path": "/apps",
"operations": [
{
"httpMethod": "POST",
"summary": "Create an application",
"notes": "Devices are instances of applications and are used to connect into the system. You would likely have a different application for each type of device that connects into the system. Using this API you can create an application. To be able to call this method the calling device needs the app.create capability on the specified org_id.\n",
"responseClass": "App",
"nickname": "create",
"consumes": [
"application/json"
],
"parameters": [
{
"paramType": "body",
"required": true,
"dataType": "AppCreate"
}
]
},
Incidentally a search for responseClass in the 1.2 spec comes up with nothing.
Pull the latest to address the 2.10.4 issue and try our scripts again, it should help troubleshoot
On Jul 18, 2014, at 10:02 AM, "Graham J" notifications@github.com wrote:
Ya I gave up running your bash scripts as the scala version checks are borked (2.10.4 vs 2.10)
Anyway decided to set the validator aside for a moment and ran the generator just for kicks. It actually seems to be doing the validation but it complaining about things that don't seem be a problem, such as:
ValidationError(/apps:/apps:POST,responseClass is required,ERROR) Whereas responseClass does appear to be in there:
"apis": [ { "path": "/apps", "operations": [ { "httpMethod": "POST", "summary": "Create an application", "notes": "Devices are instances of applications and are used to connect into the system. You would likely have a different application for each type of device that connects into the system. Using this API you can create an application. To be able to call this method the calling device needs the app.create capability on the specified org_id.\n", "responseClass": "App", "nickname": "create", "consumes": [ "application/json" ], "parameters": [ { "paramType": "body", "required": true, "dataType": "AppCreate" } ] }, Incidentally a search for responseClass in the 1.2 spec comes up with nothing.
— Reply to this email directly or view it on GitHub.
Removed the version check, returned SwaggerSpecValidator.scala back to pristine, recompiled, ran recommended command line above:
API path: /pet
API path: /user
API path: /store
swagger version: 1.2
basePath:
api version: 1.0.0
----------
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:338)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.read(BufferedReader.java:175)
at scala.io.BufferedSource$$anonfun$iter$1$$anonfun$apply$mcI$sp$1.apply$mcI$sp(BufferedSource.scala:38)
at scala.io.Codec.wrap(Codec.scala:68)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.collection.Iterator$$anon$9.next(Iterator.scala:162)
at scala.collection.Iterator$$anon$17.hasNext(Iterator.scala:511)
at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
at scala.io.Source.hasNext(Source.scala:226)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.io.Source.foreach(Source.scala:178)
at scala.collection.TraversableOnce$class.addString(TraversableOnce.scala:320)
at scala.io.Source.addString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:286)
at scala.io.Source.mkString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:288)
at scala.io.Source.mkString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:290)
at scala.io.Source.mkString(Source.scala:178)
at com.wordnik.swagger.codegen.spec.SwaggerSpecValidator.generateReport(SwaggerSpecValidator.scala:99)
at com.wordnik.swagger.codegen.spec.Validator$.main(Validator.scala:65)
at com.wordnik.swagger.codegen.spec.Validator.main(Validator.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
at com.wordnik.swagger.codegen.spec.SwaggerSpecValidator.generateReport(SwaggerSpecValidator.scala:99)
In other words, not finding the template
Fix template path in source again, recompile, run again:
API path: /pet
API path: /user
API path: /store
swagger version: 1.2
basePath:
api version: 1.0.0
----------
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:129)
at scala.io.BufferedSource.reader(BufferedSource.scala:22)
at scala.io.BufferedSource.bufferedReader(BufferedSource.scala:23)
at scala.io.BufferedSource.scala$io$BufferedSource$$charReader$lzycompute(BufferedSource.scala:33)
at scala.io.BufferedSource.scala$io$BufferedSource$$charReader(BufferedSource.scala:31)
at scala.io.BufferedSource$$anonfun$iter$1$$anonfun$apply$mcI$sp$1.apply$mcI$sp(BufferedSource.scala:38)
at scala.io.Codec.wrap(Codec.scala:68)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.collection.Iterator$$anon$9.next(Iterator.scala:162)
at scala.collection.Iterator$$anon$17.hasNext(Iterator.scala:511)
at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
at scala.io.Source.hasNext(Source.scala:226)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.io.Source.foreach(Source.scala:178)
at scala.collection.TraversableOnce$class.addString(TraversableOnce.scala:320)
at scala.io.Source.addString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:286)
at scala.io.Source.mkString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:288)
at scala.io.Source.mkString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:290)
at scala.io.Source.mkString(Source.scala:178)
at com.wordnik.swagger.codegen.spec.SwaggerSpecValidator.generateReport(SwaggerSpecValidator.scala:101)
at com.wordnik.swagger.codegen.spec.Validator$.main(Validator.scala:65)
at com.wordnik.swagger.codegen.spec.Validator.main(Validator.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Is this master? And to confirm, you're running './sbt assembly' right?
Yes master, and yes compiling with ./sbt assembly
Ok I'll have to dig in more. With a clean build I'm getting the expected results.
ok must be something here I guess, I'll blow it away and retry
git clone https://github.com/wordnik/swagger-codegen.git swagger-codegen
cd swagger-codegen
./sbt assembly
./bin/scala-petstore.sh
Please set scalaVersion := "fsc. does not exist or is not a directory
fsc -help gives more information
2.10.4" in build.sbt and run ./sbt assembly
<edit build.sbt as specified>
./sbt assembly
./bin/scala-petstore.sh
./bin/scala-petstore.sh: 28: [: /opt/sdk_gen/swagger-codegen/target/scala-fsc.: unexpected operator
Please set scalaVersion := "fsc. does not exist or is not a directory
fsc -help gives more information
2.10.4" in build.sbt and run ./sbt assembly
<edit scala-petstore.sh to remove version check>
./bin/scala-petstore.sh
fsc. does not exist or is not a directory
fsc -help gives more information
/opt/sdk_gen/swagger-codegen/samples/client/petstore/scala/ScalaPetstoreCodegen.scala:17: error: object wordnik is not a member of package com
import com.wordnik.swagger.codegen.BasicScalaGenerator
^
/opt/sdk_gen/swagger-codegen/samples/client/petstore/scala/ScalaPetstoreCodegen.scala:19: error: not found: type BasicScalaGenerator
object ScalaPetstoreCodegen extends BasicScalaGenerator {
^
/opt/sdk_gen/swagger-codegen/samples/client/petstore/scala/ScalaPetstoreCodegen.scala:20: error: not found: value generateClient
def main(args: Array[String]) = generateClient(args)
^
three errors found
<set build.sbt back to 2.10.0>
./sbt assembly
./bin/scala-petstore.sh
sc. does not exist or is not a directory
fsc -help gives more information
/opt/sdk_gen/swagger-codegen/samples/client/petstore/scala/ScalaPetstoreCodegen.scala:17: error: object wordnik is not a member of package com
import com.wordnik.swagger.codegen.BasicScalaGenerator
^
/opt/sdk_gen/swagger-codegen/samples/client/petstore/scala/ScalaPetstoreCodegen.scala:19: error: not found: type BasicScalaGenerator
object ScalaPetstoreCodegen extends BasicScalaGenerator {
^
/opt/sdk_gen/swagger-codegen/samples/client/petstore/scala/ScalaPetstoreCodegen.scala:20: error: not found: value generateClient
def main(args: Array[String]) = generateClient(args)
^
three errors found
<edit validate.sh to remove version check>
./bin/validate.sh http://petstore.swagger.wordnik.com/api/api-docs "special-key" out.html
cial-key" out.html_gen/swagger-codegen master > ./bin/validate.sh http://petstore.swagger.wordnik.com/api/api-docs "spec
swagger version: 1.2
basePath:
api version: 1.0.0
----------
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:338)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.read(BufferedReader.java:175)
at scala.io.BufferedSource$$anonfun$iter$1$$anonfun$apply$mcI$sp$1.apply$mcI$sp(BufferedSource.scala:38)
at scala.io.Codec.wrap(Codec.scala:68)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.collection.Iterator$$anon$9.next(Iterator.scala:162)
at scala.collection.Iterator$$anon$17.hasNext(Iterator.scala:511)
at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
at scala.io.Source.hasNext(Source.scala:226)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.io.Source.foreach(Source.scala:178)
at scala.collection.TraversableOnce$class.addString(TraversableOnce.scala:320)
at scala.io.Source.addString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:286)
at scala.io.Source.mkString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:288)
at scala.io.Source.mkString(Source.scala:178)
at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:290)
at scala.io.Source.mkString(Source.scala:178)
at com.wordnik.swagger.codegen.spec.SwaggerSpecValidator.generateReport(SwaggerSpecValidator.scala:99)
at com.wordnik.swagger.codegen.spec.Validator$.main(Validator.scala:65)
at com.wordnik.swagger.codegen.spec.Validator.main(Validator.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
And without a few mods I made to fix URL generation I'm back to the generator adding API URLs onto the command line specified URL instead of the basePath:
✔ megavm /graham/swagger-codegen master > ./bin/runscala.sh com.wordnik.swagger.codegen.BasicScalaGenerator http://172.17.42.1:3080/api/1/api-docs.json
base path is http://172.17.42.1:3080/api/1/api-docs.json
java.io.FileNotFoundException: http://172.17.42.1:3080/api/1/api-docs.json/api-docs.json/apps
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1401)
at com.wordnik.swagger.codegen.util.RemoteUrl$class.urlToString(RemoteUrl.scala:14)
at com.wordnik.swagger.codegen.util.ApiExtractor$.urlToString(ApiExtractor.scala:30)
at com.wordnik.swagger.codegen.util.ApiExtractor$$anonfun$fetchApiListings$1.apply(ApiExtractor.scala:39)
at com.wordnik.swagger.codegen.util.ApiExtractor$$anonfun$fetchApiListings$1.apply(ApiExtractor.scala:33)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:318)
That's not the basePath set:
{
"apiVersion": "1.0.0",
"basePath": "http://172.17.42.1:3080/api/1",
"swaggerVersion": "1.2",
(note the doubling of api-docs.json)
So ya
Share some JSON and we can sort it out
ok but as per above the samples won't work so I'd like to at least see something work before pointing it at my JSON again.
what OS are you running? Can you change this line:
SwaggerSpecValidator.scala: 99
to this:
TemplateSource.fromText(templateLocation, Source.fromInputStream(getClass.getClassLoader.getResourceAsStream(templateLocation), "utf-8").mkString))
My guess is the locale of your machine is using a character set that's not compatible with the utf-8 that's being produced by the sample
Ubuntu 14.04. I'd be pretty surprised if character encoding was the issue here, it seems like it's looking on the filesystem for required files rather than in a JAR file.
Anyway I've made some headway. The closest I got to the validator working was a Java null pointer exception so I set that aside and fired up the codegen. Now that I'm able to mentally translate the Java errors and stack traces into Swagger spec problems I've managed to get my files to pass and generate.
It really seems like its validating to some other spec version though. It complains about responseClass being required, for example, yet there's no mention of that in the 1.2 spec. I had to duplicate all responseClass lines to "type" and that passed that. My parameters have a dataType line which swagger-jack requires but codegen needs it to be called "type" also.
I seem to be turning into the de facto Swagger guy over here as we're using this for an Internet of Things initiative so I'll likely contribute some fixes at some point.
Thanks for your help.
This issue is driving me nuts, because this is a well tested library. I have a feeling that the swagger-jack project is not creating valid swagger JSON. There’s a slick project here:
https://github.com/apigee/swagger-tools
Which you might be able to use for full, human-readable validation against the 1.2 spec. -- Tony Tam Sent with Airmail
On July 22, 2014 at 11:51:34 AM, Graham J (notifications@github.com) wrote:
Ubuntu 14.04. I'd be pretty surprised if character encoding was the issue here, it seems like it's looking on the filesystem for required files rather than in a JAR file.
Anyway I've made some headway. The closest I got to the validator working was a Java null pointer exception so I set that aside and fired up the codegen. Now that I'm able to mentally translate the Java errors and stack traces into Swagger spec problems I've managed to get my files to pass and generate.
It really seems like its validating to some other spec version though. It complains about responseClass being required, for example, yet there's no mention of that in the 1.2 spec. I had to duplicate all responseClass lines to "type" and that passed that. My parameters have a dataType line which swagger-jack requires but codegen needs it to be called "type" also.
I seem to be turning into the de facto Swagger guy over here as we're using this for an Internet of Things initiative so I'll likely contribute some fixes at some point.
Thanks for your help.
— Reply to this email directly or view it on GitHub.
I think you're right about swagger-jack - the project hasn't been worked on in a long time and issues are going unanswered. Pity you guys aren't working together on this. Still, I had significant problems with codegen before it even got to reading JSON, and now that it's doing that I had to create a strange hybrid of 1.1 and 1.2 to pass everything.
I'll check out swagger-tools, thanks for the suggestion. Hopefully this will help alleviate the feeling of wishing my colleague had chosen some other way of describing our API.
can you look at our library, here: https://github.com/wordnik/swagger-node-express
jack, tools, express... all to do the same thing? Which one do I want?
swagger-tools will help you validate the swagger json. Currently the author is focusing on getting good feedback to users regarding malformed specs.
I didn't write swagger-jack, it does do something very similar to swagger-node-express, which I did write (with lots of input).
The community is making lots of integrations for swagger, so you'll see different ways to do so.
Looking at swagger-node-express, it looks like I'd need to integrate the spec data into my code and add each function separately. I've got 51 functions so far so that doesn't sound like much fun, although having the spec next to each function might be appealing...
This might be a problem on my end but I thought I'd post it here in case others are experiencing this. I've spent the better part of two days trying to get any of these tools running and everything I do comes down to what seems like a JSON parsing issue.
Running the validator:
It's reading the main file well enough to find the sub API paths I get the above when it tries to read any of them. The same thing happens if I download the files and point to them with -DfileMap so it's not a transfer issue. It sees the files but does not like them.
My best guess is maybe a json4 versioning issue but I'm not really a Java guy so I don't know how to check or fix that.
Any suggestions?