Sleuth not working for websocket client - spring-cloud-sleuth

I have a microservice which is connecting to the WebSocket server, and receiving the messages from the server. I want to integrate Sleuth in this application, as this is the gateway for my set of microservices. But when I connect to the WebSocket server and start receiving messages, I can't traceId, spanid in the log in the log. I was expecting something like:
2018-08-09 11:26:20.222 INFO [kumarman-betsync-adapter-service-v2,0a011711c2470359,0a011711c2470359,true] 7230 --- [ient-SecureIO-2] c.b.b.a.service.BetSyncEventIdExtractor : SubscribeResponse feed received for eventId=7519016
2018-08-09 11:26:20.224 INFO [kumarman-betsync-adapter-service-v2,0a011711c2470359,2b028dadad5c440d,true] 7230 --- [ient-SecureIO-2] c.b.b.a.k.message.KafkaMessageSender : sent payload to topic='betsyncEventTopic'
But I am getting:
2018-08-09 11:26:20.222 INFO [kumarman-betsync-adapter-service-v2,,,] 7230 --- [ient-SecureIO-2] c.b.b.a.service.BetSyncEventIdExtractor : SubscribeResponse feed received for eventId=7519016
2018-08-09 11:26:20.224 INFO [kumarman-betsync-adapter-service-v2,,,] 7230 --- [ient-SecureIO-2] c.b.b.a.k.message.KafkaMessageSender : sent payload to topic='betsyncEventTopic'
my code is as follows:
#Service
#Slf4j
#AllArgsConstructor
public class BetsyncWebsocketAdapter {
private final BetsyncWebSocketHandler betsyncWebSocketHandler;
public void startNewConnection() {
try {
webSocketSession = new StandardWebSocketClient().doHandshake(
betsyncWebSocketHandler,
new WebSocketHttpHeaders(),
new URI(getBetsyncConnectionUrl()))
.get(KafkaAdminClient.MAX_TIME_LIMIT_TO_CONNECT, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("exception occurred", e);
}
}
/**
* This will start the new connection after server start
*/
#EventListener(ApplicationReadyEvent.class)
public void onServerStart() {
startNewConnection();
}
}
#Slf4j
#Service
#AllArgsConstructor
public class BetsyncWebSocketHandler extends TextWebSocketHandler {
private static StringBuilder betSyncMessage = new StringBuilder();
private final LoginRequestBuilder loginRequestBuilder;
private final BetsyncMessageProcessing betsyncMessageProcessing;
#Override
public void afterConnectionEstablished(final WebSocketSession session) throws IOException {
session.sendMessage(new TextMessage(loginRequestBuilder.getLoginRequestDto()));
}
#Override
protected void handleTextMessage(final WebSocketSession session, final TextMessage message) {
betSyncMessage.append(message.getPayload());
if (message.isLast()) {
betsyncMessageProcessing.process(betSyncMessage.toString());
betSyncMessage = new StringBuilder();
} else {
log.debug("we have received a partial message starting with {}", getFirstXCharacter(message.getPayload(), 50));
}
}
#Override
protected void handlePongMessage(final WebSocketSession session, final PongMessage message) {
log.info("Response for Ping message received from the server");
}
#Override
public boolean supportsPartialMessages() {
return true;
}
#Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
log.error("server connection closed");
}
}
Our pom entries are:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<spring.boot.version>2.0.3.RELEASE</spring.boot.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>

You're creating the socket handling by yourself
webSocketSession = new StandardWebSocketClient().doHandshake(
betsyncWebSocketHandler,
new WebSocketHttpHeaders(),
new URI(getBetsyncConnectionUrl()))
.get(KafkaAdminClient.MAX_TIME_LIMIT_TO_CONNECT, TimeUnit.SECONDS);
Spring Cloud Sleuth supports WebSockets, when you use Spring Integration components directly. Since you're doing things manually, you have to ensure that the tracing context gets propagated and that you can read it yourself.

Related

Java EE 6 annotation #WebServlet is not working with embedded tomcat 8

I m trying to use web application with Embedded tomcat 8 without web.xml.
But I am not able to access the application by hitting the url http://localhost:8085/Servlet_Basic/index.jsp from browser.
Neither I am able to access the servlet by hitting the url http://localhost:8085/Servlet_Basic/hello from browser.
Here is my source code :
pom.xml dependencies
<properties>
<tomcat.version>8.5.23</tomcat.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>14</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>8.5.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
HelloServlet.java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
#WebServlet(urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public HelloServlet() {
super();
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n";
out.println(docType + "<HTML>\n" + "<HEAD><TITLE>Hello</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>My First Servlet</H1>\n" + "</BODY></HTML>");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
App.java
public class App {
public static void main(String[] args) throws LifecycleException {
int port = 8085;
Tomcat tomcat = new Tomcat();
tomcat.setPort(port);
StandardServer server = (StandardServer) tomcat.getServer();
AprLifecycleListener listener = new AprLifecycleListener();
server.addLifecycleListener(listener);
String docBase = "D:\\Servlet_Basic\\src\\main\\webapp";
Context context = tomcat.addWebapp("/Servlet_Basic", docBase);
context.setAddWebinfClassesResources(true);
tomcat.start();
System.out.println("Tomcat server started at port " + port);
tomcat.getServer().await();
}
}
src/main/webapp contents :
index.jsp
<html>
<body>
<h2>Hello World</h2>
</body>
</html>
How can I access the application and invoke servlet annotated with #WebServlet
annotation in embedded tomcat without using web.xml ?
Basically I want to use web application with embedded tomcat without web.xml and without explicitly configuring servlets using tomcat.addServlet() method.
Instead I would like to configure servlet using #WebServlet annotation

Jersey 2 - with .target HTTPS

I've been trying to perform a POST from a jersey client but continue to run into the following exception:
Caused by: java.lang.IllegalStateException: Already connected
at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:3071)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestProperty(HttpsURLConnectionImpl.java:325)
at org.glassfish.jersey.client.internal.HttpUrlConnector.setOutboundHeaders(HttpUrlConnector.java:424)
at org.glassfish.jersey.client.internal.HttpUrlConnector.lambda$_apply$0(HttpUrlConnector.java:381)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:195)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:189)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:257)
at org.glassfish.jersey.message.internal.OutboundMessageContext.commitStream(OutboundMessageContext.java:825)
at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:553)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:498)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:384)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:282)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:278)
... 63 more
I've tried a ton of answers and solutions in SO with no luck.
Going crazy here, please help!
public class JerseyWithSSL {
public static javax.ws.rs.client.Client getRESTClient() {
try {
TrustManager[] trustMgr = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted1(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted1(X509Certificate[] certs,
String authType) {
}
#Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
#Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
}};
SSLContext context = SSLContext.getInstance("SSL");
context.init(null, trustMgr, null);
javax.ws.rs.client.Client client = ClientBuilder.newBuilder().sslContext(context)
.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;
}
}).build();
return client;
} catch (NoSuchAlgorithmException | KeyManagementException ex) {
Logger.getLogger(JerseyWithSSL.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
Code which uses the above class (exception thrown here):
// send notification to all subscriptors for event: attendee.create
if (!subscriptions.isEmpty()) {
try {
Client client = JerseyWithSSL.getRESTClient();
for (Subscription sub : subscriptions) {
System.out.println("Subscription: \n" + sub.getEventName() + "\n" + sub.getTargetUrl());
Response resp = client.target(sub.getTargetUrl())
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(newAttdee, MediaType.APPLICATION_JSON));
System.out.println("Status: " + resp.getStatus());
System.out.println(resp.getEntity().toString());
resp.close();
}
} catch (Exception ex) {
Logger.getLogger(AttendeeResource.class.getName()).log(Level.SEVERE, null, ex);
}
}
Adding pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ON24Hooks</groupId>
<artifactId>ON24_Zapier_Hooks</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ON24_Zapier_Hooks</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
<version>2.16</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The IllegalStateException: Already connected is probably masking a SSLHandshakeException, as described in the issue #3000 (previously referenced as JERSEY-2728).
According to the release notes, it was fixed in Jersey 2.23. I would upgrade Jersey to the most recent version though.
I spent some time to figure it out how it is been done in Jersey 2.x. Thanks to Jersey Migration Guide to help me out.
Below is code snippet for how client is build in Jersey 2.x for HTTPS call
public Client getRESTClient() {
TrustManager[] trustMgr= new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted1(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted1(X509Certificate[] certs,
String authType) {
}
#Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
#Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
} };
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustMgr, null);
Client client = ClientBuilder.newBuilder().sslContext(context)
.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;
}
}).build();
return client;
}
Just exception can be occur at any point while it may be SSL certificate validation also which can also current socket layer connection to validate SSLContext.Please debug out try catch block thoroughly also make the execution of your http request with other client also as well from Java Url URLCONNECTION
The IllegalStateException: Already connected is probably masking a SSLHandshakeException. The way to verify/debug this is to use the following JVM flags:
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack
This will cause the JVM to print out a whole bunch of debug information regarding SSL and will show the SSL exception if there is one.

Cannot connect to mongoDB using Spring Data Reactive and Spring Boot 2.0

I get the following error every time I trying to connect to MongoDB using Spring Data Reactive and Spring Boot 2.0.
Caused by: java.lang.UnsupportedOperationException: No SSL support in java.nio.channels.AsynchronousSocketChannel. For SSL support use com.mongodb.connection.netty.NettyStreamFactoryFactory
at com.mongodb.connection.AsynchronousSocketChannelStreamFactory.<init>(AsynchronousSocketChannelStreamFactory.java:41)
at com.mongodb.async.client.MongoClients.getStreamFactory(MongoClients.java:228)
at com.mongodb.async.client.MongoClients.create(MongoClients.java:177)
at com.mongodb.async.client.MongoClients.create(MongoClients.java:123)
at com.mongodb.reactivestreams.client.MongoClients.create(MongoClients.java:103)
at com.mongodb.reactivestreams.client.MongoClients.create(MongoClients.java:53)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoClientFactory.createNetworkMongoClient(ReactiveMongoClientFactory.java:123)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoClientFactory.createMongoClient(ReactiveMongoClientFactory.java:69)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration.reactiveStreamsMongoClient(ReactiveMongoAutoConfiguration.java:67)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration$$EnhancerBySpringCGLIB$$94536095.CGLIB$reactiveStreamsMongoClient$1(<generated>)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration$$EnhancerBySpringCGLIB$$94536095$$FastClassBySpringCGLIB$$2171f816.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration$$EnhancerBySpringCGLIB$$94536095.reactiveStreamsMongoClient(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1093)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:534)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:833)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:740)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:466)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1093)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:534)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:833)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:740)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:466)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1093)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:534)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1604)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1349)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:570)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:358)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1337)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:865)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:809)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:404)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:347)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:128)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:102)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:47)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:243)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:226)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:245)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:189)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
The error message tells me to use NettyStreamFactoryFactory for SSL support. Does anyone have any examples on how to do this? The database I am trying to connect to is MongoDB Atlas, it strictly require a SSL connection.
Below is the rest of my code:
#SpringBootApplication
public class FlixMovieApiReactiveApplication {
public static void main(String[] args) {
SpringApplication.run(FlixMovieApiReactiveApplication.class, args);
}
// Add Data
#Bean
public CommandLineRunner initDatabase(MovieRepository repository) {
// entire process blocking, done in beginning
Flux<Movie> movieList = Flux.just(
new Movie("movie1", "1", "movie1"),
new Movie("movie2", "1", "movie2"),
new Movie("movie3", "5", "movie3"),
new Movie("movie4", "1", "movie4"),
new Movie("movie5", "3", "movie5"),
new Movie("movie6", "1", "movie6"),
new Movie("movie7", "2", "movie7"),
new Movie("movie8", "3", "movie8"),
new Movie("movie9", "1", "movie9"),
new Movie("movie10", "2", "movie10"),
new Movie("movie11", "1", "movie11"),
new Movie("movie12", "3", "movie12"),
new Movie("movie13", "1", "movie13"),
new Movie("movie14", "4", "movie14"),
new Movie("movie15", "1", "movie15"),
new Movie("movie16", "4", "movie16")
);
// delete then insert data. blockLast(), allows something to subscribe to pipeline, block for last emitted element
// data is written to the database.
return args -> repository.deleteAll().thenMany(repository.save(movieList)).blockLast();
}
}
#RestController
public class MovieRestController {
#Autowired
private MovieService movieService;
#GetMapping(value = "/movies")
public Flux<ResponseEntity<Movie>> list() {
return movieService.list().map(m -> new ResponseEntity<>(m, HttpStatus.OK));
}
#GetMapping(value = "/moviesByRating")
public Flux<ResponseEntity<Movie>> findByRating(
#RequestParam(value = "rating", required = false) final String rating) {
return movieService.findByRating(rating)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK));
}
#GetMapping("/movies/{movieId}")
public Mono<ResponseEntity<Movie>> read(
#PathVariable("movieId") final String movieId) {
return movieService.read(movieId)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#DeleteMapping("/movies/{movieId}")
public Mono<ResponseEntity<Movie>> delete(
#PathVariable("movieId") final String movieId) {
return movieService.delete(movieId)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#PutMapping("/movies/{movieId}")
public Mono<ResponseEntity<Movie>> update(
#PathVariable("movieId") final String movieId,
#RequestBody final MovieRequest movieRequest) {
return movieService.update(movieId, movieRequest)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#PostMapping("/movies")
public Mono<ResponseEntity<Movie>> create(
#RequestBody final Mono<MovieRequest> movieRequest) {
return movieService.create(movieRequest)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
#Service
public class MovieServiceImpl implements MovieService {
#Autowired
private MovieRepository movieRepository;
#Override
public Flux<Movie> list(){
return movieRepository.findAll();
}
#Override
public Flux<Movie> findByRating(final String rating){
return movieRepository.findByRating(rating);
}
#Override
public Mono<Movie> update(String id, MovieRequest movieRequest) {
return movieRepository.findOne(id).map(existingMovie -> {
if(movieRequest.getDescription() != null){
existingMovie.setDescription(movieRequest.getDescription());
}
if(movieRequest.getRating() != null){
existingMovie.setRating(movieRequest.getRating());
}
if(movieRequest.getTitle() != null) {
existingMovie.setTitle(movieRequest.getTitle());
}
return existingMovie;
}).then(movieRepository::save);
}
#Override
public Mono<Movie> create(Mono<MovieRequest> movieRequest) {
return movieRequest.map(newMovie -> {
Movie movie = new Movie();
if(newMovie.getDescription() != null){
movie.setDescription(newMovie.getDescription());
}
if(newMovie.getRating() != null){
movie.setRating(newMovie.getRating());
}
if(newMovie.getTitle() != null) {
movie.setTitle(newMovie.getTitle());
}
return movie;
}).then(movieRepository::save);
}
#Override
public Mono<Movie> read(String id) {
return movieRepository.findOne(id);
}
#Override
public Mono<Movie> delete(String id) {
return movieRepository.findOne(id)
.flatMap(oldValue -> movieRepository.delete(id).then(Mono.just(oldValue)))
.singleOrEmpty();
}
}
#Repository
public interface MovieRepository extends ReactiveMongoRepository<Movie, String> {
Flux<Movie> findByRating(String rating);
}
#Document
public class Movie {
#Id
private String id;
private String title;
private String rating;
private String description;
public Movie(String title, String rating, String description) {
this.title = title;
this.rating = rating;
this.description = description;
}
public Movie() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
---
spring:
data:
mongodb:
uri: mongodb://admin:xxxxxx#movie-shard-00-00-xfzg4.mongodb.net:27017,movie-shard-00-01-xfzg4.mongodb.net:27017,movie-shard-00-02-xfzg4.mongodb.net:27017/movie?ssl=true&replicaSet=Movie-shard-0&authSource=admin
management:
context-path: /admin
server:
port: 8080
Below is the 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.flix.movie</groupId>
<artifactId>flix-movie-api-reactive</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>flix-movie-api-reactive</name>
<description>Demo project for Spring Boot using Non-Blocking Reactive Spring Web MVC and Spring Data MongoDB</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<docker.image.prefix>flix</docker.image.prefix>
<docker.spotify.plugin.version>0.4.5</docker.spotify.plugin.version>
<swagger.version>2.4.0</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-dependencies-web-reactive</artifactId>
<version>0.1.0.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Package as a docker image -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.spotify.plugin.version}</version>
<configuration>
<serverId>docker-hub</serverId>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Try
in connection String
xxxx?ssl=true&sslInvalidHostNameAllowed=true&streamType=netty
or Via MongoClientSettings
EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); // make sure application shuts this down
#Bean
public MongoClient getClient()
{
return MongoClients.create(MongoClientSettings.builder()
.clusterSettings(ClusterSettings.builder()
.hosts(Arrays.asList(new ServerAddress()))
.build())
.streamFactoryFactory(NettyStreamFactoryFactory.builder()
.eventLoopGroup(eventLoopGroup).build())
.sslSettings(SslSettings.builder()
.enabled(true)
.build())
.build());
}
#PreDestroy
public void shutDownEventLoopGroup() {
eventLoopGroup.shutdownGracefully();
}
Reference
This sounds like a Spring Data Mongo and/or Spring Boot issue.
At first it seems Spring Boot is giving the appropriate information to the Spring Data Mongo client configuration.
Could you create an issue on the dedicated issue tracker for Spring Data Mongo?
As mp911de mentioned above, adding Netty dependency in your pom will solve the problem.
For me, adding the spring-boot-starter-webflux resolved the issue.
It's the MongoClient who is responsible for managing the connection. In your case it is the default unprotected one, so if you have security enabled on your Mongo instance he will bounce back.
#Configuration
#EnableReactiveMongoRepositories
class MongoConfig : AbstractReactiveMongoConfiguration() {
override fun reactiveMongoClient(): MongoClient = MongoClients.create()
override fun getDatabaseName(): String = "mydb"
}
This is my configuration for reactive mongo in spring boot 2 M4. You can customize your client via MongoClients methods or appropriate constructor.

Can't publish in cometd channel

I'm getting this error when I try to publish a string in a channel:
java.lang.AbstractMethodError: org.cometd.client.BayeuxClient$BayeuxClientChannel.publish(Ljava/lang/Object;)V
this is the code that is trying to publish:
public class EnviadorMensagem implements Runnable {
private String nomeCanal;
private Mensagem mensagem;
private ClientSession cliente;
private boolean pausado = true;
private boolean cancelado = false;
#Override
public void run() {
while (pausado) {
pausar();
}
if (!cancelado) {
converterEEnviar();
}
}
private void pausar() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void converterEEnviar() {
ConversorMensagem conversor = new ConversorMensagem();
ClientSessionChannel canal = cliente.getChannel(nomeCanal);
canal.publish(conversor.converter(mensagem)); //<- the error happens here!!
}
public void ativar() {
synchronized (this) {
pausado = false;
this.notifyAll();
}
}
public void cancelar() {
synchronized (this) {
cancelado = true;
}
ativar();
}
public void setNomeCanal(String nomeCanal) {
this.nomeCanal = nomeCanal;
}
public void setMensagem(Mensagem mensagem) {
this.mensagem = mensagem;
}
public void setCliente(ClientSession cliente) {
this.cliente = cliente;
}
}
As you can see, this class is running in a separate thread.
this is part of my pom.xml:
<dependencies>
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>cometd-java-client</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>bayeux-api</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>8.1.7.v20120910</version>
</dependency>
</dependencies>
Someone knows how to solve it??
You get AbstractMethodError when you compiled your code against a version of a library, but at runtime you are using another, that does not have that method, or has it with a different signature.
Double check your classpath and the CometD library versions you're using.

Allure. How to get screenshot on testFailure event. Use Java+Junit4+Maven

If I want to get screenshot when my Tests are failed, so what the best practice is? I try to do this next way:
1)overridre AllureRunListener:
public class SimpleScreenshotTestListener extends AllureRunListener{
#Override
public void testFailure(Failure failure) {
if (failure.getDescription().isTest()) {
fireTestCaseFailure(failure.getException());
} else {
startFakeTestCase(failure.getDescription());
fireTestCaseFailure(failure.getException());
finishFakeTestCase();
}
makeScreenshot("Failure screenshot");
}
}
The method makeScreenshot("Failure screenshot") is a static method in Util Class:
public final class Util {
private Util() {}
#Attachment(value = "{0}", type = "image/png")
public static byte[] makeScreenshot(String name) {
return ((TakesScreenshot) <Thread Local Driver>).getScreenshotAs(OutputType.BYTES);
}
}
3) In my pom file I use created listener
SimpleScreenshotTestListener:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<testFailureIgnore>false</testFailureIgnore>
<argLine>
-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
</argLine>
<properties>
<property>
<name>listener</name>
<value>cms.fireFox.Tps.SimpleScreenshotTestListener</value>
</property>
</properties>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
And my question is : Is this way is the best way or should I do this easier.
Just use JUnit Rules like the following:
public class ScreenshotOnFailureRule implements TestRule {
public Statement apply(final Statement statement, final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
try {
statement.evaluate();
} catch (Throwable t) {
captureScreenshot();
throw t;
}
}
#Attachment
private byte[] captureScreenshot() {
try {
return ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
} catch (Exception e) {
// No need to crash the tests if the screenshot fails
}
}
};
}
}
So far as captureScreenshot() method is run on failure Allure will attach resulting PNG byte stream to test case. Further reading about rules.