Generator-jhipster: Error 404 on gateway for swagger-ui

Created on 25 Feb 2016  Â·  19Comments  Â·  Source: jhipster/generator-jhipster

Overview of the issue

I generated a gateway from master
The app works on port 8080 but I get an error 404 on http://localhost:9000/swagger-ui/index.html

JHipster Version(s)

3.0 master at #c9f3e112739008bf0241678608407df419e6da53

JHipster configuration, a .yo-rc.json file generated in the root folder
{
  "generator-jhipster": {
    "jhipsterVersion": "2.27.0",
    "baseName": "gateway",
    "packageName": "com.a.e.central",
    "packageFolder": "com/a/e/central",
    "authenticationType": "jwt",
    "hibernateCache": "ehcache",
    "clusteredHttpSession": "no",
    "websocket": "no",
    "databaseType": "sql",
    "devDatabaseType": "h2Memory",
    "prodDatabaseType": "postgresql",
    "searchEngine": "no",
    "buildTool": "maven",
    "jwtSecretKey": "***",
    "rememberMeKey": "***",
    "useSass": true,
    "enableTranslation": false,
    "applicationType": "gateway",
    "testFrameworks": [],
    "enableSocialSignIn": false
  }
}
Entity configuration(s) entityName.json files generated in the .jhipster directory

No entities on gateway.

area

Most helpful comment

@yhjhoo : I understand your need, but as discussed before, it won't be done in the generator-jhipster.
Your demo is not a microservice. It's a simple application with swagger, without security

There are 2 solutions:
1) you can code yourself what you need, just keep in mind this page should not be able in production profile
2) simply generate a gateway and start it. That's what I always do

All 19 comments

Yes this is "normal".

  • We don't generate any UI anymore on the microservices, so there is no Swagger UI there
  • The idea is that the UI is now on the gateway: when you log into the gateway, the "API" menu is there like in the monolith app, but now you have a dropdown list and you can have access to the Swagger doc from the microservices from there. All the documentation is now in one place :-)
  • Be careful, this is linked to #2954 so right now I'm not sure if the Swagger JSON is available from the microservice (which will make the gateway UI fail, of course)

Thanks, I found a real issue on gateway:

/swagger-resources is provided by springfox-swagger-ui while we have defined same mapping in GatewaySwaggerApiResource. As a result, our mapping is ignored, it took me some time to find out why my breakpoint here was ignored.

This makes me think that maybe we should name spaced our URLs as we could conflict with spring-boot itself or other libs we include.

I just read the comment in GatewaySwaggerApiResource

 * GET  /swagger-resources : get the currently registered microservices swagger resources
* (Override the Springfox provided /swagger-resources endpoint)

The fact is that for me Springfox endpoint is not overridden at all.
I suppose it could be an issue of order in class loader.

@gmarziou. I remember when I added this code it worked only if you were authenticated. When you were not it fell back to the springfox provided endpoint. I totally forgot to share this with you guys. Actually, I think that we should find a way to properly override the springfox /swagger-resources controller.

Yes or we can ask springfox team whether there is a way to disable it, in the past they were very responsive

To be precise the swagger-resources endpoint is provided by springfox itself, not by springox-swagger-ui

A solution could be to exclude springfox's ApiResourceController from component scan for the gateway.

@ComponentScan(excludeFilters = @ComponentScan.Filter(value = springfox.documentation.swagger.web.ApiResourceController.class, type = FilterType.ASSIGNABLE_TYPE))

Good suggestion but unfortunately, I suspect that we would miss the other endpoints.

What we want is rather to be able to extend ApiResourceController to override /swagger-resources endpoint and use the Component scan filter to avoid instantiating the original controller.

So I submitted PR springfox/springfox#1189.

We had a very postive discussion with @dilipkrish and finally he proposed a refactoring in springfox that allowed me to simplify our solution.

We will drop GatewaySwaggerApiResource and implement a SwaggerResourcesProvider annotated by @Primary so that it takes precedence over the default one from springfox.

I will submit a PR as soon as springfox 2.4.0 gets released.

@Component
@Primary
public class GatewaySwaggerResourceProvider implements SwaggerResourcesProvider {

    private final Logger log = LoggerFactory.getLogger(GatewaySwaggerResourceProvider.class);

    @Inject
    private ProxyRouteLocator routeLocator;

    @Inject
    private DiscoveryClient discoveryClient;

    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();

        //Add the default swagger resource that correspond to the gateway's own swagger doc
        resources.add(swaggerResource("default", "/v2/api-docs", "2.0"));

        //Add the registered microservices swagger docs as additional swagger resources
        Map<String, String> routes = routeLocator.getRoutes();
        routes.forEach((path, serviceId) -> {
            resources.add(swaggerResource(serviceId, path.replace("**","v2/api-docs"), "2.0"));
        });

        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location, String version) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(version);
        return swaggerResource;
    }
}

Awesome

Thanks & Regards,
Deepu

On Sat, Feb 27, 2016 at 6:02 PM, Gaël Marziou [email protected]
wrote:

We had a very postive discussion
https://github.com/springfox/springfox/pull/1189 with @dilipkrish
https://github.com/dilipkrish and finally he proposed a refactoring in
springfox https://github.com/springfox/springfox/pull/1191 that allowed
me to simplify our solution.

Finally we will drop GatewaySwaggerApiResource and implement a
SwaggerResourcesProvider annotated by @Primary so that it takes
precedence over the default one from springfox.

I will submit a PR as soon as springfox 2.4.0 gets released.

@Component
@Primarypublic class GatewaySwaggerResourceProvider implements SwaggerResourcesProvider {

private final Logger log = LoggerFactory.getLogger(GatewaySwaggerResourceProvider.class);

@Inject
private ProxyRouteLocator routeLocator;

@Inject
private DiscoveryClient discoveryClient;

@Override
public List<SwaggerResource> get() {
    List<SwaggerResource> resources = new ArrayList<>();

    //Add the default swagger resource that correspond to the gateway's own swagger doc
    resources.add(swaggerResource("default", "/v2/api-docs", "2.0"));

    //Add the registered microservices swagger docs as additional swagger resources
    Map<String, String> routes = routeLocator.getRoutes();
    routes.forEach((path, serviceId) -> {
        resources.add(swaggerResource(serviceId, path.replace("**","v2/api-docs"), "2.0"));
    });

    return resources;
}

private SwaggerResource swaggerResource(String name, String location, String version) {
    SwaggerResource swaggerResource = new SwaggerResource();
    swaggerResource.setName(name);
    swaggerResource.setLocation(location);
    swaggerResource.setSwaggerVersion(version);
    return swaggerResource;
}

}

—
Reply to this email directly or view it on GitHub
https://github.com/jhipster/generator-jhipster/issues/2990#issuecomment-189615185
.

@jdubois

Yes this is "normal".

We don't generate any UI anymore on the microservices, so there is no Swagger UI there
The idea is that the UI is now on the gateway: when you log into the gateway, the "API" menu is there like in the monolith app, but now you have a dropdown list and you can have access to the Swagger doc from the microservices from there. All the documentation is now in one place :-)
Be careful, this is linked to #2954 so right now I'm not sure if the Swagger JSON is available from the microservice (which will make the gateway UI fail, of course)

Is it possible to enable swagger-ui on microservices?

@jhjhoo this was requested before and we don't want to do it.
Just enable the swagger profile to have the swagger docs on tour microservices, as for swagger-ui, the only solution we support is passing through the gateway is supported and works out of the box !

@PierreBesson

How to enable swagger profile? I saw this log entry "Web application configuration, using profiles: [swagger, dev]"

Does it mean I have enabled swagger? How to access it? I tried to access http://localhost:8081/swagger-ui.html but not able to see it.

@yhjhoo : remember that a microservice doesn't have UI. If you want a UI, you have to create a gateway
By default, you can access to the swagger api at http://localhost:8081/v2/api-docs/

@pascalgrimaud Yeah, I noticed microservice doesn't have UI. But is it possible to just enable swagger-ui.html? It seems like the swagger-ui.html become inaccessible after enable @EnableResourceServer . I have tried standalone microservice here https://github.com/yhjhoo/swaggerDemo and I am able to access it.

@yhjhoo : I understand your need, but as discussed before, it won't be done in the generator-jhipster.
Your demo is not a microservice. It's a simple application with swagger, without security

There are 2 solutions:
1) you can code yourself what you need, just keep in mind this page should not be able in production profile
2) simply generate a gateway and start it. That's what I always do

@pascalgrimaud @PierreBesson @yhjhoo I understand the discussion above, but I have not heard the why? Please explain why it is necessary to have a gateway to view the swagger docs for the microservice? i.e. if the microservice is being developed independently by a separate team why constrain them to having to fire up the gateway inorder to view their api? (I understand that you have the endpoint available.. I am talking specifically about the UI). Your solutions above make sense and I appreciate them, but if we are developing true microservices, then the microservice (and the team creating it) should not care about the Gateway. The notion of all documentation in one place is great for the final product, but during development I think there is a valid need to isolate that. Any thoughts?

@mabuzagu I fully agree with you and it's not that difficult to do it:

  • Add springfox jars (springfox-swagger2 and springfox-swagger-ui) to your dependencies, use 2.4.0 version as current 2.7.0 has an issue with api_key select HTML input
  • Generate a token that expires in 100 years using your gateway jwt shared secret for dev environment
  • Edit yourSwaggerConfiguration class to hard code token as api_key in dev profile by providing a SecurityConfiguration bean

    • Permit all access to /swagger-ui.html in MicroserviceSecurityConfiguration

  • Springfox now sends your token as header when using http://localhost:8080/swagger-ui.html though it does url encode API key so you you get Bearer%20xxxxx rather than Bearer xxxxx which you can easily work around in JWTFilter.

~java
@Bean
@Profile("dev")
SecurityConfiguration security() {
return new SecurityConfiguration(
null,
null,
null,
null,
"Bearer " + "insert your token that never expires",
ApiKeyVehicle.HEADER,
"Authorization",
null);
}
~

This way you don't weaker your security and make developers use tokens all time with ease and efficient use of their local resources.

When I find time I will contribute it to JHipster if team agrees or as a tip but it would be better if we could fix the 2 issues in Springfox first.

@gmarziou I agree to have this in the dev profile, it would be really convenient. The only reason we don't have it already is lack of time, as there are some issues to work around with JWT/OAuth auth. @mabuzagu PR is welcome if you can.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kaidohallik picture kaidohallik  Â·  3Comments

marcelinobadin picture marcelinobadin  Â·  3Comments

SudharakaP picture SudharakaP  Â·  3Comments

lsadehaan picture lsadehaan  Â·  3Comments

SudharakaP picture SudharakaP  Â·  3Comments