This seems like a good solution/idea….. wish I would have thought of it.  :-)

Using the configurer to configure these things is definitely the right approach.

Dan



On Apr 4, 2014, at 5:35 AM, Alessio Soldano <[email protected]> wrote:

> Hi,
> I've been mentioning this to Dan on IRC yesterday, but I'd like to bring the 
> topic back here as I have a proposal now.
> 
> I need to set a custom DestinationRegistry implementation in the 
> HTTPTransportFactory (as I override a method in the registry). With CXF 
> 2.7.x, I used to set an instance of my registry impl in the bus:
> 
> bus.setExtension(new JBossWSDestinationRegistryImpl(), 
> DestinationRegistry.class);
> 
> however that does not work anymore with CXF 3.0 because the 
> HTTPTransportFactory does not hold a reference to the bus anymore, hence it 
> does not look for configured registry in it, and simply creates the default 
> DestinationRegistryImpl.
> My idea would be to rely on the optional Configurer which could be installed 
> in the bus (I'm already setting a custom Configurer) to configure the 
> HTTPTransportFactory before it's actually used. The factory is already passed 
> to the configurer afaics. So, we'd need to allow changing the reference to 
> the registry in the factory. If you have nothing against that, I'd create a 
> jira and commit the following changes (with proper logging i18n, of course):
> 
> diff --git 
> a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPTransportFactory.java
>  
> b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPTransportFactory.java
> index 44b4592..bcf75c3 100644
> --- 
> a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPTransportFactory.java
> +++ 
> b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPTransportFactory.java
> @@ -27,6 +27,9 @@ import java.util.HashSet;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Set;
> +import java.util.concurrent.locks.Lock;
> +import java.util.concurrent.locks.ReadWriteLock;
> +import java.util.concurrent.locks.ReentrantReadWriteLock;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> 
> @@ -75,7 +78,11 @@ public class HTTPTransportFactory
>         URI_PREFIXES.add("https://";);
>     }
> 
> -    protected final DestinationRegistry registry;
> +    protected DestinationRegistry registry;
> +
> +    private final ReadWriteLock lock = new ReentrantReadWriteLock();
> +    private final Lock r = lock.readLock();
> +    private final Lock w = lock.writeLock();
> 
>     public HTTPTransportFactory() {
>         this(new DestinationRegistryImpl());
> @@ -91,6 +98,19 @@ public class HTTPTransportFactory
>         return registry;
>     }
> 
> +    public void setRegistry(DestinationRegistry newRegistry) {
> +        w.lock();
> +        try {
> +            if (registry.getDestinations().isEmpty()) {
> +                this.registry = newRegistry;
> +            } else {
> +                throw new RuntimeException("Cannot change registry already 
> in use!");
> +            }
> +        } finally {
> +            w.unlock();
> +        }
> +    }
> +
>     /**
>      * This call is used by CXF ExtensionManager to inject the 
> activationNamespaces
>      * @param ans The transport ids.
> @@ -231,31 +251,36 @@ public class HTTPTransportFactory
>         if (endpointInfo == null) {
>             throw new IllegalArgumentException("EndpointInfo cannot be null");
>         }
> -        synchronized (registry) {
> -            AbstractHTTPDestination d = 
> registry.getDestinationForPath(endpointInfo.getAddress());
> -            if (d == null) {
> -                HttpDestinationFactory jettyFactory = 
> bus.getExtension(HttpDestinationFactory.class);
> -                String addr = endpointInfo.getAddress();
> -                if (jettyFactory == null && addr != null && 
> addr.startsWith("http")) {
> -                    String m =
> -                        new 
> org.apache.cxf.common.i18n.Message("NO_HTTP_DESTINATION_FACTORY_FOUND"
> -                                                               , 
> LOG).toString();
> -                    LOG.log(Level.SEVERE, m);
> -                    throw new IOException(m);
> -                }
> -                HttpDestinationFactory factory = null;
> -                if (jettyFactory != null && (addr == null || 
> addr.startsWith("http"))) {
> -                    factory = jettyFactory;
> -                } else {
> -                    factory = new ServletDestinationFactory();
> +        r.lock();
> +        try {
> +            synchronized (registry) {
> +                AbstractHTTPDestination d = 
> registry.getDestinationForPath(endpointInfo.getAddress());
> +                if (d == null) {
> +                    HttpDestinationFactory jettyFactory = 
> bus.getExtension(HttpDestinationFactory.class);
> +                    String addr = endpointInfo.getAddress();
> +                    if (jettyFactory == null && addr != null && 
> addr.startsWith("http")) {
> +                        String m =
> +                            new 
> org.apache.cxf.common.i18n.Message("NO_HTTP_DESTINATION_FACTORY_FOUND"
> + , LOG).toString();
> +                        LOG.log(Level.SEVERE, m);
> +                        throw new IOException(m);
> +                    }
> +                    HttpDestinationFactory factory = null;
> +                    if (jettyFactory != null && (addr == null || 
> addr.startsWith("http"))) {
> +                        factory = jettyFactory;
> +                    } else {
> +                        factory = new ServletDestinationFactory();
> +                    }
> +
> +                    d = factory.createDestination(endpointInfo, bus, 
> registry);
> +                    registry.addDestination(d);
> +                    configure(bus, d);
> +                    d.finalizeConfig();
>                 }
> -
> -                d = factory.createDestination(endpointInfo, bus, registry);
> -                registry.addDestination(d);
> -                configure(bus, d);
> -                d.finalizeConfig();
> +                return d;
>             }
> -            return d;
> +        } finally {
> +            r.unlock();
>         }
>     }
> 
> 
> The read/write lock stuff is required to prevent anybody from trying to use 
> the registry while its reference is being modified, but might be considered 
> too much of a preventive measure and avoided if we simply assume and document 
> that the registry can be modified only before starting using it.
> WDYT? Perhaps is this "issue" going to be addressed in a more general way?
> 
> Thanks
> Alessio
> 
> -- 
> Alessio Soldano
> Web Service Lead, JBoss
> 

-- 
Daniel Kulp
[email protected] - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Reply via email to