package org.jentrata.ebms.messaging.internal;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.commons.io.IOUtils;
import org.h2.jdbcx.JdbcConnectionPool;
import org.jentrata.ebms.EbmsConstants;
import org.jentrata.ebms.MessageStatusType;
import org.jentrata.ebms.MessageType;
import org.jentrata.ebms.messaging.Message;
import org.jentrata.ebms.messaging.MessageStore;
import org.jentrata.ebms.messaging.UUIDGenerator;
import org.jentrata.ebms.messaging.internal.sql.RepositoryManagerFactory;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
/**
* unit test for org.jentrata.ebms.messaging.internal.JDBCMessageStore
*
* @author aaronwalker
*/
public class JDBCMessageStoreTest extends CamelTestSupport {
private JdbcConnectionPool dataSource;
private JDBCMessageStore messageStore;
@Test
public void testShouldCreateMessageStoreTablesByDefault() throws Exception {
try(Connection conn = dataSource.getConnection()) {
try (Statement st = conn.createStatement()) {
assertTableGotCreated(st,"repository");
assertTableGotCreated(st,"message");
}
}
}
@Test
public void testShouldStoreMimeMessage() throws Exception {
File body = fileFromClasspath("simple-as4-receipt.xml");
String contentType = "Multipart/Related; boundary=\"----=_Part_7_10584188.1123489648993\"; type=\"application/soap+xml\"; start=\"<soapPart@jentrata.org>\"";
String messageId = "testMimeMessage1";
assertStoredMessage(messageId, contentType, body, MessageType.USER_MESSAGE);
}
@Test
public void testShouldStoreSoapMessage() throws Exception {
String contentType = "application/soap+xml";
File body = fileFromClasspath("simple-as4-receipt.xml");
String messageId = "testSoapMessage1";
assertStoredMessage(messageId, contentType, body, MessageType.SIGNAL_MESSAGE_WITH_USER_MESSAGE);
}
@Test
public void testUpdateStoreMimeMessage() throws Exception {
File body = fileFromClasspath("simple-as4-receipt.xml");
String contentType = "Multipart/Related; boundary=\"----=_Part_7_10584188.1123489648993\"; type=\"application/soap+xml\"; start=\"<soapPart@jentrata.org>\"";
String messageId = "testMimeMessage1";
assertStoredMessage(messageId, contentType, body, MessageType.USER_MESSAGE);
messageStore.updateMessage(messageId, EbmsConstants.MESSAGE_DIRECTION_INBOUND, MessageStatusType.RECEIVED,"Message Received");
try(Connection conn = dataSource.getConnection()) {
try (PreparedStatement st = conn.prepareStatement("select * from message where message_id = ?")) {
st.setString(1,messageId);
ResultSet resultSet = st.executeQuery();
assertThat(resultSet.next(),is(true));
assertThat(resultSet.getString("status"),equalTo("RECEIVED"));
assertThat(resultSet.getString("status_description"),equalTo("Message Received"));
}
}
}
@Test
public void testFindByMessageId() throws Exception {
String contentType = "application/soap+xml";
File body = fileFromClasspath("simple-as4-receipt.xml");
String messageId = "testSoapMessage1";
assertStoredMessage(messageId, contentType, body, MessageType.SIGNAL_MESSAGE_WITH_USER_MESSAGE);
messageStore.updateMessage(messageId, EbmsConstants.MESSAGE_DIRECTION_INBOUND, MessageStatusType.RECEIVED,"Message Received");
Message message = messageStore.findByMessageId("testSoapMessage1",EbmsConstants.MESSAGE_DIRECTION_INBOUND);
assertThat(message,notNullValue());
assertThat(message.getMessageId(),equalTo("testSoapMessage1"));
assertThat(message.getStatus(),equalTo(MessageStatusType.RECEIVED));
assertThat(message.getStatusDescription(),equalTo("Message Received"));
}
@Test
public void testFindPayloadById() throws Exception {
testFindByMessageId();
InputStream stream = messageStore.findPayloadById("testSoapMessage1");
assertThat(stream,notNullValue());
assertThat(IOUtils.toString(stream),equalTo(IOUtils.toString(new FileInputStream(fileFromClasspath("simple-as4-receipt.xml")))));
}
@Test
public void testFindMessageByStatus() throws Exception {
testFindByMessageId();
List<Message> messages = messageStore.findByMessageStatus(EbmsConstants.MESSAGE_DIRECTION_INBOUND,MessageStatusType.RECEIVED.name());
assertThat(messages,notNullValue());
assertThat(messages,hasSize(1));
Message message = messages.get(0);
assertThat(message,notNullValue());
assertThat(message.getMessageId(),equalTo("testSoapMessage1"));
assertThat(message.getStatus(),equalTo(MessageStatusType.RECEIVED));
assertThat(message.getStatusDescription(),equalTo("Message Received"));
}
@Test
public void testDuplicateMessage() throws Exception{
File body = fileFromClasspath("simple-as4-receipt.xml");
String contentType = "Multipart/Related; boundary=\"----=_Part_7_10584188.1123489648993\"; type=\"application/soap+xml\"; start=\"<soapPart@jentrata.org>\"";
String messageId = "testMimeMessage1";
assertStoredMessage(messageId, contentType, body, MessageType.USER_MESSAGE);
Exchange response = assertStoredMessage(messageId, contentType, body, MessageType.USER_MESSAGE);
assertThat(response.getIn().getHeader(EbmsConstants.DUPLICATE_MESSAGE,boolean.class),is(true));
assertThat(response.getIn().getHeader(EbmsConstants.MESSAGE_ID,String.class),is(messageId));
assertThat(response.getIn().getHeader(EbmsConstants.DUPLICATE_MESSAGE_ID,String.class),notNullValue());
}
private Exchange assertStoredMessage(String messageId, String contentType, File body, MessageType messageType) throws SQLException, IOException {
Exchange request = new DefaultExchange(context());
request.getIn().setHeader(EbmsConstants.EBMS_VERSION,EbmsConstants.EBMS_V3);
request.getIn().setHeader(EbmsConstants.MESSAGE_ID,messageId);
request.getIn().setHeader(EbmsConstants.MESSAGE_DIRECTION,EbmsConstants.MESSAGE_DIRECTION_INBOUND);
request.getIn().setHeader(EbmsConstants.MESSAGE_TYPE,messageType);
request.getIn().setHeader(EbmsConstants.CONTENT_TYPE,contentType);
request.getIn().setHeader(EbmsConstants.CPA_ID,"testCPAId");
request.getIn().setBody(body);
Exchange response = context().createProducerTemplate().send(MessageStore.DEFAULT_MESSAGE_STORE_ENDPOINT,request);
messageId = response.getIn().getHeader(EbmsConstants.MESSAGE_ID,String.class);
try(Connection conn = dataSource.getConnection()) {
try (PreparedStatement st = conn.prepareStatement("select * from repository where message_id = ?")) {
st.setString(1,messageId);
ResultSet resultSet = st.executeQuery();
assertThat(resultSet.next(),is(true));
assertThat(resultSet.getString("message_box"),equalTo(EbmsConstants.MESSAGE_DIRECTION_INBOUND));
assertThat(resultSet.getString("content_type"),equalTo(contentType));
assertThat(resultSet.getDate("time_stamp"),notNullValue());
assertThat(IOUtils.toString(resultSet.getBinaryStream("content")),equalTo(IOUtils.toString(new FileInputStream(body))));
}
try (PreparedStatement st = conn.prepareStatement("select * from message where message_id = ?")){
st.setString(1,messageId);
ResultSet resultSet = st.executeQuery();
assertThat(resultSet.next(),is(true));
assertThat(resultSet.getString("message_box"),equalTo(EbmsConstants.MESSAGE_DIRECTION_INBOUND));
assertThat(resultSet.getString("message_type"),equalTo(messageType.name()));
assertThat(resultSet.getString("cpa_id"),equalTo("testCPAId"));
assertThat(resultSet.getDate("time_stamp"),notNullValue());
}
}
return response;
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
dataSource = JdbcConnectionPool.create("jdbc:h2:mem:" + getTestMethodName(), "sa", "sa");
assertThatTableDoesNotExist("repository");
RepositoryManagerFactory repositoryManagerFactory = new RepositoryManagerFactory();
repositoryManagerFactory.setDataSource(dataSource);
messageStore = new JDBCMessageStore();
messageStore.setUuidGenerator(new UUIDGenerator());
messageStore.setRepositoryManager(repositoryManagerFactory.createRepositoryManager());
messageStore.init();
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from(MessageStore.DEFAULT_MESSAGE_STORE_ENDPOINT)
.bean(messageStore,"store")
.bean(messageStore,"storeMessage")
.routeId("testPostsgresMessageStore");
}
};
}
private void assertThatTableDoesNotExist(String tableName) throws SQLException {
try(Connection conn = dataSource.getConnection()) {
try (Statement st = conn.createStatement()) {
ResultSet resultSet = st.executeQuery("select count(*) from " + tableName);
fail("DB tables shouldn't exists");
} catch (SQLException ex) {
}
}
}
private static void assertTableGotCreated(Statement st, String tableName) throws SQLException {
ResultSet resultSet = st.executeQuery("select count(*) from " + tableName);
assertThat(resultSet.next(),is(true));
assertThat(resultSet.getInt(1), equalTo(0));
}
protected static File fileFromClasspath(String filename) {
File file = new File(Thread.currentThread().getContextClassLoader().getResource(filename).getFile());
return file;
}
}