'FailedToCreateRouteException' Amazon SQS introducing Netflix-Hystrix to Spring Project - spring

I'm trying to introduce Hystrix to my Spring Project, however when I add the following dependency to my pom (tried from 1.4.4 to latest version 2.1.1):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
I get the following exception:
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route queue-name-consumer: Route(queue-name-consumer)[[From[aws-sqs://u... because of The specified queue does not exist or you do not have access to it. (Service: AmazonSQS; Status Code: 400; Error Code: AWS.SimpleQueueService.NonExistentQueue)
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:147) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doWarmUpRoutes(DefaultCamelContext.java:3949) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3856) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3642) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3494) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:209) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3253) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3272) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3249) ~[camel-core-2.22.2.jar:2.22.2]
I am using:
- Spring Boot 2.0.5
- Camel 2.22.2
- AWS-Java-SDK 1.11.381
My SQS queues are configured in my spring app in the format
#Configuration
public class QueueConfig implements CamelContextAware {
private final AmazonSQSAsync amazonSQSClient;
private CamelContext camelContext;
#Autowired
public QueueConfig(AmazonSQSAsync amazonSQSClient) {
this.amazonSQSClient = amazonSQSClient;
}
#Override
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
#Override
public CamelContext getCamelContext() {
return camelContext;
}
#Bean(name = "ExampleListenerBean)
public MessageListener<Exchange> amazonMessageListener(
RequestHandler handler,
Acknowledger<AmazonMessage> acknowledger) {
MessageListener<Exchange> listener =
new AmazonMessageListener<>(handler, acknowledger, new CamelSQSMessageConverter());
return listener;
}
#Bean(name = "ExampleRequestRouteDefinition")
public RouteBuilder exampleRouteDefinition(
#Qualifier(ExampleListenerBean) MessageListener<Exchange> listener) {
SqsQueueRouteProps properties =
SqsQueueRouteProps.main("queueDefinition", "path-to-queue").build();
String queue = properties.getFullQueueName();
return SqsQueueRouteBuilder.newBuilder(queue, amazonSQSClient, listener, getCamelContext())
.withRouteName("example-route-name")
.withProperties(properties)
.build();
}
This set up all works without the hystrix dependency, I'm not sure what incompatibilities to look for here, the error message is misleading because the queues exist there is a conflict somewhere I can not find.

Mention the version as well, and try this!
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>

Related

Migrate an application to Spring boot 3.0 which uses camel-spring-boot-starter while waiting for Camel 4

I am migrating an application to Spring boot 3.0, but I have a problem with the injection of a ProducerTemplate in one of my services (annotation #Service se Spring Boot).
I was using the Spring Boot starter from Camel
Current Spring Boot version is : 2.7.5
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-rabbitmq-starter</artifactId>
<version>3.15.0</version>
</dependency>
My ProducerTemplate is injected into the constructor of my service that extends RouteBuilder
#Service
public class MyServiceImpl extends RouteBuilder implements MyService {
private final ProducerTemplate producerTemplate;
#Autowired
public MyServiceImpl(ProducerTemplate producerTemplate) {
this.producerTemplate = producerTemplate;
}
At startup, the application crashes with this message :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.mycompany.ServiceImpl required a bean of type 'org.apache.camel.ProducerTemplate' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.apache.camel.ProducerTemplate' in your configuration.
It's not very clear to me how I should take it.
I guess I have to use the dependency
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>3.15.0</version>
</dependency>
instead of
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.15.0</version>
</dependency>
But I don't really know how I should instantiate the ProducerTemplate and the CamelContext ?
I tried without really believing something like this :
#Configuration
public class CamelConfig {
#Bean
public CamelContext getCamelContext() throws Exception {
CamelContext context = new DefaultCamelContext();
if (context.isStopped()) context.start();
return context;
}
#Bean
public ProducerTemplate getProducerTemplate() throws Exception
{
final ProducerTemplate template = getCamelContext().createProducerTemplate();
return template;
}
}
#Service
public class MyServiceImpl implements MyService {
private final ProducerTemplate producerTemplate;
private CamelContext context;
#Autowired
public MyServiceImpl(ProducerTemplate producerTemplate, CamelContext context) {
this.producerTemplate = producerTemplate;
this.context = context;
try {
this.context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:update-legacy")
.to("bean:updateJdbc");
The app failed with the following error message :
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: bean://updateJdbc due to: No bean could be found in the registry for: updateJdbc

SpringBoot web-socket without stomp

Tries to create an web application based on spring boot with web-socket support
Define public static main class annotated with #SpringBootApplication
#SpringBootApplication
public class Facade {
public static void main(String[] argv) throws IOException {
Map<String,Object> contextProperties = new HashMap<>();
contextProperties.put("server.port",p.getProperty("server.port","8091"));
SpringApplication app = new SpringApplication(Facade.class);
app.setDefaultProperties(contextProperties);
app.run(argv);
}
}
Add configuration class
#Configuration
#EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketTextHandler(), "/ws").setAllowedOrigins("*");
}
}
Add handler
#Component
public class SocketTextHandler extends TextWebSocketHandler {
#Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
String payload = message.getPayload();
session.sendMessage(new TextMessage("Hi " + payload + " how may we help you?"));
}
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
session.sendMessage(new TextMessage("Connected!"));
}
}
There are maven dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>9.0.31</version>
</dependency>
spring boot version is 2.5.5
When I connect to socket using JavaScript
webSocket = new WebSocket(wsUrl);
I see in app logs
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.socket.server.HandshakeFailureException: Servlet request failed to upgrade to WebSocket: http://127.0.0.1:8091/ws; nested exception is javax.servlet.ServletException: java.lang.reflect.InvocationTargetException] with root cause
java.lang.ClassNotFoundException: org.apache.coyote.http11.upgrade.UpgradeInfo
The tomcat-coyote dependency is in pom.xlm
I used web-sockets in jersey implementation under tomcat9. Now I tries to migrate application to spring-boot, but confused with NoClassDef exception.
Could you please explain or suggest solution for this cause.

How to bypass Redis session on Spring Boot application on Redis connection failure?

I have implemented Redis session management using LettuceConnectionFactory on my Spring Boot java application by following some of the sample applications out there and the Spring documentation. It works fine when it can connect to the Redis server. But the application doesn't respond when the connection fails because it repeatedly trying to connect. I have done a lot of research to find a solution but couldn't find anything yet. The questions I have are,
Is there a way to switch to Spring Session (it could even be a JDBC session) when it can't connect to Redis after certain number of retries?
Is there a way to set the number of retries in the connection factory? I don't see any property for this in spring.redis properties list.
Any help is appreciated.
Updated on 11/4/2019
Application properties:
spring.session.store-type=redis
spring.session.redis.flush-mode=on-save
spring.session.redis.namespace=spring:session
spring.redis.host=*****.windows.net
spring.redis.port=6380
spring.redis.ssl=true
spring.redis.password=****************
spring.redis.timeout=5000ms
spring.redis.custom.command.timeout=1000ms
HttpSessionConfig.java:
#Configuration
#PropertySource("classpath:application.properties")
#EnableRedisHttpSession
public class HttpSessionConfig extends AbstractHttpSessionApplicationInitializer {
Logger logger = LoggerFactory.getLogger(HttpSessionConfig.class);
#Value("${spring.redis.host}")
private String redisHostName;
#Value("${spring.redis.port}")
private int redisPort;
#Value("${spring.redis.password}")
private String redisPassword;
private #Value("${spring.redis.custom.command.timeout}")
Duration redisCommandTimeout;
private #Value("${spring.redis.timeout}")
Duration socketTimeout;
#Bean
LettuceConnectionFactory lettuceConnectionFactory() {
final SocketOptions socketOptions = SocketOptions.builder().connectTimeout(socketTimeout).build();
final ClientOptions clientOptions = ClientOptions.builder()
.socketOptions(socketOptions)
.build();
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.commandTimeout(redisCommandTimeout)
.clientOptions(clientOptions)
.readFrom(ReadFrom.SLAVE_PREFERRED)
.build();
RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration(redisHostName,
redisPort);
final LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(serverConfig,
clientConfig);
return lettuceConnectionFactory;
}
#Bean
public RedisTemplate<Object, Object> sessionRedisTemplate() {
final RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(lettuceConnectionFactory());
return template;
}
#Bean
public ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}
}
Dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>3.5.0.Final</version>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.1.6.RELEASE</version>
<optional>true</optional>
</dependency>
Please let me know if more details are required.
As us we're using
#Profile(value = "production") for RedisHttpSession and
#Profile(value = "development") for DevSessionConfig
then use can setting spring.profiles.active in application.properties

Spring Data Mongodb WriteConcern working?

I have the following Spring Data MongoDb Repository Java configuration:
#EnableMongoRepositories(basePackages= {"com.example.repositories.mongodb"})
public class MongoConfig extends AbstractMongoConfiguration {
private #Value("${mongo.host}") String mongoHost;
private #Value("${mongo.port}") int mongoPort;
private #Value("${mongo.database}") String mongoDatabase;
#Override
protected String getDatabaseName() {
return mongoDatabase;
}
#Override
public Mongo mongo() throws Exception {
MongoClientOptions options = MongoClientOptions.builder()
.connectionsPerHost(100)
.connectTimeout(120000)
.socketTimeout(120000)
.maxWaitTime(1200000)
.threadsAllowedToBlockForConnectionMultiplier(1500)
.writeConcern(WriteConcern.ACKNOWLEDGED)
.build();
MongoClient client = new MongoClient(new ServerAddress(mongoHost, mongoPort), options);
return client;
}
public #Bean PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
I am trying to figure out if the writeConcern is really turned on due to some jUnits not working when running repeatedly. If I place a breakpoint after the client is created above and inspect the client object I can see its property WriteConcern equals:
{w=null, wTimeout=null ms, fsync=null, journal=null}
Which suggests to me that it was not set to ACKNOWLEDGED.
Am I setting it properly and is there a way to see if the correct concern is set? None of the logger options I tried made it output.
My dependencies are:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${spring.data.mongodb}</version>
</dependency>

spring data neo4j Embedded : Connect to localhost:7474 failed: Connection refused

Having this configuration :
#Configuration
#EnableNeo4jRepositories("com.mydb.repository")
#EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer( "http://localhost:7474" );
}
#Bean
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( new File("./mydb.db") )
.setConfig( ServerSettings.auth_enabled, Boolean.FALSE.toString() )
.newGraphDatabase();
}
#Bean
#Override
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
#Bean
#Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.mydb.model");
}
}
I have 2 errors :
1_ I can't keep the Session in scope "session"
2_ I have the exception : Connect to localhost:7474 failed: Connection refused:
The server is Embedded, it should start without instaling any server on my local machine ?
Spring-boot 1.3.0 (Last) and
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
Version 4.0 of Spring Data for Neo4j doesn't support embedded version of Neo4j.
You need to install Neo4j on your local machine.
"SDN 4.1 will support embedded version." #Luanne

Resources