Sending HTML email with Spring Boot and Thymeleaf - java

I am checking out how to send an email using Spring Boot.
Send an e-mail using standard Spring Boot modules and prepare HTML content for a message using Thymeleaf template engine.
This is the dependencies I use
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Here my MailClient
#Service
public class MailClient {
private JavaMailSender mailSender;
private MailContentBuilder mailContentBuilder;
#Autowired
public MailClient(JavaMailSender mailSender, MailContentBuilder mailContentBuilder) {
this.mailSender = mailSender;
this.mailContentBuilder = mailContentBuilder;
}
public void prepareAndSend(String recipient, String message) {
MimeMessagePreparator messagePreparator = mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom("amadeu.cabanilles#gmail.com");
messageHelper.setTo("amadeu.cabanilles#gmail.com");
messageHelper.setSubject("Sample mail subject");
String content = mailContentBuilder.build(message);
messageHelper.setText(content, true);
};
try {
mailSender.send(messagePreparator);
} catch (MailException e) {
e.printStackTrace();
}
}
}
This is my Test Class
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(Application.class)
public class MailClientTest {
#Autowired
private MailClient mailClient;
private GreenMail smtpServer;
#Before
public void setUp() throws Exception {
smtpServer = new GreenMail(new ServerSetup(25, null, "smtp"));
smtpServer.start();
}
#Test
public void shouldSendMail() throws Exception {
//given
String recipient = "amadeu.cabanilles#gmail.com";
String message = "Test message content";
//when
mailClient.prepareAndSend(recipient, message);
//then
String content = "<span>" + message + "</span>";
assertReceivedMessageContains(content);
}
private void assertReceivedMessageContains(String expected) throws IOException, MessagingException {
MimeMessage[] receivedMessages = smtpServer.getReceivedMessages();
assertEquals(1, receivedMessages.length);
String content = (String) receivedMessages[0].getContent();
System.out.println(content);
assertTrue(content.contains(expected));
}
#After
public void tearDown() throws Exception {
smtpServer.stop();
}
}
Executing the Test in my computer is OK, I pass the test but I don't receive any email.

You don't receive any email because this integration test uses local testing SMTP server stub - GreenMail. The test doesn't send real emails, only verifies if the mail is prepared and sent correctly if a real SMTP server is available in the production.
In order to send emails from your local environment, you need to setup some SMTP server, but then, automated verification if the mail is actually sent is a completely different story.

Related

Connection closed: 1009 - Text message size [67000] exceeds maximum size [65536] websocketclient in spring boot 2.7

I am trying to send the websocket message larger than 65536 size and getting connection closed exception and error message.
**Connection closed: 1009 - Text message size [67000] exceeds maximum size [65536] **
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.websocketMaxTextClient</groupId>
<artifactId>websocketMaxTextClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>websocketMaxTextClient</name>
<description>Websocket response message limitation</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Websocket server configuration
#Component
public class WebsocketEndPoint extends TextWebSocketHandler{
private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
#Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws InterruptedException, IOException {
System.out.println("message : "+message.getPayload());
session.sendMessage(message);
}
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
session.setTextMessageSizeLimit(13900000);
System.out.println("textmessage limit : "+session.getTextMessageSizeLimit());
sessions.add(session);
super.afterConnectionEstablished(session);
}
#Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session);
super.afterConnectionClosed(session, status);
}
}
WebsocketConfig
#EnableWebSocket
#Configuration
public class WebsocketConfig implements WebSocketConfigurer {
#Autowired
private WebsocketEndPoint websocketEndPoint;
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(websocketEndPoint, "/web-socket").setHandshakeHandler(handshakeHandler());
}
public DefaultHandshakeHandler handshakeHandler() {
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
policy.setMaxTextMessageBufferSize(17981302);
policy.setMaxTextMessageSize(13800000);
policy.setMaxBinaryMessageBufferSize(18981302);
policy.setMaxBinaryMessageSize(15981302);
policy.setInputBufferSize( 15981302);
return new DefaultHandshakeHandler(
new JettyRequestUpgradeStrategy(new WebSocketServerFactory()));
}
#Bean
public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(1024*1024);
// container.setMaxBinaryMessageBufferSize(32768);
return container;
}
}
`
Websocket clientt code
#SpringBootApplication
public class WebsocketMaxTextClientApplication {
/*
* WebSocket client connection
*/
public static void main(String[] args) throws URISyntaxException, IOException {
String url = "ws://127.0.0.1:8082/web-socket";
WebSocketClient client = new WebSocketClient();
try
{
client.setMaxTextMessageBufferSize(13300000);
client.getPolicy().setMaxTextMessageSize(1329705);
client.getPolicy().delegateAs(WebSocketBehavior.CLIENT);
client.start();
URI echoUri = new URI(url);
ClientUpgradeRequest request = new ClientUpgradeRequest();
client.connect(socket, echoUri, request);
// wait for closed socket connection.
socket.awaitClose(5, TimeUnit.SECONDS);
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
try
{
client.stop();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
Websocketclient end point
#WebSocket
public class WebsocketMaxTextClientEndPoint {
private final CountDownLatch closeLatch;
#SuppressWarnings("unused")
private Session session;
public WebsocketMaxTextClientEndPoint()
{
this.closeLatch = new CountDownLatch(1);
}
public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException
{
return this.closeLatch.await(duration, unit);
}
#OnWebSocketClose
public void onClose(int statusCode, String reason)
{
System.out.printf("Connection closed: %d - %s%n", statusCode, reason);
this.session = null;
this.closeLatch.countDown(); // trigger latch
}
#OnWebSocketConnect
public void onConnect(Session session)
{
System.out.printf("Got connect: %s%n", session);
this.session = session;
try
{
session.getRemote().sendString("Thanks for the conversation.");
String json = randomString(67000);
System.out.println("default textmessage Length in websocket : "+session.getPolicy().getMaxTextMessageSize());
session.getRemote().sendString(json);
}
catch (Throwable t)
{
t.printStackTrace();
}
}
#OnWebSocketMessage
public void onMessage(String msg)
{
System.out.printf("Got msg: %s%n", msg);
}
#OnWebSocketError
public void onError(Throwable cause)
{
System.out.print("WebSocket Error: ");
cause.printStackTrace(System.out);
}
private String randomString(int size) {
return RandomStringUtils.random(size, true, true);
}
}
The log details are
Connection closed: 1009 - Text message size [67000] exceeds maximum size [65536]
10:12:19.175 [main] DEBUG org.eclipse.jetty.util.component.AbstractLifeCycle - stopping WebSocketClient#29c17a75[httpClient=HttpClient#614c5515{STARTED},openSessions.size=1]
10:12:19.175 [main] DEBUG org.eclipse.jetty.websocket.client.WebSocketClient - Stopping WebSocketClient#29c17a75[httpClient=HttpClient#614c5515{STARTED},openSessions.size=1]
10:12:19.175 [main] DEBUG org.eclipse.jetty.util.component.AbstractLifeCycle - stopping SessionTracker#548b7f67{STARTED}
10:12:19.175 [main] DEBUG org.eclipse.jetty.util.component.AbstractLifeCycle - stopping WebSocketSession[websocket=JettyAnnotatedEventDriver[com.websocketMaxTextClient.websocketMaxTextClient.endPoint.WebsocketMaxTextClientEndPoint#17c1bced],behavior=CLIENT,connection=WebSocketClientConnection#66e7e62f::SocketChannelEndPoint#7f4cda1a{l=/127.0.0.1:64098,r=/127.0.0.1:8082,OPEN,fill=-,flush=-,to=3/300000}{io=0/0,kio=0,kro=1}->WebSocketClientConnection#66e7e62f[s=ConnectionState#44b79a43[CLOSING],f=Flusher#21d129b1[IDLE][queueSize=0,aggregateSize=-1,terminated=null],g=Generator[CLIENT,validating],p=Parser#42399352[ExtensionStack,s=START,c=0,len=56,f=CLOSE[len=56,fin=true,rsv=...,masked=false]]],remote=WebSocketRemoteEndpoint#55dc6bce[batching=true],incoming=JettyAnnotatedEventDriver[com.websocketMaxTextClient.websocketMaxTextClient.endPoint.WebsocketMaxTextClientEndPoint#17c1bced],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]]
10:12:19.176 [main] DEBUG org.eclipse.jetty.websocket.common.WebSocketSession - stopping - WebSocketSession[websocket=JettyAnnotatedEventDriver[com.websocketMaxTextClient.websocketMaxTextClient.endPoint.WebsocketMaxTextClientEndPoint#17c1bced],behavior=CLIENT,connection=WebSocketClientConnection#66e7e62f::SocketChannelEndPoint#7f4cda1a{l=/127.0.0.1:64098,r=/127.0.0.1:8082,OPEN,fill=-,flush=-,to=4/300000}{io=0/0,kio=0,kro=1}->WebSocketClientConnection#66e7e62f[s=ConnectionState#44b79a43[CLOSING],f=Flusher#21d129b1[IDLE][queueSize=0,aggregateSize=-1,terminated=null],g=Generator[CLIENT,validating],p=Parser#42399352[ExtensionStack,s=START,c=0,len=56,f=CLOSE[len=56,fin=true,rsv=...,masked=false]]],remote=WebSocketRemoteEndpoint#55dc6bce[batching=true],incoming=JettyAnnotatedEventDriver[com.websocketMaxTextClient.websocketMaxTextClient.endPoint.WebsocketMaxTextClientEndPoint#17c1bced],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]]
10:12:19.176 [WebSocketClient#1632392469-20] DEBUG org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection - outgoingFrame(CLOSE[len=56,fin=true,rsv=...,masked=true], org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection$CallbackBridge#7ce49efe)
10:12:19.176 [main] DEBUG org.eclipse.jetty.websocket.common.WebSocketSession - callApplicationOnClose(CloseInfo[code=1006,reason=Disconnected])
10:12:19.176 [main] DEBUG org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection - CLIENT disconnect()
10:12:19.176 [WebSocketClient#1632392469-20] DEBUG org.eclipse.jetty.websocket.common.io.FrameFlusher - Enqueued FrameEntry[CLOSE[len=56,fin=true,rsv=...,masked=true],org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection$CallbackBridge#7ce49efe,OFF,null] to Flusher#21d129b1[IDLE][queueSize=1,aggregateSize=-1,terminated=null]
10:12:19.176 [main] DEBUG org.eclipse.jetty.websocket.common.io.FrameFlusher - Terminating Flusher#21d129b1[PROCESSING][queueSize=1,aggregateSize=-1,terminated=java.io.EOFException: Disconnected]
10:12:19.176 [WebSocketClient#1632392469-20] DEBUG org.eclipse.jetty.websocket.common.io.FrameFlusher - Flushing Flusher#21d129b1[PROCESSING][queueSize=1,aggregateSize=-1,terminated=java.io.EOFException: Disconnected]
10:12:19.176 [main] DEBUG org.eclipse.jetty.io.AbstractEndPoint - shutdownOutput SocketChannelEndPoint#7f4cda1a{l=/127.0.0.1:64098,r=/127.0.0.1:8082,OPEN,fill=-,flush=-,to=4/300000}{io=0/0,kio=0,kro=1}->WebSocketClientConnection#66e7e62f[s=ConnectionState#44b79a43[DISCONNECTED],f=Flusher#21d129b1[FAILED][queueSize=1,aggregateSize=-1,terminated=java.io.EOFException: Disconnected],g=Generator[CLIENT,validating],p=Parser#42399352[ExtensionStack,s=START,c=0,len=56,f=CLOSE[len=56,fin=true,rsv=...,masked=false]]]
10:12:19.179 [WebSocketClient#1632392469-20] DEBUG org.eclipse.jetty.websocket.common.WebSocketSession - callApplicationOnError()
java.io.EOFException: Disconnected
I want to send more than 10 MB data from websocket client to server.
Please help me, Tried to resolve it but unable to find the exact root cause.
Unable to send websocket client message larger than 65536 to websocket server in spring boot 2.7 and want to send 10 mb websocket client response to websocket server.Please provide solution, Thanks

The problem of connecting Apache Flink to elasticsearch

I used a piece of code inside the Flink site to connect Apache Flink to Elastic Search. I want to run this piece of code from NetBeans software through maven project.
public class FlinkElasticCon {
public static void main(String[] args) throws Exception {
final int port;
try {
final ParameterTool params = ParameterTool.fromArgs(args);
port = params.getInt("port");
} catch (Exception e) {
System.err.println("No port specified. Please run 'SocketWindowWordCount --port <port>'");
return;
}
// get the execution environment
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// get input data by connecting to the socket
DataStream<String> text = env.socketTextStream("localhost", port, "\n");
// parse the data, group it, window it, and aggregate the counts
DataStream<WordWithCount> windowCounts = text
.flatMap((String value, Collector<WordWithCount> out) -> {
for (String word : value.split("\\s")) {
out.collect(new WordWithCount(word, 1L));
}
})
.keyBy("word")
.timeWindow(Time.seconds(5))
.reduce(new ReduceFunction<WordWithCount>() {
#Override
public WordWithCount reduce(WordWithCount a, WordWithCount b) {
return new WordWithCount(a.word, a.count + b.count);
}
});
// print the results with a single thread, rather than in parallel
//windowCounts.print().setParallelism(1);
env.execute("Socket Window WordCount");
List<HttpHost> httpHosts = new ArrayList<>();
httpHosts.add(new HttpHost("127.0.0.1", 9200, "http"));
httpHosts.add(new HttpHost("10.2.3.1", 9200, "http"));
ElasticsearchSink.Builder<String> esSinkBuilder = new ElasticsearchSink.Builder<>(
httpHosts,
new ElasticsearchSinkFunction<String>() {
public IndexRequest createIndexRequest(String element) {
Map<String, String> json = new HashMap<>();
json.put("data", element);
return Requests
.indexRequest()
.index("my-index")
.type("my-type")
.source(json);
}
#Override
public void process(String element, RuntimeContext ctx, RequestIndexer indexer) {
indexer.add(createIndexRequest(element));
}
}
);
windowCounts.addSink((SinkFunction<WordWithCount>) esSinkBuilder);
}
public static class WordWithCount {
public String word;
public long count;
public WordWithCount() {}
public WordWithCount(String word, long count) {
this.word = word;
this.count = count;
}
#Override
public String toString() {
return word + " : " + count;
}
}
}
When adding Dependency, it does not identify the elasticsearchsink class. Given that I added different Dependency to it, but the problem is still not resolved. When importing :
import org.apache.flink.streaming.connectors.elasticsearch6.ElasticsearchSink
The red line is created as unknown in the code.
my pom:
<?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>org.apache.flink</groupId>
<artifactId>mavenproject1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-elasticsearch6_2.11</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<version>1.8.1</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-elasticsearch-base_2.11</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.0.0-alpha1</version>
<!--<version>6.0.0-alpha1</version>-->
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>1.8.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_2.11</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-core</artifactId>
<version>0.8.1</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
apache flink version : 1.8.1
elasticsearch version : 7.4.2
netbeans version : 8.2
java version : 8
please help me.
Flink Elasticsearch Connector 7
Please find a working and detailed answer which I have provided here.

#StreamListener not receiving message from kafka topic

I am able to send and receive the message using code:
#EnableBinding(Processor.class)
public class KafkaStreamsConfiguration {
#StreamListener(Processor.INPUT)
#SendTo(Processor.OUTPUT)
public String processMessage(String message) {
System.out.println("message = " + message);
return message.replaceAll("my", "your");
}
}
#RunWith(SpringRunner.class)
#SpringBootTest
#DirtiesContext
public class StreamApplicationIT {
private static String topicToPublish = "eventUpdateFromEventModel";
#BeforeClass
public static void setup() {
System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString());
}
#Autowired
private KafkaMessageSender<String> kafkaMessageSenderToTestErrors;
#Autowired
private KafkaMessageSender<EventNotificationDto> kafkaMessageSender;
#ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, topicToPublish);
#Autowired
private Processor pipe;
#Autowired
private MessageCollector messageCollector;
#Rule
public OutputCapture outputCapture = new OutputCapture();
#Test
public void working() {
pipe.input()
.send(MessageBuilder.withPayload("This is my message")
.build());
Object payload = messageCollector.forChannel(pipe.output())
.poll()
.getPayload();
assertEquals("This is your message", payload.toString());
}
#Test
public void non_working() {
kafkaMessageSenderToTestErrors.send(topicToPublish, "This was my message");
assertTrue(isMessageReceived("This was your message", 50));
}
private boolean isMessageReceived(final String msg, final int maxAttempt) {
return IntStream.rangeClosed(0, maxAttempt)
.peek(a -> {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
fail();
}
}).anyMatch(i -> outputCapture.toString().contains(msg));
}
}
#Service
#Slf4j
public class KafkaMessageSender<T> {
private final KafkaTemplate<String, byte[]> kafkaTemplate;
private final ObjectWriter objectWriter;
public KafkaMessageSender(KafkaTemplate<String, byte[]> kafkaTemplate, ObjectMapper objectMapper) {
this.kafkaTemplate = kafkaTemplate;
this.objectWriter = objectMapper.writer();
}
public void send(String topicName, T payload) {
try {
kafkaTemplate.send(topicName, objectWriter.writeValueAsString(payload).getBytes());
} catch (JsonProcessingException e) {
log.info("error converting object into byte array {}", payload.toString().substring(0, 50));
}
log.info("sent payload to topic='{}'", topicName);
}
}
But when I send the message using kafkaTemplate to any topic, StreamListener doesn't receive the message.
spring.cloud.stream.bindings.input.group=test
spring.cloud.stream.bindings.input.destination=eventUpdateFromEventModel
my pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring boot version -->
<spring.boot.version>1.5.7.RELEASE</spring.boot.version>
<spring-cloud.version>Edgware.SR3</spring-cloud.version>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<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>
working
Object payload = messageCollector.forChannel(pipe.output())
.poll()
.getPayload();
...
not working
KafkaTemplate
This is because you are using the TestBinder in your test, not the real Kafka broker and kafka binder.
The message collector is simply fetching it from the channel. If you want to test with a real Kafka broker, see the test-embedded-kafka sample app.
EDIT
I just tested the Ditmars (boot 1.5.x) version of the sample and it works fine...

XA resource has become unavailable XID raised -7

I am getting below error in a random way. It doesn't throw error initially but after a while the error is thrown. Once I restart my server everything gets reset and error is not thrown.
XA resource 'XXXXAtomikosDataSource': resume for XID '31302E3137382E36382E3235302E746D30303031353030303138:31302E3137382E36382E3235302E746D3135' raised -7: the XA resource has become unavailable
I am using below dependencies.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
And with configuration beans
#Bean(name= "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
return userTransactionImp;
}
#Bean
#Primary
public TransactionManager atomTransactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
#Bean("atomikosTransactionManager")
public PlatformTransactionManager platformTransactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
TransactionManager transactionManager = atomTransactionManager();
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, transactionManager);
jtaTransactionManager.setAllowCustomIsolationLevels(true);
jtaTransactionManager.setDefaultTimeout(1000);
return jtaTransactionManager;
}
#Bean(name = "atomikosDataSources")
public Map<String, DataSource> atomikosDataSources(PropertiesFactoryBean databaseProperties, Environment environment, BcusDefaultEncrytor bcusDefaultEncrytor) throws SQLException, IOException {
List<String> databases= Collections.list(databaseProperties.getObject().propertyNames()).stream().map(key->key.toString()).filter(key-> key.contains("url")).collect(Collectors.toList());
Map<String, DataSource> collect = databases.stream().collect(Collectors.toMap(dbName -> dbName.split("\\.")[0].toUpperCase() + "AtomikosDataSource", dbName -> {
OracleXADataSource dataSource = null;
try {
dataSource = new OracleXADataSource();
dataSource.setURL(environment.getProperty(dbName));
dataSource.setUser(environment.getProperty("database.username"));
dataSource.setPassword(bcusDefaultEncrytor.decryptQAPassword(environment.getProperty("database.password")));
}
catch (SQLException e)
{
LOG.error(
"DatabaseConditionException [errorCode= Error while configuring atomikos data sources- Could not OracleXADataSource object, errorMessage= {} ]",
e.getMessage());
}
catch (Exception e) {
LOG.error(
"DatabaseConditionException [errorCode= Error while configuring atomikos data sources- Could not decrypt QA Password make sure you have proper **QA** Encryption password in your folder, errorMessage= {} ]",
e.getMessage());
}
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(dataSource);
xaDataSource.setUniqueResourceName(dbName.split("\\.")[0].toUpperCase() + "AtomikosDataSource");
xaDataSource.setPoolSize(5);
return xaDataSource;
}));
return collect;
}
The issue is because of a bug in atomikos 3.9.3 version in spring-boot-starter-jta-atomikos brings:1.4.2.RELEASE.
Once you update the version to atomikos 4.0.4, the issue resolves.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<exclusions>
<exclusion>
<artifactId>transactions-jdbc</artifactId>
<groupId>com.atomikos</groupId>
</exclusion>
<exclusion>
<artifactId>transactions-jms</artifactId>
<groupId>com.atomikos</groupId>
</exclusion>
<exclusion>
<artifactId>transactions-jta</artifactId>
<groupId>com.atomikos</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jms</artifactId>
<version>${transaction.version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${transaction.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.0.1B_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>${transaction.version}</version>
</dependency>

STOMP in Spring WebSocket Lost Connection before connected

I try to connect with server by STOMP, but I get Lost Connection message with any specific information.
WebSocket config:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/topic", "/queve")
.setClientLogin("quest")
.setClientPasscode("quest");
registry.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/hello").setAllowedOrigins("*").withSockJS();
}
}
Controller:
#Controller
public class HelloController {
#MessageMapping("/hello")
public void greeting(HelloMessage message){
System.out.println("Wiadomosc: " + message.getName());
}
#SubscribeMapping({"/helloSub"})
public HelloMessage handleSubscription() {
HelloMessage outgoing = new HelloMessage();
System.out.println("SUB");
outgoing.setName("Jas");
return outgoing;
}
}
js script:
var sock = new SockJS("http://localhost:8080/BuyMyTime/hello");
var stomp = Stomp.over(sock);
var payload = JSON.stringify({'name':'Jasiek'});
stomp.connect('quest', 'quest', function(frame){
//stomp.send("/hello", {}, payload);
});
When i send get http://localhost:8080/BuyMyTime/hello i receive: Welcome to SockJS! so Socket is fine but when i try stomp.connect i receive:
Opening Web Socket... stomp.js:134:99
Web Socket Opened... stomp.js:134:99
>>> CONNECT
login:quest
passcode:quest
accept-version:1.1,1.0
heart-beat:10000,10000
"Whoops! Lost connection to http://localhost:8080/BuyMyTime/hello" stomp.js:134:99
Is there any missing config i did not included? How can I get more info about this connection lost? Please for any help.
Update (Aug 28 2016)
I add this dependencies:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
and now get:
<<< ERROR
message:Broker not available.
content-length:0
"Whoops! Lost connection to http://localhost:8080/BuyMyTime/greeting"

Categories