Camel 2.14.0 / CXF 3.0.1 Jetty config: protocol mismatch error

We have a couple of webservices (REST + SOAP) running in Apache Camel 2.13.0 based on CXF version 2.7.10 that use SSL and Basic Authentication in full, which works very well.

Due to the upgrade from Camel version to 2.14.0, which internally uses CXF 3.0.1, our services have now stopped working Protocol mismatch for port x: engine protocol is http, the url protocol is https

- however the configuration was not affected during the version upgrade.

...
Caused by: java.io.IOException: Protocol mismatch for port 8081: engine protocol is http, the url protocol is https
    at org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory.createJettyHTTPServerEngine(JettyHTTPServerEngineFactory.java:271)
    at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.retrieveEngine(JettyHTTPDestination.java:121)
    at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.finalizeConfig(JettyHTTPDestination.java:154)
    ... 48 more

      

So I created a new eclipse project that simplifies it to the bare minimum (just a simple SOAP service with two endpoints that use either HTTP or HTTPS).

Jetty server configuration can be seen here

The actual service is configured as a bean to use that bean in the Camel route later:

@Bean(name="endpoint1ServiceSSL")
public CxfSpringEndpoint endpoint1ServiceSSL() throws Exception
{
    final CxfSpringEndpoint factoryBean = new CxfSpringEndpoint();
    factoryBean.setServiceClass(EnhancedEndpoint1Endpoint.class);
    factoryBean.setWsdlURL("classpath:/wsdl/test.wsdl");
    factoryBean.setEndpointName(new QName(NAMESPACE, "Endpoint1ServicePort", PREFIX));
    factoryBean.setServiceName(new QName(NAMESPACE, "Endpoint1_Service", PREFIX));
    factoryBean.setAddress(env.getProperty("services.address.ssl")+"/endpoint1");
    factoryBean.setDataFormat(DataFormat.POJO);
    final Map<String, Object> properties = new HashMap<>();
    properties.put("schema-validation-enabled", "true");
    properties.put("allowStreaming", true);
    factoryBean.setProperties(properties);
    factoryBean.getInInterceptors().add(new LoggingInInterceptor());
    factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());

    return factoryBean;
}

      

NAMESPACE

and PREFIX

- these are just some constants, nothing important for this example. bean gets specific values ​​like the base address of the service from a properties file that only contains values ​​like:

services.address = http://0.0.0.0:8080/
services.address.ssl = https://0.0.0.0:8081/

      

and other ssl keystore related stuff. Note that CXF will use the quay beans configuration during the initialization process and therefore create a secure SSL connection for HTTPS-invoked URLs - at least this happened before the version update.

The route can now access the service using this very simple route:

public class Endpoint1Route extends RouteBuilder
{
    @Override
    public void configure() throws Exception
    {
        from("cxf:bean:endpoint1Service")
            .to("log:endpoint1Service");

        from("cxf:bean:endpoint1ServiceSSL")
            .to("log:endpoint1ServiceSSL");
    }
}

      

This worked well with CXF 2.7.10 and Camel 2.13.0 - but as said above, there is a protocol inconsistency after the upgrade for whatever reason (hopefully you can see from the github linked project; after cloning the project, you you must execute generate-sources and then run ServicesApp

as a stand-alone Java application).

I also created a new branch to update the version to make it easier to switch between both versions.

Does anyone know why the Jetty config that was working before the version upgrade now returns a protocol mismatch error? Are there any updated libraries missing that I haven't figured out yet? Or am I setting something wrong in the first place?


@Edit:

After further testing, I'm pretty sure that some API changes inside CXF led to problems as the bean that configures the secure SSL Jetty server is no longer executed on startup, and with version 2.7.10 the bean gets executed.

This changes the actual question to "How to set up a Jetty Server SSL in Apache CXF 3.0.1"


@Edit # 2:

I was able to get a secure SSL Jetty server running in Camel 2.14.0 / CXF 3.0.1, but only via XML config . Since we prefer Java configuration over XML, we are still looking for a method to configure Jetty with SSL in CXF 3.0.1. However, the jettySSLEngineFactory Spring bean pass file seems to me to be another CXF error.

To clarify, in CXF 2.7.x, the jetty server can be configured in Java when creating a Spring bean that returns an instance JettyHTTPServerEngineFactory

as shown in the master branch of the github project linked above. This bean was used by CXF when configuring the server instance and hence configuring the Jetty SSL secured server. However, in CXF 3.0.1, this bean is no longer called - the only JettyDestinationFactory

one I don't know about is how to set up a secure SSL server. Also, the XML example provided in the docs does not provide any clue on how to set up Jetty with SSL using a destination factory.

Since engine-factory

inside the XML example in the docs actually maps to the configuration JettyHTTPServerEngineFactory

and Jetty via XML, it works fine, this seems to indicate a Spring bean error inside CXF 3.0.1 so that I.

+3


source to share


1 answer


As the protocol mismatch error was caused by CXF skipping the bean initialization of the jetty bean configuration. However, it turns out that there are certain issues with an internal change to the Spring version in CXF extending the Spring configuration class.

When you remove extends SoapSSLConfig

in CxfEndpointConfig

and inject this class, the configuration is done by @Import(SoapSSLConfig.class)

initializing the bean, and so the configuration of the Jetty server still works.

Used code:



@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class CxfEndpointConfig extends SoapSSLConfig
{
    ...
}

      

which lead to injection failures. Replacing the above code with the below solution to the problem.

@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
@Import(SoapSSLConfig.class)
public class CxfEndpointConfig
{
    ...
}

      

+1


source







All Articles