Return-Path: X-Original-To: apmail-cxf-dev-archive@www.apache.org Delivered-To: apmail-cxf-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CE4BD109F3 for ; Fri, 4 Apr 2014 09:35:41 +0000 (UTC) Received: (qmail 84106 invoked by uid 500); 4 Apr 2014 09:35:40 -0000 Delivered-To: apmail-cxf-dev-archive@cxf.apache.org Received: (qmail 83807 invoked by uid 500); 4 Apr 2014 09:35:39 -0000 Mailing-List: contact dev-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list dev@cxf.apache.org Received: (qmail 83799 invoked by uid 99); 4 Apr 2014 09:35:38 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Apr 2014 09:35:38 +0000 X-ASF-Spam-Status: No, hits=-5.0 required=5.0 tests=RCVD_IN_DNSWL_HI,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of asoldano@redhat.com designates 209.132.183.28 as permitted sender) Received: from [209.132.183.28] (HELO mx1.redhat.com) (209.132.183.28) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Apr 2014 09:35:33 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s349Z9LM022104 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 4 Apr 2014 05:35:09 -0400 Received: from localhost.localdomain (vpn1-5-242.ams2.redhat.com [10.36.5.242]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s349Z8sU012085 for ; Fri, 4 Apr 2014 05:35:08 -0400 Message-ID: <533E7CCB.6000504@redhat.com> Date: Fri, 04 Apr 2014 11:35:07 +0200 From: Alessio Soldano User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130805 Thunderbird/17.0.8 MIME-Version: 1.0 To: dev@cxf.apache.org Subject: Setting custom DestinationRegistry in HTTPTransportFactory (CXF 3.0) Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Virus-Checked: Checked by ClamAV on apache.org 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