Spring boot unable to connect redis client Jedis to pool: Connection refused - spring-boot

I'm new to Spring boot development and all I want is to enable a Session for an Admin user. I'm writing a REST stateless (API) and a stateful service and I'm following a tutorial which is using redis in-memory-database for storing user sessions. I'm already using MySQL/JDBC for storing other data. Using redis and jdbc doesn't conflict?
In order to enable user session, I made the following:
These are the dependencies that I have added lately:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
Creating a Jedis Connection Factory:
#Configuration
#EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
#Bean
public JedisConnectionFactory jedisConnectionFactory() {
return new JedisConnectionFactory();
}
}
And the secured http configuration:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin").password("password").roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers("/").hasRole("ADMIN")
.anyRequest().authenticated();
}
}
I have also added the redis connection hostname and port in the application.properties:
# ===============================
# = REDIS
# ===============================
spring.redis.host=localhost
spring.redis.port=6379
However, when I run the application, the following error is thrown:
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at redis.clients.jedis.Connection.connect(Connection.java:184)
... 35 common frames omitted
I have tried to change localhost to 192.168.1.2 (my PC's local IP), tried to change the port but the connection is still refused.
This is the stacktrace first line:
[restartedMain] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
I don't know what else I could do. I'm having an antivirus (Windows). Should I disable it? Should I disable the firewall? Should I scan the ports to see what ports are opened?
Edit:
I have already tried using redis standalone configuration to pass the hostname and the port, but still can't connect:
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
#Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("127.0.0.1", 6379);
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
}

Configure the Jedis' connection pool:
spring:
redis:
client-type: jedis
jedis:
pool:
enabled: true
max-active: 4
max-idle: 4
max-wait: -10ms
min-idle: 0

If it is localhost. Try with 127.0.0.1:****
Sometimes using ip (192.168.x.x) can give errors ...
# ===============================
# = REDIS
# ===============================
spring.redis.host=127.0.0.1
spring.redis.port=6379

Related

How to configure embeded mongodb to run in given port in spring boot

I want to use embedded mongoDB with Spring boot for my development and testing. When I try to configure its getting started but always run with dynamic port instead of port which I give in URL config. Idea is I want to use same kind of MongoConfig for both my test (Unit/Integration) and real environment.
My property file looks below.
spring:
profiles: local
data:
mongodb:
uri: mongodb://localhost:62309/local_db
#Configuration
public class MongoDBConfig {
private final Environment env;
public MongoDBConfig(Environment env) {
this.env = env;
}
#Bean
public MongoDbFactory getMongoFactory() {
return new SimpleMongoClientDbFactory(env.getProperty("spring.data.mongodb.uri"));
}
#Bean
public MongoTemplate getMongoTemplate() {
return new MongoTemplate(
> getMongoFactory
());
}
}
pom.xml
--------
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<!-- <scope>test</scope> -->
</dependency>
with this configuration app is getting started when I start it but with dynamic port every restart. Also seeing below exception trace in logs. From this seems like Spring is first try to connect given mongo instance from my local machine and its not finding any so its failing then its invoking emebeded mongodb.
Is there a way I can make spring to make use of configured port to run embedded mongoDB without that error being thrown.
Error Trace
[cluster-ClusterId{value='62141aecfb7ede3c51b3d064', description='null'}-localhost:62309] INFO org.mongodb.driver.cluster -
Exception in monitor thread while connecting to server localhost:62309
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70)
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:128)
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:64)
at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:79)
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:65)
... 3 common frames omitted

Spring - Websockets - JSR-356

I implemented websockets into my application. I copied the configuration and dependencies from jHipster generated app, but I am getting the following errors:
java.lang.IllegalArgumentException: No 'javax.websocket.server.ServerContainer' ServletContext attribute. Are you running in a Servlet container that supports JSR-356?
and
org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine
I believe these errors are the reason for the socket connection not being consistent and the therefore the client is not able to send and/or receive any messages.
I searched for a solution but other post didn't help (ie. adding glassfish dependencies).
These are my ws dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
</dependency>
Do I need to include some other dependencies or is the problem elsewhere?
I found a solution here.
I added these 2 beans:
#Bean
public TomcatServletWebServerFactory tomcatContainerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();;
factory.setTomcatContextCustomizers(Collections.singletonList(tomcatContextCustomizer()));
return factory;
}
#Bean
public TomcatContextCustomizer tomcatContextCustomizer() {
return new TomcatContextCustomizer() {
#Override
public void customize(Context context) {
context.addServletContainerInitializer(new WsSci(), null);
}
};
}

Use ElasticSearch client in non web application with Spring

I'm creating a non web application with Spring that will read data from Kafka and write it in ElasticSearch, i included the following dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
And the following configuration class:
#Configuration
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration{
#Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}
When i execute the following code:
#Override
public void run(String... args) throws Exception {
IndexRequest request = new IndexRequest("test-transactions");
request.id("2");
request.source("{\"name\":\"Sammie\"," + "\"lastname\":\"Goldner\"," + "\"username\":\"hugh.vonrueden\","
+ "\"amount\":9622235.2009}", XContentType.JSON);
client.index(request, RequestOptions.DEFAULT);
}
I get the following exception:
Caused by: java.lang.ClassNotFoundException: org.springframework.http.HttpHeaders
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_251]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_251]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) ~[na:1.8.0_251]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_251]
... 46 common frames omitted
If i include the following dependency the code works fine:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
But it brings a lot of other functionalities that i don't want in my code, is there any other way to configure spring-boot-starter-data-elasticsearch in a non web application?
Thanks.

Ignore MongoDB socket connection on Spring Test

I am using mongo in my spring project, but I cant connect to mongo server. Anyone knows a way to ignore this bean when executing tests, because sometimes I dont have the mongo server up and I dont want that this build fail.
I really like to know if I can ignore it using SpringRunner.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = { Application.class })
public class ApplicationTests {
#Test
public void contextLoads() {
}
}
Stacktrace:
Caused by: org.springframework.dao.DataAccessResourceFailureException:
Timed out after 30000 ms while waiting for a server that matches WritableServerSelector.
Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: localhost}, caused by {java.net.UnknownHostException: localhost}}]; nested exception is com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: localhost}, caused by {java.net.UnknownHostException: localhost}}]
Spring components:
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Dalston.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
PS I stopped the mongodb at localhost intentionally.
You can disable Spring Boot's auto configuration of MongoDB by adding the following annotation to your ApplicationTests class:
#EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
This will prevent Spring Boot from creating the MongoClient (assuming there are no other classes in your test context annotated with #EnableAutoConfiguration or #SpringBootApplication).
I solved using embedded mongodb.
Dependency (https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo):
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
I added specific configuration on application-test.yml (execute using spring.profile.active=test)
spring:
data:
mongodb:
database: dbtest
host: localhost
port: 27028
And the ApplicationTests.java
#RunWith(SpringRunner.class)
#SpringBootTest(classes = { Application.class })
public class ApplicationTests {
private static final String LOCALHOST = "127.0.0.1";
private static final String DB_NAME = "dbtest";
private static final int MONGO_TEST_PORT = 27028;
private static MongodProcess mongoProcess;
private static Mongo mongo;
#BeforeClass
public static void initializeDB() throws IOException {
MongodStarter starter = MongodStarter.getDefaultInstance();
IMongodConfig mongodConfig = new MongodConfigBuilder()
.version(Version.Main.V3_3)
.net(new Net(LOCALHOST, MONGO_TEST_PORT, Network.localhostIsIPv6()))
.build();
MongodExecutable mongodExecutable = null;
try {
mongodExecutable = starter.prepare(mongodConfig);
mongoProcess = mongodExecutable.start();
mongo = new MongoClient(LOCALHOST, MONGO_TEST_PORT);
mongo.getDB(DB_NAME);
} finally {
if (mongodExecutable != null)
mongodExecutable.stop();
}
}
#Test
public void contextLoads() {}
#AfterClass
public static void shutdownDB() throws InterruptedException {
if (mongo != null) mongo.close();
if (mongoProcess != null) mongoProcess.stop();
}
}

Spring Integration Java DSL problems at startup with Http Outbound Gateway

I'm new to Spring Integration and am trying to develop an application which simply (1) polls a folder for new files with extension .dat containing data in csv format (2) initialize for each line a domain POJO object of class RecordDTO and finally (3) sends this object as payload to a REST service with a POST.
For this I'm trying to use Java DSL for Spring Integration.
The problem I'm getting is the following VerifyError / HttpRequestExecutingMessageHandler overrides final method onInit. exception.
2016-07-22 10:01:38.965 ERROR 4460 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'upcase' defined in eu.softeco.examples.SpringBootIntegrationTestApplication: Initialization of bean failed; nest
ed exception is java.lang.VerifyError: class org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler overrides final method onInit.()V
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
...
Caused by: java.lang.VerifyError: class org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler overrides final method onInit.()V
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_45]
at java.lang.ClassLoader.defineClass(ClassLoader.java:760) ~[na:1.8.0_45]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_45]
...
Below are relevant details concerning my code and maven configuration. Please not that
1) the problem is at startup, before any data is put in the input folder
2) if I replace the final Http outboundGateway step with the simple (commented) System.out.println, everything works fine.
Following are code/config details. This is my main Spring Boot application class with Spring Integration Flow definition:
#SpringBootApplication
#EnableIntegration
#IntegrationComponentScan
public class SpringBootIntegrationTestApplication {
...
public static void main(String[] args) {
SpringApplication.run(SpringBootIntegrationTestApplication.class, args);
}
/**
* Inbound FileReadingMessageSource
*/
#Bean
#InboundChannelAdapter(channel = "upcase.input", poller = #Poller(fixedDelay = "4000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource source = new FileReadingMessageSource();
source.setDirectory(new File(INBOUND_PATH));
source.setFilter(new SimplePatternFileListFilter("*.dat"));
return source;
}
/**
* Spring Integration Java DSL Flow
*/
#Bean
public IntegrationFlow upcase() {
FileToStringTransformer fileToStringTranformer = Transformers.fileToString();
fileToStringTranformer.setDeleteFiles(true);
return flow -> flow
// get string contents from fie
.transform(fileToStringTranformer)
// split into individual lines
.split( s -> s.applySequence(true).get().getT2().setDelimiters("\n"))
// cleanup lines from trailing returns
.transform( (String s) -> s.replace("\n", "").replace("\r", "") )
// convert csv string to RecordDTO object
.transform("#recordFromCsvTransformer.transform(payload)")
// print on System.out
// .handle(m -> System.out.println(m.getPayload()))
// send to
.handle(Http.outboundGateway("http://localhost:8080/records")
.httpMethod(HttpMethod.POST)
.expectedResponseType(RecordDTO.class));
}
}
Below the RecordFromCsvTransformer class
#Component
public class RecordFromCsvTransformer
{
#Transformer
public RecordDTO transform(String csvline) throws Exception {
RecordDTO record = new RecordDTO();
... parse csv and initialize record's fields...
return record;
}
}
And Finally the relevant parts of pom.xml (dependencies);
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RC1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
...
</dependencies>
...
As a side question in general, can someone suggest me some good tutorial / getting started guide to learn Spring Integration with Java Annotation/Java DSL? So far I've only found either introductory guide based on Spring Integration XML configuration or material about Java Annotations/DSL but that already requires prior knowledge of Spring Integration.
<version>2.1.0.RELEASE</version>
That version of Spring Integration is mismatched with the spring-integration-core version brought in transitively by maven.
You need to use the same version of all spring-integration-* files - check which version of spring-integration-file is being pulled in by boot and use the same version.

Resources