How to add /api before swagger-ui.html - spring-boot

How to add default parameter before swagger-ui.html
Like this:
http://localhost:8080/api/swagger-ui.html
What I have integrated so far:
Pom.xml:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
SwaggerConfig.java:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
Do I have to map "swagger-ui.html" to something with #RequestMapping?

Try this:
new Docket(DocumentationType.SWAGGER_2)
.host("www.mydomain.com")
.pathProvider(new RelativePathProvider(servletContext) {
#Override
public String getApplicationBasePath() {
return "/myapi";
}
});
in case you run into any issues: https://github.com/springfox/springfox/issues/1443

Include the following annotations at class level in SwaggerConfig.java:
#PropertySource("classpath:swagger.properties") and
#ComponentScan
Then create the swagger.properties file in the resources directory (same location as your application.properties file)

Related

In my SpringBoot app I keep getting error 403 on /swagger-ui

I know this may be a duplicated question but I've already tried all the solutions on the existing ones. In my project I have imported these dependencies:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
I configure swagger with this class:
#Configuration
#EnableSwagger2
#EnableWebMvc
public class SwaggerConfiguration implements WebMvcConfigurer{
#Bean
public Docket api() {
var logger = LoggerFactory.getLogger(SwaggerConfiguration.class);
logger.info("configuring swagger");
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
I have both .antMatchers("/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**" ,"/swagger.json").permitAll()
and web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**");
because the internet couldn't make up it's mind on which should be used, but nothing works, if I go at /v2/api-docs I get some json wall-text with all my endpoints tho

swagger UI doesn't show apis while all configuration seems to be right

I have a springboot helloword project, the structure isstructure of project
and my swaggerConfig is
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//.enable(false)
.select()
.apis(RequestHandlerSelectors.basePackage("org/jayden/swaggertest/controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SpringBoot and Swagger2")
.description("desc")
.termsOfServiceUrl("http://localhost:8080/")
.version("1.0.0")
.build();
}
}
My controller is:
#RestController
#RequestMapping("/user")
#Api(value = "testApi", tags = "test")
public class UserController {
/**
* #param
* #return
*/
#PostMapping(value = "/save")
#ApiImplicitParam(name = "user", value = "addUser")
#ApiOperation(value = "addUser", notes = "addUserByParm")
public String saveUser(){
return "added";
}
I use porm.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
Could you please tell me what mistake I've made.
I've got the wrong message from swagger-ui:
wrong message from swagger-ui
I've got wrong message from console in chrome:
wrong in chrome console
This is my first time to ask question on stackOverflow, sorry for any unclear descriptions. Thank you guys!
You can try
RequestHandlerSelectors.basePackage("org/jayden/swaggertest/controller")
instead of
RequestHandlerSelectors.basePackage("org.jayden.swaggertest.controller")

Spring Boot application is ignoring hikaricp config

I'm new to stackoverflow, but read tons of posts here and now stuck.my application.properties is read, but the portion for configuring hikaricp is ignored/has no effect.
I read https://www.javadevjournal.com/spring-boot/spring-boot-hikari/ and folowed those steps there, still any success.
pom.xml
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.4.10.Final</version>
<exclusions>
<exclusion>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>5.4.10.Final</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
<version>2.2.2.RELEASE</version>
</dependency>
application.properties
spring.cache.jcache.config=classpath:ehcache.xml
spring.datasource.jdbc-url=jdbc:postgresql://VOC-APP202-db:5432/voice-app
spring.datasource.username=vocapp202
spring.datasource.password=******
srping.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.connectionTimeout=1000
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.maxLifetime=60000
spring.datasource.hikari.connectionTestQuery=SELECT * FROM table where id=1
spring.datasource.hikari.minimumIdle=1
spring.datasource.hikari.maximumPoolSize=5
spring.datasource.hikari.poolName=voiceapp-db-pool
spring.datasource.hikari.autoCommit=false
BlacklistApplication.class:
package de.mycompany.voice.blacklist_ng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
#SpringBootApplication
#EnableJpaAuditing
#EnableCaching
#Configuration
public class BlacklistngApplication {
public static void main(String[] args) {
SpringApplication.run(BlacklistngApplication.class, args);
}
}
Config class:
#Configuration
#ConfigurationProperties("spring.datasource")
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = {"de.firsttelecom.voice.blacklist_ng.repository.vocapp202"}
)
public class VocApp202DbConfig extends HikariConfig {
#Primary
#Bean(name = "dataSource")
public DataSource dataSource() {
return new HikariDataSource(this);
}
What I'm missing?
spring.datasource.hikari.* (and also spring.datasource.url) properties will work only if you are using Spring Boot DataSource autoconfiguration. In order to achieve it, you need to remove this bean:
#Primary
#Bean(name = "dataSource")
public DataSource dataSource() {
return new HikariDataSource(this);
}
Spring Boot will create it for you automatically using all these properties. You can check DataSourceAutoConfiguration.class for more information.
If, for some reason, you cannot remove this bean (f.e., you have another bunch of datasources, and you need to create your manual datasource in order to mark it as #Primary), you can use "raw" properties to configure hikari. So, instead of removing dataSource() method, you should modify your properties by removing hikari. part:
...
spring.datasource.jdbc-url=jdbc:postgresql://VOC-APP202-db:5432/voice-app
...
spring.datasource.connectionTimeout=1000
spring.datasource.idleTimeout=30000
spring.datasource.maxLifetime=60000
spring.datasource.connectionTestQuery=SELECT * FROM table where id=1
spring.datasource.minimumIdle=1
spring.datasource.maximumPoolSize=5
spring.datasource.poolName=voiceapp-db-pool
spring.datasource.autoCommit=false
jdbc-url is also hikari-specific property, that's why it works now.
To summarize: properties without hikari. and with jdbc-url for manually created datasource beans, and properties with hikari. and url for Spring Boot DataSource autoconfiguration.
If you're already using application.properties file with hikari and datasource configuration, the moment you use new HikariDataSource(this) it will override your application.properties values.
You either create your HikariDataSource manually and remove from application.properties:
#Bean(name = "dataSource")
public DataSource dataSource() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setMaximumPoolSize(5);
hikariDataSource.setMaxLifetime(60000);
hikariDataSource.setMinimumIdle(1);
//.. some other configs
return hikariDataSource;
}
or use application.properties values only.
but something did not work with application.properties, so I now did:
DbConfig.class(es)
#Primary
#Bean(name = "dataSource")
public DataSource dataSource() {
HikariConfig config = new HikariConfig("/hikari_voiceapp.properties");
//HikariDataSource dataSource = new HikariDataSource(config);
return new HikariDataSource(config);
}
and specify all params to each database in separate hikari.properties file including the name of database:
hikari_asterisk.properties
hikari_billing.properties
hikari_voiceapp.properties
works for me.
To keep configuration in standard format, and still create DataSource explicitly, connection pool specific prefix can be used for configuration properties. This is the same what spring boot DataSourceConfiguration does when auto-configuration is used:
#Bean
#Primary
#ConfigurationProperties(prefix = "spring.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariDataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
Sample application.yaml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/postgres?gssEncMode=disable
username: postgres
password: postgres
hikari:
minimumIdle: 0
maximumPoolSize: 50
idleTimeout: 90000
maxLifetime: 900000
connectionTimeout: 45000
leakDetectionThreshold: 45000
I used the following approach
second.datasource.jdbc-url=jdbc-url
second.datasource.username=username
second.datasource.password=password
.
.
.
.
=================== In Java Configuration File ==================
#Bean(name = "secondDataSource")
#ConfigurationProperties(prefix = "second.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(EntityManagerFactoryBuilder builder,
#Qualifier("secondDataSource") DataSource dataSource) {
Map<String, String> props = new HashMap<String, String>();
props.put("spring.jpa.database-platform", "org.hibernate.dialect.Oracle12cDialect");
.
.
.
return builder.dataSource(dataSource).packages("com.second.entity").persistenceUnit("secondDB")
.properties(props)
.build();
}
#Bean(name = "secondTransactionManager")
public PlatformTransactionManager secondTransactionManager(
#Qualifier("secondEntityManagerFactory") EntityManagerFactory secondEntityManagerFactory) {
return new JpaTransactionManager(secondEntityManagerFactory);
}

Swagger 2 + spring integration

I'm trying to expose rest API with Spring Integration and document it with swagger. Is it even possible ? I cannot find any docs or example to make it work.
My swagger docket bean:
Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
And simple flow:
#Bean
public IntegrationFlow inbound() {
return IntegrationFlows.from(Http.inboundGateway("/foo")
.requestMapping(m -> m.methods(HttpMethod.GET))
.requestPayloadType(String.class))
.channel("httpRequest")
.get();
}
I use spring boot:2.0.1 and springfox-swagger2 : 2.8.0
Thank in advance,
Mateusz
Spring Integration is currently not supported by springfox, although they have provided a generalization which seems to make it possible, based upon IntegrationRequestMappingHandlerMapping:
https://github.com/springfox/springfox/issues/550
They are asking for a PR which would implement this:
https://github.com/springfox/springfox/issues/797
This is my sample code.
Maven
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
Configuration
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.ant("/open/api/**")).build();
}
}

Error while connecting to AWS SQS from spring boot

I am trying to integrate AWS SQS into my springboot app using spring cloud AWS, but keep getting this error(posted below), can someone help?
Here are my files.
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'simpleMessageListenerContainer' defined in
class path resource
[org/springframework/cloud/aws/messaging/config/annotation/SqsConfiguration.class]:
Invocation of init method failed; nested exception is
java.lang.NoSuchMethodError:
com.amazonaws.http.ExecutionContext.setCredentials(Lcom/amazonaws/auth/AWSCredentials;)V
#Configuration
public class AWSConfig {
#Value("${amazon.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
#Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
#Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
#Value("${amazon.sqs.endpoint}")
private String amazonSqsEndpoint;
#Bean
#Primary
public AmazonSQSAsyncClient amazonSQSAsyncClient() {
AmazonSQSAsyncClient amazonSQSAsyncClient = new AmazonSQSAsyncClient(amazonAWSCredentials());
if (!StringUtils.isEmpty(amazonSqsEndpoint)) {
amazonSQSAsyncClient.setEndpoint(amazonSqsEndpoint);
}
return amazonSQSAsyncClient;
}
#Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
}
}
I am able to work with dynamodb with this but not able to connect to SQS.
I have given the correct access key, secret access key and end point in application.properties file.
#Component
#EnableSqs
public class SQSDao {
private static final Logger logger = LoggerFactory.getLogger(SQSDao.class);
private QueueMessagingTemplate queueMessagingTemplate;
#Autowired
public SQSDao(AmazonSQSAsync amazonSqs) {
this.queueMessagingTemplate = new QueueMessagingTemplate(amazonSqs);
}
public void send(String message) {
System.out.println(queueMessagingTemplate.getDefaultDestination());
queueMessagingTemplate.convertAndSend("test-queue", MessageBuilder.withPayload(message).build());
}
#SqsListener(value = "test-queue", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void receive(String message)
{
System.out.println("message: " + message);
}
}
I was facing the same issue as described. My solution requeried implement some extra methods for the Config class:
imports [...]
#Configuration
#RefreshScope
public class SpringCloudSQSConfig {
#Value("${cloud.aws.credentials.accessKeyId:default}")
private String accessKeyId;
#Value("${cloud.aws.credentials.secretKey:default}")
private String secretKey;
#Value("${cloud.aws.region.static:default}")
private String region;
private Logger logger = LoggerFactory.getLogger(this.getClass());
#Bean
public QueueMessagingTemplate queueMessagingTemplate() {
return new QueueMessagingTemplate(amazonSQSAsync());
}
public AmazonSQSAsync amazonSQSAsync() {
return AmazonSQSAsyncClientBuilder.standard().withRegion(Regions.US_EAST_2)
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKeyId, secretKey)))
.build();
}
#Bean
public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory() {
SimpleMessageListenerContainerFactory msgListenerContainerFactory = new SimpleMessageListenerContainerFactory();
msgListenerContainerFactory.setAmazonSqs(amazonSQSAsync());
return msgListenerContainerFactory;
}
#Bean
public QueueMessageHandler queueMessageHandler() {
QueueMessageHandlerFactory queueMsgHandlerFactory = new QueueMessageHandlerFactory();
queueMsgHandlerFactory.setAmazonSqs(amazonSQSAsync());
QueueMessageHandler queueMessageHandler = queueMsgHandlerFactory.createQueueMessageHandler();
List<HandlerMethodArgumentResolver> list = new ArrayList<>();
HandlerMethodArgumentResolver resolver = new PayloadArgumentResolver(new MappingJackson2MessageConverter());
list.add(resolver);
queueMessageHandler.setArgumentResolvers(list);
return queueMessageHandler;
}
}
And for the dependencies implemented:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws-messaging</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
and adding the next property in the properties file:
spring.main.allow-bean-definition-overriding=true
I was able to fix this problem by adding the last line shown to my application.yml during local testing
spring:
autoconfigure:
exclude:
- org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
I resolved it by removing duplicate dependencies :
aws-xray-recorder-sdk-aws-sdk
aws-xray-recorder-sdk-aws-sdk-v2
aws-xray-recorder-sdk-aws-sdk-instrumentor
aws-xray-recorder-sdk-aws-sdk-v2-instrumentor
Before :
<!-- AWS X-Ray -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-aws-sdk-v2</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-spring</artifactId>
</dependency>
After:
<!-- AWS X-Ray -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-aws-sdk-v2</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-xray-recorder-sdk-spring</artifactId>
</dependency>
Fixed it, apparently issue was related to dependency mix up as mentioned here

Resources