Spring Cloud - Zuul Server error - java

Application.java
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableZuulProxy
public class ZuulServer {
public static void main(String[] args) {
SpringApplication.run(ZuulServer.class, args);
}
}
application.yml
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/v2/
zuul:
proxy:
route:
service1: /myservice1
service2: /myservice2
Example calls:
http://localhost:8080/proxy/myservice1/users
http://localhost:8080/proxy/myservice2/auctionlots/today
Predecoration filter works during routing getting following error (using 1.0.0.M2) :
Caused by: java.lang.NoSuchMethodError: com.netflix.hystrix.HystrixExecutableBase$ObservableCommand.toBlocking()Lrx/observables/BlockingObservable;
at com.netflix.hystrix.HystrixExecutableBase.queue(HystrixExecutableBase.java:342)
at com.netflix.hystrix.HystrixObservableCommand.queue(HystrixObservableCommand.java:50)
at com.netflix.hystrix.HystrixExecutableBase.execute(HystrixExecutableBase.java:296)
at com.netflix.hystrix.HystrixObservableCommand.execute(HystrixObservableCommand.java:50)
at com.netflix.hystrix.HystrixCommand.execute(HystrixCommand.java:485)
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:162)
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.run(RibbonRoutingFilter.java:86)
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112)
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:197)
... 41 common frames omitted

#vladsfl My sample app with your provided code works. That particular error comes from having an incompatible version (likely old) of rxjava. The version in my sample (and the version that works with hystrix) is com.netflix.rxjava:rxjava-core:jar:0.20.6. Can you provide your configuration? What version of rxjava do you have?

Related

Embedded MongoDB with Spring not working in test

I am trying to create a test class with embedded MongoDB.
I can't start my test because it seems that embedded mongodb has not started.
The exception that I get is the following:
2021-10-18 17:33:17 INFO - [org.mongodb.driver.cluster:76] - Exception in monitor thread while connecting to server localhost:27019
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.AsynchronousSocketChannelStream$OpenCompletionHandler.failed(AsynchronousSocketChannelStream.java:272)
at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:129)
at java.base/sun.nio.ch.Invoker.invokeDirect(Invoker.java:158)
at java.base/sun.nio.ch.Invoker.invoke(Invoker.java:186)
at java.base/sun.nio.ch.Invoker.invoke(Invoker.java:298)
at java.base/sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ConnectTask.failed(WindowsAsynchronousSocketChannelImpl.java:308)
at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:389)
at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.io.IOException: The remote computer refused the network connection.
The dependency for embedded mongo:
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
This is my test class
import ...
#ExtendWith(SpringExtension.class)
#SpringBootTest
#ActiveProfiles("test")
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#EnableReactiveMongoRepositories
#ComponentScan(
excludeFilters = {#ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
value = {MongoReactiveDataAutoConfiguration.class}
)}
)
#Slf4j
public class MyServiceTest {
#Autowired
private MyService myService;
#Test
public void saveDataOnMongoTest(){
}
}
This is my configuration of mongo on my yaml under the test profile
data:
mongodb:
uri: mongodb://localhost:27019/myDb
database: myDb
port: 27019 # embedded test purpose
repositories:
type: reactive
jpa:
repositories:
enabled: true
mongodb:
embedded:
version: 4.0.3
features: sync_delay,no_http_interface_arg,only_with_ssl,only_windows_2008_server
Add exclusion annotation to the main class like
#SpringBootTest
#EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
It may be working.
Found this because I had the same issue.
I fixed it by adding the following to the src/test/resources/application.properties:
spring.data.mongodb.port=0
spring.mongodb.embedded.version=3.6.5
Port -> 0 means use a random port and the version must be set so it will download and start a mongo db.
This is Kotlin code but it's the test that works for me:
#DataMongoTest
#ExtendWith(SpringExtension::class)
class HolmesDataApplicationTests {
#Test
fun contextLoads() {
}
#Test
fun test(#Autowired mongoTemplate: ReactiveMongoTemplate) {
val objectToSave = BasicDBObjectBuilder.start()
.add("key", "value")
.get()
mongoTemplate.save(objectToSave, "collection")
}
}

Turning off Spring Boot AWS Autoconfiguration

I'm using spring-cloud-aws-autoconfigure:2.1.0.RELEASE to connect to AWS. However when the app is running in an enviromnent other than AWS, I don't want the auto configuration to take place.
I tried turning off the auto configuration as suggested here and here with java configuration class, and also with spring.autoconfigure.excludes property in my yml file like this:
spring:
autoconfigure:
exclude:
- org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration
But none of those solutions seems to work. The autoconfiguration still takes place and consequently, the app fails to start.
Found a solution: I added this directly to my main application class:
import org.springframework.cloud.aws.autoconfigure.context.*;
#SpringBootApplication
#EnableAutoConfiguration(exclude = {
ContextCredentialsAutoConfiguration.class,
ContextInstanceDataAutoConfiguration.class,
ContextRegionProviderAutoConfiguration.class,
ContextResourceLoaderAutoConfiguration.class,
ContextStackAutoConfiguration.class,
MailSenderAutoConfiguration.class,
})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Found solution: I excluded every class I found in the autoconfiguration jar:
spring:
autoconfigure:
exclude:
- org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration
- org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration

Spring RMQ listener always use PLAIN auth even after configuring SSL properties

I have a spring boot application and I am trying to configure listeners to already existing queues. Following is what I configured in my application.yml file. I have also annotated my config class with #EnableRabbit and listener with #RabbitListener with appropriate configuration referring spring documentation.
Please note that every property has a valid default value, I have removed them before posting them here.
spring:
rabbitmq:
host: ${rmq_host}
port: ${rmq_port}
virtualHost: ${rmq_virtual_host}
requestedHeartbeat: ${rmq_requested_heartbeat_seconds}
listener:
simple:
concurrency: ${rmq_listener_config_concurrent_users}
autoStartup: ${rmq_listener_config_auto_startup}
acknowledge-mode: ${rmq_listener_config_ack_mode}
ssl:
enabled: ${rmq_ssl_enabled:true}
keyStore: ${rmq_ssl_keystore}
keyStorePassword: ${rmq_ssl_keystore_password}
trustStore: ${rmq_ssl_truststore}
trustStorePassword: ${rmq_ssl_truststore_password}
With this configuration when I try to start the application it throws below exception.
org.springframework.amqp.rabbit.listener.exception.FatalListenerStartupException: Authentication failure
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:532)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1389)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:65)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:368)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:565)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$1.createConnection(ConnectionFactoryUtils.java:90)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:140)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:76)
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:527)
... 2 common frames omitted
Caused by: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:342)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:909)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:859)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:799)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:352)
... 7 common frames omitted
While writing producers, I observed the same error which was resolved by setting sasl configurations to EXTERNAL but I could do it then as I was writing configuration beans on my own, here I am trying to use out of the box support from spring.
OK, so here is what i found. There is an open defect on spring-boot which mentions that due to unavailability of configuring sasl while using spring boot, it always uses PLAIN mode of authentication and there is a workaround which made my code work as expected. Below is the configuration class I added.
#Configuration
public class RabbitMQConfig {
#Autowired
private RabbitProperties rabbitProperties;
#Autowired
private CachingConnectionFactory cachingConnectionFactory;
#PostConstruct
public void init() {
if ( rabbitProperties.getSsl().isEnabled() && rabbitProperties.getSsl().getKeyStore() != null ) {
cachingConnectionFactory.getRabbitConnectionFactory().setSaslConfig( DefaultSaslConfig.EXTERNAL );
}
}
}

Spring boot enable http/2 protocol

I'm using Spring boot 1.5.12 (JDK 8) with embedded Undertow server 1.4 and I have enable http2 protocol inside my properties using 'server.https.enabled: true' but it doesn't seems to be working. I have also secured connection with self signed certificate. When I load my application (Angular 5) on the browser I'm still getting http/1.1 protocol.
Here is what I have in my SpringBootApplication class:
#SpringBootApplication
#EnableEurekaClient
#EnableOAuth2Sso
public class Application extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void configure(HttpSecurity http) throws Exception {
//some authorization configuration
}
}
Application.properties file
security:
require-ssl: true
server:
ssl:
enabled: true
http2:
enabled: true
port: 8085
ssl:
key-store: classpath: keystore.p12
key-store-type: PKCS12
key-alias: devel
key-store-password: pass
key-password: pass
eureka:
client:
serviceUrl:
defaultZone: https://localhost:8761/eureka
instance:
preferIpAddress: false
securePortEnabled: true
securePort: ${server.port}
Is there anything else I have to configure?
Thanks in advance
Try adding the following bean to your configuration:
#Bean
UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
factory.addBuilderCustomizers(
builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
return factory;
}
The property server.http2.enabled doesn't exist in spring boot 1.5.13. See this

spring-boot health not showing details (withDetail info)

I have written a class implementing HealthIndicator, overriding the health-method. I return Health.down().withDetail("SupportServiceStatus", "UP").build();
This should make my health-endpoint return:
{
"status":"UP",
"applicationHealth": {
"status":"UP"
}
}
Instead it just returns (health, without details):
{
"status":"UP",
}
Javacode (somewhat simplified):
#Component
public class ApplicationHealth implements HealthIndicator {
#Override
public Health health() {
return check();
}
private Health check() {
return Health.up().withDetail("SupportServiceStatus", supportServiceStatusCode).build();
}
}
According to spring-boot docs:
. . . by default, only the health status is exposed over an unauthenticated HTTP connection. If you are happy for complete health information to always be exposed you can set endpoints.health.sensitive to false.
Solution is to set endpoints.health.sensitive to false in application.properties.
application.properties
endpoints.health.sensitive=false
For >1.5.1 application.properties
management.security.enabled=false
At Spring Boot 2.0.0.RELEASE (thx #rvit34 and #nisarg-panchal):
management:
endpoint:
health:
show-details: "ALWAYS"
endpoints:
web:
exposure:
include: "*"
management.endpoints.web.exposure.include=* exposes all endpoints, if that is what you want.
Current documentation can be found here: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
At Spring Boot 2.0.0.RELEASE:
management:
endpoint:
health:
show-details: "ALWAYS"
Thanks #rvit34 and #Ninja Code Monkey its working.
For Springboot 2.x.x.RELEASE,
Use below for application.properties,
management.endpoint.health.show-details=ALWAYS
Use below for applicaton.yml,
management:
endpoint:
health:
show-details: "ALWAYS"
Setting 'endpoints.health.sensitive' made no difference... had to set:
management:
security:
enabled: false
need to add
management.endpoint.health.show-details=always
to Application.properties
For Spring boot 2.X I have following in my application.properties file for detailed information:
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=ALWAYS
I had this same problem, on version Spring Boot 1.5.9 I had to set
management.security.enabled=false

Categories

Resources