Enhancements to Testing and JSSE Debugging in Camel 2.10

While testing and security are often the last to get invited to the party, they are integral parts of well written software.  Two new features in Camel 2.10 help to ease debugging of TLS related security issues and to provide full support for writing unit tests of Camel routes in Spring Test.  While these two new features aren’t likely to make TLS configuration and unit testing the king and queen of prom, they will make you a more productive Camel rider.

Spring Test

CamelTestSupport provides a number of value-added features for JUnit and TestNG based unit tests involving Camel routes.  These features include activities like starting a CamelContext, reducing the shutdown timeout for the context to a small value for testing, and the enabling and disabling of aspects of the CamelContext to speed up test execution and loading.  These value-added features reduce the amount of boilerplate code that needs to be maintained when writing unit tests for Camel routes.  CamelSpringTestSupport provides these same value added features while also allowing the loading of a Spring context from XML resources.  While Spring provides a set of annotations to support declarative configuration of unit tests involving Spring contexts in Spring Test, CamelSpringTestSupport leverages a collection of methods that must be overridden in sub-classes and generally do not follow the pattern that Spring Test users are accustomed to.  Camel 2.10 introduces Camel Enhanced Spring Test.  This new feature provides all of the capabilities of CamelSpringTestSupport through a set of annotations.  These annotations allow developers confortable with Spring Test to take advantage of the features of CamelSpringTestSupport in an entirely declarative manner.  When using the annotations, developers can reduce the amount of code written and can generally avoid needing to sub-class Camel specific test classes.  The following code snippets demonstrate the same unit test written using CamelSpringTestSupport and the new Camel Enhanced Spring Test capabilities.

In both examples, Camel’s auto-mocking capability is used to mock the bean endpoint in the Spring DSL defined route.  The auto-mock expectations are set and verified during the test execution.  The primary differences between the two test implementations is the use of annotation driven test configuration in the Spring Test based example.  This new feature aims to provide an easy transition into Camel route testing for developers comfortable with Spring Test.  Additionally, the more advanced capabilities of Spring Test may also be leveraged for more complex test cases.  The source code for both examples is available in my Google Code repository.

CamelSpringTestSupport

public class ExampleRouteBuilderSpringTestSupportTest extends CamelSpringTestSupport {

    @Produce(uri = "direct:input")
    protected ProducerTemplate inputProducerTemplate;

    @EndpointInject(uri = "mock:bean:exampleBean")
    protected MockEndpoint mockBeanExampleBean;

    @Test
    public void testRoute() throws Exception {
        mockBeanExampleBean.expectedBodiesReceived("Hello Bob");

        inputProducerTemplate.sendBody("Bob");

        assertMockEndpointsSatisfied();
    }

    @Override
    public String isMockEndpoints() {
        return "bean:exampleBean";
    }

    @Override
    protected AbstractApplicationContext createApplicationContext() {
        return new ClassPathXmlApplicationContext("classpath:valeri/blog/examples/camel2_10/ExampleSpringContext.xml");
    }
}
  • Line 1 – Extends org.apache.camel.test.junit4.CamelSpringTestSupport to provide support for testing Spring based Camel routes and/or Spring based registries.
  • Lines 19-21 – Overrides the isMockEndpoints method to return the pattern for automatically mocked endpoints.
  • Lines 24-26 – Implements the createApplicationContext method to return the Spring application context used in the test.

Camel Enhanced Spring Test

@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:valeri/blog/examples/camel2_10/ExampleSpringContext.xml")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@MockEndpoints("bean:exampleBean")
public class ExampleRouteBuilderEnhancedSpringTest {

    @Autowired
    protected CamelContext context;

    @Produce(uri = "direct:input")
    protected ProducerTemplate inputProducerTemplate;

    @EndpointInject(uri = "mock:bean:exampleBean")
    protected MockEndpoint mockBeanExampleBean;

    @Test
    public void testRoute() throws Exception {
        mockBeanExampleBean.expectedBodiesReceived("Hello Bob");

        inputProducerTemplate.sendBody("Bob");

        MockEndpoint.assertIsSatisfied(context);
    }
}
  • Line 1 – Instructs JUnit 4 to use the org.apache.camel.test.junit4.CamelSpringJUnit4ClassRunner implementation for running tests.  This implementation provides the integration between JUnit, Camel, and Spring Test.
  • Line 2 – Indicates where the Spring XML file is located.  This annotation can also support non-XML based Spring context definitions as well.  This annotation takes the place of createApplicationContext method in CamelSpringTestSupport style tests.
  • Line 3 – Indicates that the Spring Context, and consequently the Camel Context should be recreated between each test method to ensure that the test cases are independent of each other.
  • Line 4 – Indicates to Camel Enhanced Spring Test that the endpoints matching the pattern should automatically be mocked during test execution.  This annotation takes the place of the isMockEndpoints method in CamelSpringTestSupport style tests.

Enhanced TLS/SSL Logging with the Camel SSL Configuration Utility

Simplified TLS/SSL configuration was added to Camel 2.8; however, this simplified configuration did not aid in debugging runtime issues with the resulting SSL context, factories, and sockets.  Camel 2.10 introduces detailed log output any time a socket or server socket is instantiated from an SSLContext configured from SSLContextParameters.  This debugging output is particularly useful as sockets are often instantiated deep inside of third-party libraries and are often inaccessible to code written by Camel users.  The ability to debug runtime TLS configuration through detailed logging means that you don’t have to step through piles of code you didn’t write with a debugger just to find the cause of your TLS problems.  To enable the improved debug output, configure your logging library to log at the debug level for the logger with the name log4j.logger.org.apache.camel.util.jsse.  The following configuration fragment demonstrates this configuration using Log4J’s properties file syntax.

log4j.logger.org.apache.camel.util.jsse=DEBUG

Once you have enabled debug logging, any socket created from an SSLContextParameters will result in output similar to that shown below.  The output indicates all configuration values in play for the socket, the initial state of the socket when created, and the resulting state after it was reconfigured to match the user provided configuration options.  Additional logging is also available at the trace level.

2012-07-13 18:18:30,894 [main           ] DEBUG BaseSSLContextParameters       - Configuring SSLSocket [669a4cb[SSL_NULL_WITH_NULL_NULL: Socket[unconnected]]] with 
	 explicitly set cipher suites [null],
	 cipher suite patterns [null],
	 available cipher suites [[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]],
	 currently enabled cipher suites [[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]],
	 and default cipher suite patterns [Patterns [includes=[.*], excludes=[.*_NULL_.*, .*_anon_.*]]].
	 Resulting enabled cipher suites are [[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]].
2012-07-13 18:18:30,894 [main           ] DEBUG BaseSSLContextParameters       - Configuring SSLSocket [669a4cb[SSL_NULL_WITH_NULL_NULL: Socket[unconnected]]] with 
	 explicitly set protocols [null],
	 protocol patterns [null],
	 available protocols [[SSLv2Hello, SSLv3, TLSv1]],
	 currently enabled protocols [[SSLv2Hello, SSLv3, TLSv1]],
	 and default protocol patterns [Patterns [includes=[.*], excludes=[]]].
	 Resulting enabled protocols are [[SSLv2Hello, SSLv3, TLSv1]].
About these ads
This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

One Response to Enhancements to Testing and JSSE Debugging in Camel 2.10

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s