Troubleshooting Swagger issues in WSO2 API Manager

WSO2 API Manager provides this functionality through the integration of Swagger (https://developers.helloreverb.com/swagger). Swagger-based interactive documentation allows you to try out APIs from the documentation itself which is available as the "API Console" in API Store. 

There are certain requirements that need to be satisfied in order to swagger Try-it functionality to work. First requirement is to enable CORS in API Mananger Store. This documentation describes how that should be done. 

But most of them face many issues in getting the swagger Try-it into work. So this blog post describes common issues faced by users with Swagger and how to troubleshoot them.  

Issue-1

API Console keeps on loading the response for ever as below.

Cause -1

API resource not supporting OPTIONS HTTP verb. 

Solution

Add OPTIONS HTTP verb for API resources as below. Then Save the API and Try again. 



Cause -2 

Backend endpoint not supporting OPTIONS HTTP verb. 

Note: You can verify this by directly invoking the backend for OPTIONS verb. If backend is not supporting OPTIONS verb, "403 HTTP method not allowed" will be returned. 

Solution

If you have control over the Backend service/api, enable OPTIONS HTTP verb. 

Note: You can verify this by directly invoking the backend for OPTIONS verb. If backend is supporting OPTIONS verb, 200/202/204 success response should be returned.


If you can't enable OPTIONS HTTP verb in the backend, then what you can do is modify the API synapse sequence of the API, which returns back without sending the request to the backend if it is an OPTIONS request. 

Issue-2

API Console completes request execution, but no response is returned. 


Cause-1

Authentication Type enabled for OPTIONS HTTP verb is not 'None'. 


If this is the cause below error message will be shown in the wso2carbon.log.

org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Required OAuth credentials not provided
at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:122)
at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:92)
at org.apache.synapse.rest.API.process(API.java:285)
at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)

Solution

Make the Auth Type as none for OPTIONS HTTP verb as below. Then Save & Publish the API.



Note: If you are seeing the Issue -2 , even though Authentication type is shown as none for OPTIONS, then please re-select the authentication type as 'none' as above. Then Save & Publish the API. There is an UI bug in API Manager 1.7.0, where although you have set some other authentication type other than 'None' for OPTIONS verb, UI shows it as none. 

Cause-2

API Store domain/port which you are currently trying swagger API Console, is not included in the CORS Access-Control-Allow-Origin configuration. For example, in below CORS configuration, only localhost domain addresses are allowed for API Store. But API Console is accessed using IP address. 




Solution

Include domain/port in the CORS Access-Control-Allow-Origin configuration. For above example, we have to include IP address as below.  Then restart the server and try API Console again. 


Issue-3

API Console keeps on loading the response for ever as below when API Store is accessed as HTTPs, while HTTP is working properly. 

Cause-1

Browser blocking the request due to accessing the API Gateway in HTTP from HTTPs. 

Solution

Go to API Publisher and edit "Swagger API Definition" of the API and change the basePath with https gateway address as below. The Save the "Swagger API Definition" and try again. 


Cause-2 

If you are still getting the issue, even after applying the above then, cause can be that the security certificate issued by the server is not trusted by your browser.

Solution

Access the HTTPS gateway endpoint directly from your browser and accept the security certificate. Then try again. 


Comments

  1. Thanks for the great post. I am using version 1.8 of the API Manager and I am having an issue with the try-it functionality. I did all the things you recommended but when I click on Try It, I am getting no response. I have CORS enabled and OPTIONS has None for authorization. I also have HTTPs working. In Firebug, the console has a 403 error for the OPTIONS call. I did notice that the headers for the OPTIONS request had an Access-Control-Request-Header of 'authorization'. If I make a similar request with a different tool, I also get a 403 error. Removing the header fixes the issue. Is this a bug or do you think I have something setup incorrectly? Thanks for any advice.

    ReplyDelete
  2. Can you do a OPTIONS call to your API URL as below and post your responses here?

    ex:- curl -v -X OPTIONS http://localhost:8280/api/1.0.0

    ReplyDelete
  3. Thanks for responding. Here is the response from curl -v -k -X OPTIONS https://dev.xxxx.com:8243/pub/vp/1.0.0/members

    > OPTIONS /pub/vp/1.0.0/members HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    > Host: dev.xxxx.com:8243
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Access-Control-Request-Headers,Content-Type
    < Last-modified: Fri, 16 Jan 2015 09:07:31 EST
    < Allow: POST,GET,OPTIONS,HEAD,PUT
    < Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
    < Content-Type: application/vnd.sun.wadl+xml
    < Date: Fri, 16 Jan 2015 14:07:31 GMT
    < Server: WSO2-PassThrough-HTTP
    < Transfer-Encoding: chunked
    <

    Here are the headers for the OPTIONS request sent by the browser when I click on the OPTIONS try-it button:

    OPTIONS /pub/vp/1.0.0/members HTTP/1.1
    Host: dev.xxxx.com:8243
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Origin: https://dev.xxxx.com:9443
    Access-Control-Request-Method: OPTIONS
    Access-Control-Request-Headers: authorization
    Connection: keep-alive

    Here is the equivalent curl request and the response:
    curl -v -k -X OPTIONS -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.5' -H 'Access-Control-Request-Headers: authorization' -H 'Access-Control-Request-Method: OPTIONS' -H 'Connection: keep-alive' -H 'Host: dev.xxxx.com:8243' -H 'Origin: https://dev.xxxx.com:9443' -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0' 'https://dev.xxxx.com:8243/pub/vp/1.0.0/members'

    > OPTIONS /pub/vp/1.0.0/members HTTP/1.1
    > Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    > Accept-Encoding: gzip, deflate
    > Accept-Language: en-US,en;q=0.5
    > Access-Control-Request-Headers: authorization
    > Access-Control-Request-Method: OPTIONS
    > Connection: keep-alive
    > Host: dev.xxxx.com:8243
    > Origin: https://dev.xxxx.com:9443
    > User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
    >
    < HTTP/1.1 403 Forbidden
    < Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Access-Control-Request-Headers,Content-Type
    < Access-Control-Allow-Origin: https://dev.xxxx.com:9443
    < Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
    < Content-Type: text/plain
    < Date: Fri, 16 Jan 2015 14:05:08 GMT
    < Server: WSO2-PassThrough-HTTP
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    <

    If I remove the Access-Control-Request-Headers headers from the OPTIONS request, this is the response:
    > OPTIONS /pub/vp/1.0.0/members HTTP/1.1
    > Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    > Accept-Encoding: gzip, deflate
    > Accept-Language: en-US,en;q=0.5
    > Access-Control-Request-Method: OPTIONS
    > Connection: keep-alive
    > Host: dev.xxxx.com:8243
    > Origin: https://dev.xxxx.com:9443
    > User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
    >
    < HTTP/1.1 200 OK
    < Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Access-Control-Request-Headers,Content-Type
    < Access-Control-Allow-Origin: https://dev.xxxx.com:9443
    < Access-Control-Max-Age: 1800
    < Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
    < Content-Type: application/octet-stream
    < Access-Control-Allow-Credentials: true
    < Date: Fri, 16 Jan 2015 14:10:34 GMT
    < Server: WSO2-PassThrough-HTTP
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    <

    ReplyDelete
  4. Thanks for the informative post.

    I tried adding OPTIONS HTTP verb to API resource. However, when I press submit button after adding the verb, I get a message 'Error while adding the API - '

    ReplyDelete

Post a Comment

Popular posts from this blog

Manually install a maven dependency

PHP-SOAP web service with out a WSDL

Axis 2 web services in eclipse: Exception java.lang.NoClassDefFoundError: org/apache/http/HttpResponseFactory thrown when Services link clicked