/** * */ package hk.hku.cecid.edi.sfrm.handler; import org.junit.Assert; import org.junit.Test; import java.security.cert.X509Certificate; import java.util.Map; import hk.hku.cecid.edi.sfrm.spa.SFRMException; import hk.hku.cecid.edi.sfrm.dao.ds.SFRMPartnershipDSDVO; import hk.hku.cecid.edi.sfrm.handler.OutgoingMessageHandler; import hk.hku.cecid.edi.sfrm.pkg.SFRMHeader; import hk.hku.cecid.edi.sfrm.pkg.SFRMMessage; import hk.hku.cecid.edi.sfrm.pkg.SFRMConstant; import hk.hku.cecid.edi.sfrm.pkg.SFRMMessageException; import hk.hku.cecid.edi.sfrm.handler.SFRMMessageFactory; import hk.hku.cecid.piazza.commons.net.ConnectionException; import hk.hku.cecid.piazza.commons.security.KeyStoreManager; import hk.hku.cecid.piazza.commons.security.SMimeException; import hk.hku.cecid.piazza.commons.security.SMimeMessage; import hk.hku.cecid.piazza.commons.test.SystemComponentTest; import hk.hku.cecid.piazza.commons.test.utils.SimpleHttpMonitor; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Method; /** * @author Patrick Yip * */ public class OutgoingMessageHandlerTest extends SystemComponentTest<OutgoingMessageHandler> { private OutgoingMessageHandler outHandler; // testing data private SimpleHttpMonitor mock; private int mockPort = 9000; private String mockEndpoint = "http://localhost:" + mockPort; private String partnershipId = "loopback"; private String messageId = "messageId"; private String filename = "file.tar"; private int totalSegment = 1; private long totalSize = 1024; private String contentType = "text/plain"; private String messageContent = "Hello World!!!"; private String publicCertMD5 = "3D0483C7D74BC9894B7667ECB5A121A108E01629"; @Override public String getSystemComponentId() { return "outgoing-message-handler"; } @Override public void setUp() throws Exception { outHandler = (OutgoingMessageHandler)TARGET; } @Override public void tearDown() throws Exception { } // TODO: suppose in test case SFRMMessageFactoryTest @Test public void testCreateHandshakingRequest() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); // why message id need to be <messageId> ? Assert.assertEquals("Message-Id should be " + messageId, messageId, (String)message.getHeader(SFRMHeader.MESSAGE_ID)); Assert.assertEquals("Partnership-Id should be " + partnershipId, partnershipId, (String)message.getHeader(SFRMHeader.SFRM_PARTNERSHIP)); Assert.assertEquals("Segment-Type should be META", SFRMConstant.MSGT_META, message.getHeader(SFRMHeader.SFRM_SEGMENT_TYPE)); //TODO: To see why the assertion fail on the following Assert.assertEquals("Segment No should be 0", 0, Integer.parseInt(message.getHeader(SFRMHeader.SFRM_SEGMENT_NO))); Assert.assertEquals("Total number of segment should be " + totalSegment, totalSegment, Integer.parseInt(message.getHeader(SFRMHeader.SFRM_META_TOTAL_SEGMENT))); Assert.assertEquals("Total size of segment should be " + totalSize, totalSize, Long.parseLong(message.getHeader(SFRMHeader.SFRM_TOTAL_SIZE))); Assert.assertEquals("Filename should be " + filename, filename, message.getHeader(SFRMHeader.SFRM_FILENAME)); } @Test public void testMetaMessgeHeader() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); outHandler.packOutgoingMessage(message, null, null, null); // why message id need to be <messageId> ? Assert.assertEquals("Message-Id should be " + messageId, messageId, (String)message.getHeader(SFRMHeader.MESSAGE_ID)); Assert.assertEquals("Partnership-Id should be " + partnershipId, partnershipId, (String)message.getHeader(SFRMHeader.SFRM_PARTNERSHIP)); Assert.assertEquals("Segment-Type should be META", SFRMConstant.MSGT_META, message.getHeader(SFRMHeader.SFRM_SEGMENT_TYPE)); //TODO: To see why the assertion fail on the following Assert.assertEquals("Segment No should be 0", 0, Integer.parseInt(message.getHeader(SFRMHeader.SFRM_SEGMENT_NO))); Assert.assertEquals("Total number of segment should be " + totalSegment, totalSegment, Integer.parseInt(message.getHeader(SFRMHeader.SFRM_META_TOTAL_SEGMENT))); Assert.assertEquals("Total size of segment should be " + totalSize, totalSize, Long.parseLong(message.getHeader(SFRMHeader.SFRM_TOTAL_SIZE))); Assert.assertEquals("Filename should be " + filename, filename, message.getHeader(SFRMHeader.SFRM_FILENAME)); } @Test public void testPlainMetaMessge() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent("Hello World!!!", contentType); outHandler.packOutgoingMessage(message, null, null, null); SFRMMessage newMsg = new SFRMMessage(message.getHeaders(), message.getContentStream()); Assert.assertTrue("Message type should be META", newMsg.getClassifier().isMeta()); Assert.assertFalse("Message should be unsigned", newMsg.getClassifier().isSigned()); Assert.assertFalse("Message should be unencrypted", newMsg.getClassifier().isEncrypted()); Assert.assertTrue("Incorrect message content", messageContent.equals(newMsg.getContent())); } @Test public void testSignMD5MetaMessge() throws Exception { LOG.info("testSignMessge"); SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); outHandler.packOutgoingMessage(message, "md5", null, null); KeyStoreManager keyman = outHandler.getKeyStoreManager(); SMimeMessage smime = new SMimeMessage( message.getBodyPart(), keyman.getX509Certificate(), keyman.getPrivateKey()); Assert.assertTrue("Message should be signed", smime.isSigned()); Assert.assertFalse("Message should be not encrypted", smime.isEncrypted()); try { smime = smime.verify(); } catch (SMimeException sme) { Assert.fail("Signature verification error"); } Assert.assertTrue("Incorrect message content", messageContent.equals(smime.getBodyPart().getContent())); } @Test public void testSignSHA1MetaMessge() throws Exception { LOG.info("testSignMessge"); SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); outHandler.packOutgoingMessage(message, "sha1", null, null); KeyStoreManager keyman = outHandler.getKeyStoreManager(); SMimeMessage smime = new SMimeMessage( message.getBodyPart(), keyman.getX509Certificate(), keyman.getPrivateKey()); Assert.assertTrue("Message should be signed", smime.isSigned()); Assert.assertFalse("Message should be unencrypted", smime.isEncrypted()); try { smime = smime.verify(); } catch (SMimeException sme) { Assert.fail("Signature verification error"); } Assert.assertTrue("Incorrect message content", messageContent.equals(smime.getBodyPart().getContent())); } @Test(expected=SMimeException.class) public void testSignMetaMessgeFailed() throws Exception { LOG.info("testSignMessge"); SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); outHandler.packOutgoingMessage(message, "sha1", null, null); SMimeMessage smime = new SMimeMessage(message.getBodyPart()); Assert.assertTrue("Message should be signed", smime.isSigned()); Assert.assertFalse("Message should be unencrypted", smime.isEncrypted()); smime = smime.verify(); } @Test public void testEncryptDES3MetaMessge() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); Method m = SFRMPartnershipDSDVO.class.getDeclaredMethod("getX509Certificate", File.class); m.setAccessible(true); X509Certificate cert = (X509Certificate)m.invoke(new SFRMPartnershipDSDVO(), new File(FIXTURE_LOADER.getResource(publicCertMD5).getFile())); outHandler.packOutgoingMessage(message, null, "3des", cert); KeyStoreManager keyman = outHandler.getKeyStoreManager(); SMimeMessage smime = new SMimeMessage( message.getBodyPart(), keyman.getX509Certificate(), keyman.getPrivateKey()); Assert.assertFalse("Message should be signed", smime.isSigned()); Assert.assertTrue("Message should be unencrypted", smime.isEncrypted()); try { smime = smime.decrypt(); } catch (SMimeException sme) { Assert.fail("Decryption error"); } Assert.assertTrue("Incorrect message content", messageContent.equals(smime.getBodyPart().getContent())); } @Test public void testEncryptRC2MetaMessge() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); Method m = SFRMPartnershipDSDVO.class.getDeclaredMethod("getX509Certificate", File.class); m.setAccessible(true); X509Certificate cert = (X509Certificate)m.invoke(new SFRMPartnershipDSDVO(), new File(FIXTURE_LOADER.getResource(publicCertMD5).getFile())); outHandler.packOutgoingMessage(message, null, "rc2", cert); KeyStoreManager keyman = outHandler.getKeyStoreManager(); SMimeMessage smime = new SMimeMessage( message.getBodyPart(), keyman.getX509Certificate(), keyman.getPrivateKey()); Assert.assertFalse("Message should be signed", smime.isSigned()); Assert.assertTrue("Message should be unencrypted", smime.isEncrypted()); try { smime = smime.decrypt(); } catch (SMimeException sme) { Assert.fail("Decryption error"); } Assert.assertTrue("Incorrect message content", messageContent.equals(smime.getBodyPart().getContent())); } @Test(expected=SMimeException.class) public void testEncryptMetaMessgeFailed() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); Method m = SFRMPartnershipDSDVO.class.getDeclaredMethod("getX509Certificate", File.class); m.setAccessible(true); X509Certificate cert = (X509Certificate)m.invoke(new SFRMPartnershipDSDVO(), new File(FIXTURE_LOADER.getResource(publicCertMD5).getFile())); outHandler.packOutgoingMessage(message, null, "rc2", cert); SMimeMessage smime = new SMimeMessage(message.getBodyPart()); Assert.assertFalse("Message should be signed", smime.isSigned()); Assert.assertTrue("Message should be unencrypted", smime.isEncrypted()); smime = smime.decrypt(); } @Test public void testSignEncryptMetaMessge() throws Exception { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); Method m = SFRMPartnershipDSDVO.class.getDeclaredMethod("getX509Certificate", File.class); m.setAccessible(true); X509Certificate cert = (X509Certificate)m.invoke(new SFRMPartnershipDSDVO(), new File(FIXTURE_LOADER.getResource(publicCertMD5).getFile())); outHandler.packOutgoingMessage(message, "md5", "3des", cert); KeyStoreManager keyman = outHandler.getKeyStoreManager(); SMimeMessage smime = new SMimeMessage( message.getBodyPart(), keyman.getX509Certificate(), keyman.getPrivateKey()); // signature is also encrypted Assert.assertTrue("Message should be unencrypted", smime.isEncrypted()); try { smime = smime.decrypt(); Assert.assertTrue("Message should be signed", smime.isSigned()); smime = smime.verify(); } catch (SMimeException sme) { Assert.fail("Signature vertification / decryption error"); } Assert.assertTrue("Incorrect message content", messageContent.equals(smime.getBodyPart().getContent())); } /** * Test for sending the handshaking message * @throws ConnectionException * @throws SFRMMessageException * @throws Exception */ @Test public void testSendMetaMessage() throws SFRMMessageException, ConnectionException { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); mock = new SimpleHttpMonitor(mockPort); mock.start(); outHandler.sendMessage(message, mockEndpoint, false, null, null, null); Map headers = mock.getHeaders(); Assert.assertEquals("Message-Id should be " + messageId, messageId, (String)headers.get(SFRMHeader.MESSAGE_ID)); Assert.assertEquals("Partnership-Id should be " + partnershipId, partnershipId, (String)headers.get(SFRMHeader.SFRM_PARTNERSHIP)); Assert.assertEquals("Segment-Type should be META", SFRMConstant.MSGT_META, headers.get(SFRMHeader.SFRM_SEGMENT_TYPE)); //TODO: To see why the assertion fail on the following Assert.assertEquals("Segment No should be 0", 0, Integer.parseInt((String)headers.get(SFRMHeader.SFRM_SEGMENT_NO))); Assert.assertEquals("Total number of segment should be " + totalSegment, totalSegment, Integer.parseInt((String)headers.get(SFRMHeader.SFRM_META_TOTAL_SEGMENT))); Assert.assertEquals("Total size of segment should be " + totalSize, totalSize, Long.parseLong((String)headers.get(SFRMHeader.SFRM_TOTAL_SIZE))); Assert.assertEquals("Content-Type not match", contentType, (String)headers.get("Content-Type")); Assert.assertEquals("Filename should be " + filename, filename, headers.get(SFRMHeader.SFRM_FILENAME)); mock.stop(); } /** * Test for sending the handshaking message * @throws SFRMMessageException * @throws SFRMException * @throws ConnectionException * @throws SFRMMessageException * @throws Exception */ @Test(expected=ConnectionException.class) public void testOutgoingMetaMessageFail() throws SFRMMessageException, ConnectionException { SFRMMessage message = SFRMMessageFactory.getInstance(). createHandshakingRequest(messageId, partnershipId, totalSegment, totalSize, filename); message.setContent(messageContent, contentType); //Setting the mock http server mock = new SimpleHttpMonitor(mockPort) { protected void onResponse(final OutputStream out) throws IOException{ out.write(("HTTP/1.1 400 Bad Request" + CRLF).getBytes()); out.write(("Server: SFRM Mock Server" + CRLF).getBytes()); out.write(("Content-Length: 0" + CRLF).getBytes()); out.write(("Content-Type: text/plain" + CRLF + CRLF).getBytes()); } }; mock.start(); outHandler.sendMessage(message, mockEndpoint, false, null, null, null); mock.stop(); } }