Spring Boot 3+Swagger +Spring Jersey - spring-boot

I am unable to locate the import of the following class while working with the Swagger part.
ApiListingResource
BeanConfig
Is there an adequate substitution of these classes in Jersey's swagger-based implementation?
this.register(ApiListingResource.class);
this.register(SwaggerSerializers.class);
BeanConfig config = new BeanConfig();
config.setConfigId("X Swagger ");
config.setTitle("X Swagger ");
config.setVersion("1.0.0");
config.setBasePath("api");
config.setResourcePackage("com.xyz");
config.setScan(true);

Related

How to make Spring Boot Reactive endpoints visible to SpringDoc OpenApi

I am working on a new Spring Boot reactive server application. The application exposes reactive endpoints as shown below:
#Configuration
public class XXXXRouter {
#Bean
public RouterFunction<ServerResponse> routes(ClaimsHandler handler) {
return nest(path("/api/xxxx"), nestedRoutes(handler));
}
private static RouterFunction<ServerResponse> nestedRoutes(xxxxHandler handler) {
return route(GET("/"), handler::allClaims)
.andRoute(GET("/{id}"), handler::byId)
.andRoute(GET("/{id}/notes"), handler::notesById);
}
}
I need to make these endpoints to swagger-ui like framework. I am using following dependencies to generate required swagger-ui and api-docs:
implementation 'org.springdoc:springdoc-openapi-webflux-core:1.2.32'
implementation 'org.springdoc:springdoc-openapi-webflux-ui:1.2.32'
I also have the following API config:
#Configuration
public class OpenAPIConfig {
#Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()).info(new Info().title("Contact Application API")
.description("This is a sample Spring Boot RESTful service using springdoc-openapi and OpenAPI 3."));
}
}
localhost:8080/swagger-ui.html shows swagger-ui page. But, endpoints are not shown there.
Here is the output from localhost:8080/v3/api-docs:
{"openapi":"3.0.1","info":{"title":"Contact Application API","description":"This is a sample Spring Boot RESTful service using springdoc-openapi and OpenAPI 3."},"servers":[{"url":"http://localhost:8080","description":"Generated server url"}],"paths":{},"components":{}}
My question is how do we make the reactive endpoints available to swagger-ui.html?

Adding authorization to Annotation-driven swagger.json with Jersey 2 and Spring Boot

I'm trying to add Basic Authentication to Swagger UI for a to a Swagger-annotated Jersey 2.0 web service built with Spring Boot. I'm using:
Spring Boot 1.5.4
spring-boot-starter-jersey
Swagger UI 3.0.4
(Maven package) swagger-jersey2-jaxrs 1.5.13
I'm able to generate a swagger.json file with the following JerseyConfig and with Swagger annotations on my Resources. This article was immensely helpful in getting this far.
#Component
public class JerseyConfiguration extends ResourceConfig {
private static Log logger = LogFactory.getLog(JerseyConfiguration.class);
#Value("${spring.jersey.application-path:/}")
private String apiPath;
public JerseyConfiguration() {
registerEndpoints();
configureSwagger();
}
private void registerEndpoints() {
register(MyEndpoints.class);
// Generate Jersey WADL at /<Jersey's servlet path>/application.wadl
register(WadlResource.class);
// Lets us get to static content like swagger
property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "((/swagger/.*)|(.*\\.html))");
}
/**
* Configure the Swagger documentation for this API.
*/
private void configureSwagger() {
// Creates file at localhost:port/swagger.json
this.register(ApiListingResource.class);
this.register(SwaggerSerializers.class);
BeanConfig config = new BeanConfig();
config.setConfigId("example-jersey-app");
config.setTitle("Spring Boot + Jersey + Swagger");
config.setVersion("2");
config.setContact("Me <me#example.com>");
config.setSchemes(new String[] {"http", "https"});
config.setResourcePackage("com.example.api");
config.setBasePath(this.apiPath);
config.setPrettyPrint(true);
config.setScan(true);
}
}
Now I want to be able to use Basic Authentication to connect to these services from Swagger UI. I've configured it in Spring and can use it to authenticate to the site, but not from Swagger UI.
Unfortunately, none of the Spring Boot examples currently on the Swagger sample site include Jersey and authentication, and none of the Jersey examples use Spring Boot and #SpringBootApplication like I'm using on in my project.
How do I get Basic Auth to show up in the Swagger UI?
I was able to get this to work by adding ServletConfigAware to JerseyConfiguration. Then I could use the same style of Swagger configuration used in the Swagger Bootstrap.java examples.
#Component
public class JerseyConfiguration extends ResourceConfig implements ServletConfigAware{
private ServletConfig servletConfig;
// ... this is all unchanged ...
/**
* Configure the Swagger documentation for this API.
*/
private void configureSwagger() {
// Creates file at localhost:port/swagger.json
this.register(ApiListingResource.class);
this.register(SwaggerSerializers.class);
BeanConfig config = new BeanConfig();
// ... this is all unchanged ...
config.setScan(true);
Swagger swagger = new Swagger();
swagger.securityDefinition("basicAuth", new BasicAuthDefinition());
new SwaggerContextService().withServletConfig(servletConfig).updateSwagger(swagger);
}
#Override
public void setServletConfig(ServletConfig servletConfig) {
logger.info("Setting ServletConfig");
this.servletConfig = servletConfig;
}
}
After making these changes, and adding annotations like the following to my endpoints:
#Api(value = "/api", description = "My super API",
authorizations = {#Authorization(value="basicAuth")})
#Path("api")
#Component
public class MyApi {
I saw the following changes:
Added to my swagger.json:
"securityDefinitions":{"basicAuth":{"type":"basic"}}
...
"security":[{"basicAuth":[]}]}}
Also, in Swagger UI, a new green button appeared in the same row as the Schemes dropdown, that says "Authorize" with an open lock on it. If I click on it, a popup shows up where I can enter the username and password. Now those credentials are sent to the API when I use the Swagger UI "Try It" feature.

Swagger 2 (Spring fox) adds 'es' to my API's

I was just trying to integrate Swagger into my Spring Boot (JAX-RS) project built with Gradle.I was able to generate a docker (Swagger UI) for the same as following :
I have configured my swagger with the default settings as follows :
package com.abc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#EnableAutoConfiguration
#SpringBootApplication
#EnableMongoRepositories
#Slf4j
#Import({springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration.class,springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration.class})
#EnableSwagger2
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
public static void run(String[] args) throws Exception{
log.info("Started application on: 8080");
}
}
As we can see in the image for GET Events API the docker shows /eventses .. So from where it has added es to /events API which is written as :
#GET
public HashMap<String, Object> getEventList(#DefaultValue("1") #QueryParam("page") int page,
#DefaultValue("10") #QueryParam("rpp") int rpp, #QueryParam("events") String eventIds) {
HashMap<String, Object> eventsResultMap= new HashMap<String, Object>();
List<Events> events = null;
if (eventIds != null && eventIds.length() > 0) {
List<String> eventsIdList = Arrays.asList(eventIds.split(","));
log.info("" + eventsIdList);
events = eventService.getEvents(eventsIdList);
} else {
events = eventService.getEvents(page - 1, rpp);
}
eventsResultMap.put("EVENTS", events);
HashMap<String, Object> recordsMetaMap = new HashMap<String, Object>();
recordsMetaMap.put("total", eventService.totalCount());
recordsMetaMap.put("page", page);
recordsMetaMap.put("rpp", rpp);
eventsResultMap.put("_metadata", recordsMetaMap);
log.info("The events you have queried for are:" + eventsResultMap);
return eventsResultMap;
}
Please, guide me where I am doing wrong.What custom configs need to be done.
I have taken Reference from spring official documentation.
Everything in /eventses comes from Springfox's support for Spring Data REST and has nothing to do with the getEventList method in your controller. If you don't want to have auto-discovery of your entities like that, removing the class from the #Import line should do the trick.
If you are using a jax-rs implementation with spring boot, you should use swagger-core jax-rs libraries rather than spring fox. Swagger team has provided very detailed instructions here on how to configure your application for different implementations like jersey, rest-easy etc. I found it very easy to integrate for jersey 2.x.
To make your swagger documentation rich, you should try to provide as much meta data as you can using different swagger annotations as documented here. Swagger makes great use of these annotations combined with jax-rs annotations in some cases (E.g. QueryParam vs PathParam identification).
If you let me know which jax-rs implementation you are using, I might be able to provide you some sample configuration.
Edit:
For Jersey 2.x you will need to add something like this in your Jersey Configuration class (which extends org.glassfish.jersey.server.ResourceConfig):
#Bean
public BeanConfig swaggerConfig() {
register(ApiListingResource.class);
register(SwaggerSerializers.class);
BeanConfig config = new BeanConfig();
config.setConfigId("your-config-id");
config.setTitle( "Your Title" );
config.setSchemes(new String[] { "https", "http" });
config.setBasePath("your application base path E.g. /api");
config.setResourcePackage("package to be scanned E.g. com.example");
config.setPrettyPrint(true);
config.setScan(true);
return config;
}
Other than that, you will need to annotate your endpoint(service) classes with swagger annotations. E.g.
#Path("/material")
#Service
#Api(value = "Material")
public class MaterialEndpoint {
#POST
#ApiOperation(value = "Create Material")
#ApiResponses(value = { #ApiResponse(code = 201, message = "Success", response = CreateMaterialResponse.class),
#ApiResponse(code = 409, message = "Failure", response = ErrorResponse.class) })
public Response createMaterial(CreateMaterialRequest createMaterialRequest){
// Code goes here
}
}
And your entities with swagger annotations. It is upto you how rich you want your swagger documentation to be. Depending on that you can choose to annotate more or less classes.

Java configuration for SAAJInInterceptor and WSS4JInInterceptor beans

I have a web application that provides a soap web service using apache cxf and spring boot. So I have no xml file in my classpath to configure my beans, they are all configured in java configuration.I would like to set up authentication with ws-security from cxf.
So I would like to know if there are java configurations for the SAAJInInterceptor and WSS4JInInterceptor beans for example like this:
#Bean
public ServletRegistrationBean cxfServlet() {
ServletRegistrationBean servlet = new ServletRegistrationBean(new CXFServlet(), "/services/*");
servlet.setLoadOnStartup(1);
return servlet;
}
You just have to add the interceptor when you create your endpoint :
Map<String,Object> interceptorConfig = new HashMap<String,Object>();
// set the properties of you WSS4J config
// ...
WSS4JInInterceptor myInterceptor = new WSS4JInInterceptor(interceptorConfig);
myEndpoint.getInInterceptors().add(myInterceptor);
Another solution is by using annotation with #InInterceptors

Spring + Apache CXF: SearchContextProvider not initialized

I'm integrating Spring Boot with Apache CXF. Everyhthing is OK, but I cannot get the SearchContext to work inside the controllers:
#Context
private SearchContext context;
public #ResponseBody List<Users> getAll(#Context SearchContext context, #RequestParam String search){
....
}
The SearchContext is not correctly injected, as is not created by the SearchContextProvider in the package org.apache.cxf.jaxrs.ext.search.
I'm launching the CXF Servlet with this Bean:
#Bean
public ServletRegistrationBean cxfServlet() {
CXFServlet cxf = new CXFServlet();
ServletRegistrationBean registration = new ServletRegistrationBean(cxf, "/api/*");
return registration;
}
I'm using a Java-based configuration, no XML.
In an XML based configuration, it seems that this tag is required:
<jaxrs:providers>
<bean class="org.apache.cxf.jaxrs.ext.search.SearchContextProvider"/>
</jaxrs:providers>
How can I declare the provider in a Java based configuration of the servlet?
In your main config class, add:
#ComponentScan("org.apache.cxf.jaxrs")
Since the class (SearchContextProvider) is already annotated with #Provider annotation, Spring will be able to pick it up if it is being scanned. Assuming that you are already doing component-scan on your own package, you can just add the jaxrs package like:
#ComponentScan({ "com.something", "org.apache.cxf.jaxrs" })

Resources