[ 
https://issues.apache.org/jira/browse/CAMEL-3750?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13020304#comment-13020304
 ] 

David Valeri commented on CAMEL-3750:
-------------------------------------

For number 1)

A) Is there harm in extending AbstractCamelFactoryBean from core-xml?  It 
appeared to be the pattern being followed by the Spring and Blueprint handlers. 
The pattern I see is AbstractCamelFactoryBean (core-xml) -> 
AbstractMyTypeFactoryBean (core-xml) -> ConcreteMyTypeFactoryBean (spring OR 
blueprint).  I think this makes Blueprint support just a matter of implementing 
ConcreteMyTypeFactoryBean instances and a handler in the Blueprint module 
right?  Is there some mistake in my abstract factory beans that is going to 
prevent adding Blueprint support down the road?

B) The SSLContextParameters use of ClassResolver was implemented per the 
earlier request from Claus.  Originally the code was as follows:

{code:java}
            try {
                is = new FileInputStream(this.resource);
            } catch (FileNotFoundException e) {
                LOG.debug("Could not open resource as a file, trying as class 
path resource.", e);
            }

            if (is == null) {
                is = this.getClass().getResourceAsStream(this.resource);
                if (is == null) {
                    LOG.debug("Could not open resource as a class path resource 
using the "
                              + this.getClass().getClassLoader() 
                              + " classloader.  Trying as a class path resource 
with the TCCL (if set).");
                }
            }
            
            if (is == null && Thread.currentThread().getContextClassLoader() != 
null) {
                is = 
Thread.currentThread().getContextClassLoader().getResourceAsStream(this.resource);
                if (is == null) {
                    LOG.debug("Could not open resource as a class path resource 
using the TCCL "
                              + this.getClass().getClassLoader() + ".  Trying 
as a URL.");
                }
            }

            if (is == null) {
                try {
                    is = new URL(this.resource).openStream();
                } catch (IOException e) {
                    LOG.debug("Could not open resource as a URL.", e);
                }
            }

            if (is == null) {
                throw new IOException("Could not open " + this.resource + " as 
a file, class path resource, or URL.");
            }
{code}

I didn't look through the ClassResolver implementations before making the 
requested change, but after reviewing OsgiClassResolver, it appears that it 
does not consult the TCCL.  OsgiClassResolver only looks in the bundle that 
created the Camel context.  I can see a case where the key store resource may 
be in another bundle from the one loading the context and accessible only 
through the bundle's classpath rather than through the Bundle contents.  
Perhaps both ClassResolver and the TCCL should be consulted?

2) The HTTP component's TLS support is a little limited because of how Commons 
HTTP 3.x supports TLS configuration.  The 3.x branches lookup a 
"ProtocolSocketFactory" in a global repository provided by the Protocol class.  
I could accept sslContextParametersRef and set it into Protocol in the 
component, BUT the second endpoint the user creates using 
sslContextParametersRef is going to clobber the ProtocolSocketFactory 
configuration from the first endpoint since they both use the same schema name 
("https").  Since this repository is global, used both inside and outside of 
the Camel component, and I think it would be exceedingly difficult to rework 
the component to cleanly support a per endpoint use of sslContextParametersRef, 
I opted for the simpler approach as show below.

{code:java}
                SSLContextParameters params = new SSLContextParameters();
                
                ProtocolSocketFactory factory = 
                    new SSLContextParametersSecureProtocolSocketFactory(params);
                
                Protocol.registerProtocol("https",
                        new Protocol(
                                "https",
                                factory,
                                443));
{code}

I suppose it might be possible to generate a schema name for each endpoint 
using the sslContextParametersRef parameter and register the 
ProtocolSocketFactory under that generated schema name.  Then hand the URL off 
to Commons HTTP with the generated schema name.

So https://www.google.com?sslContextParametersRef=params1 would result in 
something like the following:

{code:java}
                ProtocolSocketFactory factory = 
                    new 
SSLContextParametersSecureProtocolSocketFactory(params1);
                
                Protocol.registerProtocol("generatedSchemaName1",
                        new Protocol(
                                "https",
                                factory,
                                443));
{code}

Where Commons HTTP is actually handed the URL: 
generatedSchemaName1://www.google.com
I'd have to look at the HTTP component again to see if all of the needed 
information to do something like this is accessible or if there would be a fair 
bit of refactoring needed to get all of the information in the same spot.

> Provide a common mechanism to facilitate configuration of TLS across Camel 
> components
> -------------------------------------------------------------------------------------
>
>                 Key: CAMEL-3750
>                 URL: https://issues.apache.org/jira/browse/CAMEL-3750
>             Project: Camel
>          Issue Type: New Feature
>          Components: camel-core, camel-http, camel-jetty
>            Reporter: David Valeri
>            Assignee: Willem Jiang
>             Fix For: Future
>
>         Attachments: CAMEL-3750-camel-core-xml.patch, 
> CAMEL-3750-camel-core.patch, CAMEL-3750-camel-http.patch, 
> CAMEL-3750-camel-http4.patch, CAMEL-3750-camel-itest-osgi.patch, 
> CAMEL-3750-camel-jetty.patch, CAMEL-3750-camel-spring.patch
>
>
> CXF provides a nice Spring Namespace handler for configuring TLS options on 
> the Jetty transport.  Configuring these options using XML in Spring or 
> through a simplified set of utility classes decreases the learning curve for 
> users by sheltering them from the horrors of JSSE.
> There are a large number of components in Camel that deal with socket 
> communication at some level, but they all require users to learn the specific 
> low level configuration capabilities of the library on which the component is 
> based in order to configure custom TLS options.
> It would be convenient if users didn't need to learn the advanced networking 
> configuration options for each component.
> This enhancement suggests a similar Spring Namespace handler and utility 
> classes that allow for simplified configuration of an SSLContext as well as 
> adding provisions to some of the Camel components in order to accept this new 
> configuration mechanism.  The initial components to support the new 
> configuration mechanism are the http, http4, and Jetty components.  Other 
> components would follow.
> An example usage is below.
> Programmatic configuration:
> {code}
> KeyStoreParameters ksp = new KeyStoreParameters();
> ksp.setResource(this.getClass().getClassLoader().getResource("jsse/localhost.ks").toString());
> ksp.setPassword(pwd);
> ksp.setContext(context);
>         
> KeyManagersParameters kmp = new KeyManagersParameters();
> kmp.setKeyPassword(pwd);
> kmp.setKeyStore(ksp);
> TrustManagersParameters tmp = new TrustManagersParameters();
> tmp.setKeyStore(ksp);
>         
> SSLContextParameters sslContextParameters = new SSLContextParameters();
> sslContextParameters.setKeyManagers(kmp);
> sslContextParameters.setTrustManagers(tmp);
> {code}
> XML Configuration:
> {code:XML}
> <SSLContextParameters id="sslContextParameters" secureSocketProtocol="TLS">
>   <keyManagers
>       keyPassword="password">
>     <keyStore resource="./localhost.jks" password="password"/>
>   </keyManagers>
>   <secureSocketProtocolsFilter>
>     <include>TLS.*</include>
>   </secureSocketProtocolsFilter>
> </SSLContextParameters>
> {code}
> Usage in a route:
> {code}
> from("jetty:https://localhost:443/hello?sslContextParametersRef=sslContextParameters";).process(proc);
> {code}

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to