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

Problems with Paramater References with OAS 3.x specifications #309

Closed
rvesse opened this issue May 20, 2019 · 5 comments
Closed

Problems with Paramater References with OAS 3.x specifications #309

rvesse opened this issue May 20, 2019 · 5 comments

Comments

@rvesse
Copy link
Contributor

rvesse commented May 20, 2019

Trying to use Inflector with an OAS 3.0 spec that uses parameter references extensively (this is a tiny subset of the whole API document) e.g.

openapi: 3.0.1
info:
  title: Example API
  version: 1.0.0
paths:
  /manifests:
    get:
      summary: Gets all available Manifests
      operationId: listAllManifests
      responses:
        '200':
          description: List of Manifests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedResourceNameList'
            application/x-yaml:
              schema:
                $ref: '#/components/schemas/OwnedResourceNameList'
  '/manifests/{owner}':
    get:
      summary: Gets all Manifests owned by the specified owner
      operationId: listOwnedManifests
      parameters:
        - $ref: '#/components/parameters/OwnerParam'
      responses:
        '200':
          description: List of Manifests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedResourceNameList'
            application/x-yaml:
              schema:
                $ref: '#/components/schemas/OwnedResourceNameList'
components:
  parameters:
    OwnerParam:
      in: path
      name: owner
      schema:
        type: string
      required: true
      description: The username of the user whose resources that you wish to access
      example: lhamilton
  schemas:
    OwnedResourceNameList:
      type: array
      items:
        type: object
        properties:
          owner:
            type: string
          name:
            type: string
      example:
        - owner: lhamilton
          name: track-analysis

And attempting to access the methods that use reference parameters result in NPEs:

> curl -H "Accept: application/json" -vvv http://localhost:8080/manifests/foo
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /manifests/foo HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: application/json
> 
< HTTP/1.1 500 Internal Server Error
< Date: Mon, 20 May 2019 09:46:57 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: Content-Type, api_key, Authorization
< Content-Type: application/json
< Content-Length: 110
< Server: Jetty(9.2.9.v20150224)
< 
* Connection #0 to host localhost left intact
{"code":500,"message":"There was an error processing your request. It has been logged (ID: 00736be1c96884e5)"}mbp-rvesse2:~ rvesse$ curl -H "Accept: application/json" -vvv http://localhost:8080/manifests/foo

Produces the following error trace:

11:06:07.312 [qtp2089816579-28] ERROR i.s.i.utils.DefaultExceptionMapper - There was an error processing your request. It has been logged (ID: 66035bf379eae73c)
java.lang.NullPointerException: null
        at io.swagger.inflector.controllers.SwaggerOperationController.apply(SwaggerOperationController.java:435) ~[swagger-inflector-1.0.17.jar:1.0.17]
        at io.swagger.inflector.controllers.SwaggerOperationController.apply(SwaggerOperationController.java:89) ~[swagger-inflector-1.0.17.jar:1.0.17]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_92]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_92]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_92]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_92]
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) ~[jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [jersey-common-2.25.1.jar:na]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [jersey-common-2.25.1.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.25.1.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.25.1.jar:na]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [jersey-common-2.25.1.jar:na]
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [jersey-common-2.25.1.jar:na]
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [jersey-server-2.25.1.jar:na]
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) [jersey-container-servlet-core-2.25.1.jar:na]
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) [jersey-container-servlet-core-2.25.1.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) [jersey-container-servlet-core-2.25.1.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) [jersey-container-servlet-core-2.25.1.jar:na]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) [jersey-container-servlet-core-2.25.1.jar:na]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808) [jetty-servlet-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [jetty-servlet-9.2.9.v20150224.jar:9.2.9.v20150224]
        at io.swagger.inflector.utils.CORSFilter.doFilter(CORSFilter.java:35) [swagger-inflector-1.0.17.jar:1.0.17]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [jetty-servlet-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) [jetty-security-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.Server.handle(Server.java:497) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) [jetty-io-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.9.v20150224.jar:9.2.9.v20150224]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.9.v20150224.jar:9.2.9.v20150224]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_92]

Attaching a debugger and setting breakpoints I can see that the RefParameter is not getting resolved at all so all its fields are null leading to the NPE in SwaggerOperationController

Took a look at ResolverUtils.resolveFully() and it doesn't look like it does anything to resolve reference parameters which seems incorrect.

@rvesse
Copy link
Contributor Author

rvesse commented May 20, 2019

Interestingly if I manually resolve the reference by replacing it with a concrete definition then the API call still fails to resolve the parameter directly with the exact same NPE.

Not sure if this is a problem with my parameter definition or a more general problem with Inflector's parameter type handling (and possibly a problem with parsing the Swagger document).

I would tend to assume that this is my error but looking at the docs I don't see what I've done wrong??

@rvesse
Copy link
Contributor Author

rvesse commented May 20, 2019

Realised part of the problem might be that I was targeting the wrong version of Inflector. I am using OAS 3.x so needed to use Inflector 2.x however using 2.0.0 produces a different NPE instead:

Caused by: java.lang.NullPointerException
    at io.swagger.oas.inflector.controllers.OpenAPIOperationController.matchBuildMethodToImplemented (OpenAPIOperationController.java:209)
    at io.swagger.oas.inflector.controllers.OpenAPIOperationController.detectMethod (OpenAPIOperationController.java:187)
    at io.swagger.oas.inflector.controllers.OpenAPIOperationController.<init> (OpenAPIOperationController.java:141)
    at io.swagger.oas.inflector.OpenAPIInflector.createController (OpenAPIInflector.java:457)
    at io.swagger.oas.inflector.OpenAPIInflector.addOperation (OpenAPIInflector.java:450)
    at io.swagger.oas.inflector.OpenAPIInflector.init (OpenAPIInflector.java:163)
    at io.swagger.oas.inflector.OpenAPIInflector.<init> (OpenAPIInflector.java:108)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0 (Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance (Constructor.java:423)
    at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe (ReflectionHelper.java:1375)
    at org.jvnet.hk2.internal.Utilities.justCreate (Utilities.java:1083)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.create (ServiceLocatorImpl.java:978)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize (ServiceLocatorImpl.java:1082)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize (ServiceLocatorImpl.java:1074)
    at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.createAndInitialize (AbstractHk2InjectionManager.java:213)
    at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.createAndInitialize (ImmediateHk2InjectionManager.java:54)
    at org.glassfish.jersey.server.ApplicationConfigurator.createApplication (ApplicationConfigurator.java:138)
    at org.glassfish.jersey.server.ApplicationConfigurator.init (ApplicationConfigurator.java:96)
    at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0 (ApplicationHandler.java:313)
    at java.util.Arrays$ArrayList.forEach (Arrays.java:3880)
    at org.glassfish.jersey.server.ApplicationHandler.initialize (ApplicationHandler.java:313)
    at org.glassfish.jersey.server.ApplicationHandler.<init> (ApplicationHandler.java:282)
    at org.glassfish.jersey.servlet.WebComponent.<init> (WebComponent.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.init (ServletContainer.java:178)
    at org.glassfish.jersey.servlet.ServletContainer.init (ServletContainer.java:370)
    at javax.servlet.GenericServlet.init (GenericServlet.java:244)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet (ServletHolder.java:669)
    at org.eclipse.jetty.servlet.ServletHolder.initialize (ServletHolder.java:426)
    at org.eclipse.jetty.servlet.ServletHandler.initialize (ServletHandler.java:760)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext (ServletContextHandler.java:374)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp (WebAppContext.java:1497)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp (JettyWebAppContext.java:360)
    at org.eclipse.jetty.webapp.WebAppContext.startContext (WebAppContext.java:1459)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart (ContextHandler.java:785)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart (ServletContextHandler.java:287)
    at org.eclipse.jetty.webapp.WebAppContext.doStart (WebAppContext.java:545)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart (JettyWebAppContext.java:428)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start (ContainerLifeCycle.java:138)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart (ContainerLifeCycle.java:117)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart (AbstractHandler.java:113)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart (ContextHandlerCollection.java:167)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start (ContainerLifeCycle.java:138)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart (ContainerLifeCycle.java:117)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart (AbstractHandler.java:113)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start (ContainerLifeCycle.java:138)
    at org.eclipse.jetty.server.Server.start (Server.java:419)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart (ContainerLifeCycle.java:108)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart (AbstractHandler.java:113)
    at org.eclipse.jetty.server.Server.doStart (Server.java:386)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:68)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty (AbstractJettyMojo.java:467)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute (AbstractJettyMojo.java:329)
    at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute (JettyRunMojo.java:179)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
[INFO] Started ServerConnector@1d1deb11{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}

So still no closer to having a usable REST service :(

@rvesse rvesse changed the title ResolverUtil.resolveFully() does not resolve RefParameter leading to NPE Problems with Paramater References with OAS 3.x specifications May 20, 2019
@rvesse
Copy link
Contributor Author

rvesse commented May 20, 2019

Did some more debugging, the root of the problem is that the schema for my referenced parameter does not seem to get loaded properly resulting in the null argument type.

Can't see anything obviously wrong with my schema declaration but clearly something is wrong with it? Any ideas?

@rvesse
Copy link
Contributor Author

rvesse commented May 20, 2019

Further digging, in OpenAPIInflector.java in the init() method where the spec gets parsed I see there is an message being reported:

attribute components.parameters.OwnerParam.[owner].type is unexpected

Which would explain why the type isn't parsed but I'm still confused because this parameter definition looks identical to example ones in the pet store examples

@rvesse
Copy link
Contributor Author

rvesse commented May 20, 2019

So this was a weird white space issue, applying some reformatting fixed the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant