Folks,
I currently have code similar to that included below in a few places in
order to provide failover between multiple URLs (supplied one per line
in a string that is either found via spring/jndi or from a database).
I need to modify this to add two new facilities:
1. I need to parse the URLs, determine if they point to multiple IP
addresses, and if so I need to failover across the all of the separately.
2. I need to randomise the order of the URLs to provide a load
distribution (it's not exactly balanced, but there's enough traffic that
it will be adequate).
Questions:
1. Is there any simpler way of doing this?
2. Would it be better if this was built into CXF (as a helper function
somewhere, rather than default behaviour)?
3. Most of the endpoints I create this way are shortlived, but for long
lived ones is there any decent place to add hook to change the endpoint
address every n requests?
The code (nodConverterService is a CXF client):
String[] urls = sourceUrls.split( "\n" );
for( String url : urls ) {
try {
URL parsedUrl = new URL( url );
log.debug( "URL \"{}\" parsed OK \"{}\"", url, parsedUrl );
} catch( Exception ex ) {
log.debug( "Attempt to parse URL \"{}\" threw exception
: {}", url, ex );
}
}
BindingProvider binder = ( BindingProvider ) nodConverterService;
binder.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, urls[ urls.length - 1 ].trim() );
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
Client client = org.apache.cxf.frontend.ClientProxy.getClient(
nodConverterService );
HTTPConduit http = ( HTTPConduit ) client.getConduit();
http.setClient( httpClientPolicy );
if( urls.length > 1 ) {
log.debug( "Configuring FailoverFeature for {} URLs",
urls.length );
List< String > alternateUrls = Arrays.asList( urls );
FailoverFeature feature = new FailoverFeature();
SequentialStrategy strategy = new SequentialStrategy();
strategy.setAlternateAddresses( alternateUrls );
feature.setStrategy( strategy );
feature.initialize( client, null );
}
log.debug( "Initial URL: \"{}\"",
binder.getRequestContext().get(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY ) );