Adding OkHttp custom interceptor to Feign client - java

I'm having problems to set up a global OkHttp interceptor for my #FeignClient beans. I'm not experiencing any error, but the interceptor is being ignored.
My understanding is that Spring Cloud's auto configuration should pick the OkHttpClient.Builder bean that I'm declaring and use it to create the underlying OkHttpClient instances, but I might be wrong about this.
Here are the relevant parts of my Spring app:
#SpringBootApplication
#EnableFeignClients(defaultConfiguration = FeignConfig.class)
#EnableCircuitBreaker
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class);
}
}
#Configuration
public class FeignConfig {
#Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
#Bean
public OkHttpClient.Builder okHttpClientBuilder(MyInterceptor interceptor) {
return new OkHttpClient.Builder().addInterceptor(interceptor);
}
}
public class MyInterceptor implements okhttp3.Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
System.out.println("Hey there, this is my request: " + request);
Response response = chain.proceed(request);
System.out.println("Hey there, this is my response: " + response);
return response;
}
}
The intercept method above is never called. I need MyInterceptor to be a Spring bean, because I need to inject other dependencies to it.
#FeignClient(name = "myClient", fallback = MyClientFallback.class)
public interface MyClient {
// method declarations
}
#Component
public class MyClientFallback implements MyClient {
// method fallback implementations
}
Here's the relevant part of my application.properties file:
feign.hystrix.enabled = true
feign.okhttp.enabled = true
ribbon.eureka.enabled = false
ribbon.eager-load.enabled = true
ribbon.eager-load.clients = myClient
myClient.ribbon.listOfServers = <IP_LIST>
myClient.ribbon.ServerListRefreshInterval = 10000
As you see from the properties declared above, I'm not using Eureka and I'm using Ribbon to load balance my rest client. I'm also using Hystrix to enable fallback responses and I have set the feign.okhttp.enabled property to true.
Below is the info about dependecies config and versions...
Spring Boot version is 2.0.3.RELEASE and Spring Cloud version is Finchley.SR1, while OkHttp version is 3.11.0.
In my pom.xml file, I have this spring-cloud-dependencies config:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
I have also included the following Spring Boot and Spring Cloud dependencies, along with the OkHttp dependency:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
...
</dependencies>

You should provide an OkHttpClient bean as stated in the doc:
The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP.
https://github.com/OpenFeign/feign/blob/master/okhttp/src/main/java/feign/okhttp/OkHttpClient.java

The solution is to let Spring auto configuration do its job.
In order for that to happen, the following dependency must be removed from the pom.xml file:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
And the following one must be manually included:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
Once this is done, everything works as expected with the provided configuration.

Solution is to use OkHttpClient. Add pom.xml dependencies:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
and configure a bean:
#Configuration
public class FeignConfiguration {
#Bean
public OkHttpClient client() {
return new OkHttpClient();
}
}
Explanation: For 401, 407 and some other HTTP-status responses, bodies are replaced with null by HTTP clients used in Open Feign by default.
From OpenFeign: Currently in the feign.Default client there is a streaming mode enabled. You can see in the sun.net.www.protocol.http.HttpURLConnection following lines of code :
if (respCode == HTTP_UNAUTHORIZED) {
if (streaming()) {
disconnectInternal();
throw new HttpRetryException (RETRY_MSG2, HTTP_UNAUTHORIZED);
}
}
So if the streaming is enabled and you have 401 HTTP response code you will get empty errorStream, because there is no initialization. The feign client will try to get the errorStream as a body because there is a check
if (status >= 400) {
stream = connection.getErrorStream();
} else { stream = connection.getInputStream(); }

Related

How to return just a String using Webflux - webclient?

I would like to make this call and return a string
but I'm having this error:
"java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking,
which is not supported in thread reactor-http-nio-3"
I dont understand why am I doing wrong?
WebClient supports asynchronous as well as synchronous calls.
This a springboot project with just 3 dependencies.
How can I return just a string like a normal synchronous call?
#RestController
public class HomeController {
#GetMapping("/")
public String home() {
String resp = webclient.get()
.uri(ANY_URL).retrieve()
.bodyToMono(String.class)
.block();
return resp;
}
}
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Thanks.
Fixed by adding spring-boot-starter-web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Not sure what is your goal but the whole idea of Webflux is to create non-blocking reactive services. WebClient support both async and sync usage but the error you are getting is from reactive controller. There is no reason to block in your example - just change return type from String to Mono<String>.
#GetMapping("/")
public Mono<String> home() {
String resp = webclient.get()
.uri(ANY_URL).retrieve()
.bodyToMono(String.class);
}
The intuition behind this is
use spring-boot-starter-webflux and WebClient in async mode to create reactive services. Controller should return Mono or Flux. The caveat here is that your logic should be reactive (async) end-to-end to get full advantage of the Reactive API.
add spring-boot-starter-web if you want to build non-reactive service and just use WebClient in sync (blocking) mode as your Http client.

Problem in integrating spring boot application with Keycloak

I want to integrate Keycloak with spring boot application. The problem is that at the end, I got 403 forbidden error when calling the protected endpoints.
Following is my decoded JWT token, which is issued by Keycloak. I have a client, which is named clientApp1, and a realm role, which is named clientApp1User and mapped to the created user. Following is my decoded JWT token:
{
alg: "RS256",
typ: "JWT",
kid: "ZWDbgcSI8nD2Yq4LA6hxYcsTbnf6y6Zj8PKyUobE_qE"
}.
{
exp: 1666444432,
iat: 1666444132,
jti: "e6883855-ef20-4fac-95dd-8f13bd0ae552",
iss: "http://localhost:12500/auth/realms/sampleRealm",
aud: "account",
sub: "80e1e45f-49fb-4a5a-9a60-b0057d291c53",
typ: "Bearer",
azp: "clientApp1",
session_state: "c22af762-7be9-4150-94d5-8bd35065ac57",
acr: "1",
allowed-origins: [
"http://localhost:11501"
],
realm_access: {
roles: [
"clientApp1User",
"offline_access",
"uma_authorization",
"default-roles-samplerealm"
]
},
resource_access: {
account: {
roles: [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
scope: "email profile",
sid: "c22af762-7be9-4150-94d5-8bd35065ac57",
email_verified: false,
name: "user1FirstName User1LastName",
preferred_username: "user1",
given_name: "user1FirstName",
family_name: "User1LastName"
}.
[signature]
Moreover, here is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ResourceServerSample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ResourceServerSample</name>
<description>ResourceServerSample</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Since, I want to use Security annotations to secure my end points I have set the security configuration as following:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
public class SecurityConfig {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.anyRequest().permitAll()
.and().oauth2ResourceServer().jwt();
http.csrf().disable();
return http.build();
}
Finally, in order to protect my endpoints I have used annotations like following:
#RestController
public class TestControllers {
// Public endpoint
#GetMapping("/welcome")
public ResponseEntity<String> welcome() {
return ResponseEntity.status(HttpStatus.OK).body("Welcome to the unprotected endpoint");
}
// #RolesAllowed("clientApp1User")
// #Secured("clientApp1User")
#PreAuthorize("hasAuthority('clientApp1User')")
#GetMapping("/clientApp1User")
public ResponseEntity<String> clientApp1User() {
return ResponseEntity.status(HttpStatus.OK).body("clientApp1User protected endpoint sends its regards");
}
#PreAuthorize("hasAuthority('SCOPE_email')")
#GetMapping("/testScope")
public ResponseEntity<String> testScope() {
return ResponseEntity.status(HttpStatus.OK).body("testScope protected endpoint sends its regards");
}
}
The problem that I face is that the endpoint, which is protected with #RolesAllowed("clientApp1User") or #Secured("clientApp1User") or #PreAuthorize("hasAuthority('clientApp1User')") returns 403 forbidden, when it's called with a valid access token.
On the other hand endpoints with annotations like #PreAuthorize("hasAuthority('SCOPE_email')") or #PreAuthorize("hasAuthority('SCOPE_profile')") return 200 Ok.
I believe spring boot can not accurately parse the JWT token and only excepts values in scope claim with the prefix <SCOPE_> and as an authority.
Can any one help me to fix the problem and use the RolesAllowed/Secured/PreAuthorize annotations to secure the endpoint with declared roles in realm_access and resource_access claims?
Roles are private claims: it is neither in OAuth2 nor OpenID specs and each authorization-server provider uses its own.
You have to provide your own Converter<Jwt, AbstractAuthenticatonToken> #Bean to map authorities from realm_access.roles (and maybe resource_access.clientApp1.roles if you enable client level roles in Keycloak) to everride Spring-boot default which turns Jwt into JwtAuthenticationToken (which can be fine) with authorities mapped from scope claim, adding SCOPE_ prefix (which is not what you want).
Complete samples here: https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials which cover various servlets scenarios with #controller tests.
For reactive apps or secured #Service & #Repository tests, see in https://github.com/ch4mpy/spring-addons/tree/master/samples (but it contain less explanations than tutorials, so start with tutorials and move up to samples for your exact use-case)
Sample
With the help of spring-boot 3 starters from the repo linked above, configuration for Keycloak can be as simple as (just adapt properties for any other OIDC provider):
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<!-- depending on your use-case, you might replace !-->
<!-- "webmvc" with "webflux" (for reactive apps) and !-->
<!-- "jwt" with "introspecting" (for access-token introsepection instead of JWT decoding) -->
<artifactId>spring-addons-webmvc-jwt-resource-server</artifactId>
<version>6.0.4</version>
</dependency>
#Configuration
#EnableMethodSecurity()
public class SecurityConfig {
}
#This illustrates configuration for accepting identities from both
# a Keycloak instance with authorities mapped from realm_access.roles and resource_access.account.roles
# an Auth0 domain with authorities mapped from roles and permissions
com.c4-soft.springaddons.security.issuers[0].location=https://localhost:8443/realms/master
com.c4-soft.springaddons.security.issuers[0].authorities.claims=realm_access.roles,resource_access.account.roles
com.c4-soft.springaddons.security.issuers[1].location=https://dev-ch4mpy.eu.auth0.com/
com.c4-soft.springaddons.security.issuers[1].authorities.claims=roles,permissions
com.c4-soft.springaddons.security.cors[0].path=/**
com.c4-soft.springaddons.security.cors[0].allowed-origins=https://localhost,https://localhost:8100,https://localhost:4200
com.c4-soft.springaddons.security.permit-all=/actuator/health/readiness,/actuator/health/liveness,/welcome
Bonus
As already spoiled, in tutorials and samples, you'll see how to mock OAuth2 identities (with authorities) during unit and integration tests.
#WebMvcTest(controllers = SampleController.class)
#AutoConfigureAddonsWebSecurity // this is required only if you use one of the starters above
#Import({ SecurityConfig.class })
class SampleControllerTest {
#Test
void whenAnonymousThenGetWelcomeIsOk() throws Exception {
mockMvc.perform(get("/sample")).andExpect(status().isOk());
}
#Test
void whenAnonymousThenGetClientApp1UserUnauthorized() throws Exception {
mockMvc.perform(get("/clientApp1User")).andExpect(status().isUnauthorized());
}
#Test
#WithMockJwtAuth("clientApp1User")
void whenClientApp1UserThenGetClientApp1UserOk() throws Exception {
mockMvc.perform(get("/clientApp1User")).andExpect(status().isOk());
}
}
You can have a look at this example on github.
The problem right now is that you need to add your roles to the Security Context of Spring Boot.
public static class CustomJwtConfigure implements Converter<Jwt, JwtAuthenticationToken> {
#Override
public JwtAuthenticationToken convert(Jwt jwt) {
var tokenAttributes = jwt.getClaims();
var jsonObject = (JSONObject) tokenAttributes.get(REALM);
var roles = (JSONArray) jsonObject.get(ROLES);
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
roles.forEach(role -> grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role)));
return new JwtAuthenticationToken(jwt, grantedAuthorities);
}
}
Link to github account

I got this message: Cannot construct instance of `reactor.core.publisher.Mono`

I used Jersey and Webflux with R2DBC. after send the POST via the postman I got this message " Cannot construct instance of reactor.core.publisher.Mono "
This is my JerseyConfiguration:
#Component
public class JerseyConfiguration
extends ResourceConfig {
public JerseyConfiguration() {
register(ProductController.class, 1);
}
}
and this is my Controller:
#Path("/v1")
#Controller
public class ProductController {
#Autowired
private ProductService productService;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/product")
public Mono<Product> createProduct(#RequestBody Mono<Product> productMono){
return productMono.flatMap(this.productService::createProduct);
}
}
and this sis my service:
#Service
public class ProductService {
#Autowired
private ProductRepository repository;
public Mono<Product> createProduct(final Product product){
return this.repository.save(product);
}
}
and also this my pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Now, this is my problem; I got this message from the postman:
Cannot construct instance of `reactor.core.publisher.Mono` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
Please let me know how to solve that problem.
Thank you
You cannot mix WebFlux and Jersey. You should choose one or the other, not both. They both provide an HTTP server engine, but:
Jersey is a Servlet JAX-RS implementation, it does not know anything about reactive streams, Mono, Flux, etc.
Webflux is the Spring HTTP server engine based on reactive streams and async Netty HTTP server.
If you look at Spring Boot reference documentation, section 3.5: Web, you will see that Jersey is one of the available engines, competing with other possible engines, i.e Web MVC and web reactive (webflux).
So, the answer is : Jersey is incompatible with Webflux, and you must choose between Webflux reactive Web and Spring rest annotation, or Jersey and Jax_RS without using Mono/Flux as return-type.
Note 1 : You should annotate your class with #RestController whe using webflux, so it understand that method return is the HTTP response body (see the last paragraph of reference documentation section 1.4.1: #Controller for details.
Note 2 : If you really want to use jersey, but you still require to consume Mono objects from other parts of your system, you might use one of the conversion functions provided by Reactor to return an object that jersey can work with. For example, on Mono object, you will find a toFuture() method. You could also block(), but it could be dangerous.

JMSListener annotation is not working along with REST service

I am using "Spring Boot - 2.1.5.RELEASE" and "Spring framework - 5.1.7.RELEASE".
JMS listener annotation is not picking a message from a MQ queue. No error logs are rolling in my IntelliJ IDEA as well.
About my project - I am exposing a REST service which sends and receives a message from MQ (used JMSTemplate annotation). Till now it was working. Now I have to add another class which should listen for a queue. Hence added #JMSListener annotation which is not picking any message. Any insight will be really helpful.
The pom has below specified dependencies.
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mq-jms-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
The class has below specified method.
import org.springframework.jms.annotation.JmsListener;
#Component
public class PickMyMessage {
#JmsListener(destination = "IN",containerFactory = "myFactory")
public void pullMyMessaage(String message){
System.out.println("Message is pulled..");
}
}
My main application has #EnableJMS annotation. In my application.yml file I have given below information.
ibm:
mq:
channel: MY.APP.SVRCONN
connName: 192.168.0.1(1415)
password: Pswd
queueManager: QM01
user: appsrv
My Bean class configs are
My JMS connection factory as below.
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
}
Not sure what else I am missing here. Any insight will be really helpful.
Instead of my existing project, if i create any simple demo project it is working as expected.
The class PickMyMessage is not a Spring bean, that's why Spring ignores it. Declare it as a #Bean or as a #Component.
May be there are further problems. But this is the first one that needs to be resolved.

Spring Boot 2.2.4 application, using Swagger

I have a REST application using Spring Boot 2.2.4.RELEASE.
My REST controller is annotated like
#RestController
#RequestMapping("/")
My REST controller has #GetMapping, #PostMapping, etc., it works as expected.
Now I want to integrate Swagger in latest version.
https://github.com/swagger-api/swagger-core
https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Getting-started
The Maven dependencies shown there I added to my pom.xml:
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-core</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-integration</artifactId>
<version>2.1.1</version>
</dependency>
According to the 'Getting Started', just by adding the dependencies I should see the generated OpenAPI at http://localhost:8080/openapi.json but nothing shows up there.
Is Swagger (swagger-core,... in version 2.1.1) usable with Spring Boot web applications?
There is a project SpringFox, but it is not up to date. Also springdoc-openapi is available. But using Swagger directly would be my first thought.
You'll need a SwaggerConfig file in your code.
Configuration needed in Swagger for Java goes like this:
(Note that this is just the basic File and you can Configure it however you want.)
#EnableSwagger2
#Configuration
public class SwaggerConfig {
public static String bucketName;
#Value("${swagger.config.basePackage}")
public void setName(String name) {
bucketName = name;
}
#Bean
public Docket classifiedApi()
{
ArrayList<ApiKey> apiKeys=new ArrayList<>();
apiKeys.add(apiKey());
return new Docket(DocumentationType.SWAGGER_2).securitySchemes(apiKeys)
.select()
.apis(RequestHandlerSelectors.basePackage(bucketName))
.build()
.apiInfo(metaData());
}
private ApiKey apiKey() {
return new ApiKey("Api Key", Constants.JWTToken.API_KEY, "header");
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("APPNAME REST API")
.description("Spring Boot REST API for APPNAME")
.contact(new Contact("YOURNAME ", "Coming Soon ...", "CONTACT ADDRESS"))
.build();
}
}

Categories

Resources