You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/07/29 18:43:30 UTC

svn commit: r1508129 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ systests/jaxrs/src/test/java/org/apach...

Author: sergeyb
Date: Mon Jul 29 16:43:29 2013
New Revision: 1508129

URL: http://svn.apache.org/r1508129
Log:
[Cxf-5135] Some more experimenting with complex Client API

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java Mon Jul 29 16:43:29 2013
@@ -35,14 +35,16 @@ public class ConfigurableImpl<C extends 
     private C configurable;
     private Class<?>[] supportedProviderClasses;
     public ConfigurableImpl(C configurable, RuntimeType rt, Class<?>[] supportedProviderClasses) {
-        this(configurable, rt, supportedProviderClasses, null);
+        this(configurable, supportedProviderClasses, new ConfigurationImpl(rt));
     }
     
-    public ConfigurableImpl(C configurable, RuntimeType rt, 
-                            Class<?>[] supportedProviderClasses, Configuration config) {
+    public ConfigurableImpl(C configurable, Class<?>[] supportedProviderClasses, Configuration config) {
+        this(configurable, supportedProviderClasses);
+        this.config = config instanceof ConfigurationImpl ? (ConfigurationImpl)config : new ConfigurationImpl(config);
+    }
+    
+    private ConfigurableImpl(C configurable, Class<?>[] supportedProviderClasses) {
         this.configurable = configurable;
-        this.config = config == null ? new ConfigurationImpl(rt) 
-            : new ConfigurationImpl(rt, config);
         this.supportedProviderClasses = supportedProviderClasses;
     }
     

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurationImpl.java Mon Jul 29 16:43:29 2013
@@ -40,9 +40,14 @@ public class ConfigurationImpl implement
         this.runtimeType = rt;
     }
     
-    public ConfigurationImpl(RuntimeType rt, Configuration parent) {
-        props = parent.getProperties();
-        this.runtimeType = rt;
+    public ConfigurationImpl(Configuration parent) {
+        if (parent != null) {
+            this.props.putAll(parent.getProperties());
+            this.runtimeType = parent.getRuntimeType();
+            for (Object o : parent.getInstances()) {
+                providers.put(o, parent.getContracts(o.getClass()));
+            }
+        }
     }
     
     @Override

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java Mon Jul 29 16:43:29 2013
@@ -67,6 +67,10 @@ public final class ClientProviderFactory
         Endpoint e = m.getExchange().get(Endpoint.class);
         return (ClientProviderFactory)e.get(CLIENT_FACTORY_NAME);
     }
+    
+    public static ClientProviderFactory getInstance(Endpoint e) {
+        return (ClientProviderFactory)e.get(CLIENT_FACTORY_NAME);
+    }
        
     private static synchronized ClientProviderFactory initBaseFactory(Bus bus) {
         ClientProviderFactory factory = (ClientProviderFactory)bus.getProperty(SHARED_CLIENT_FACTORY);

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientBuilderImpl.java Mon Jul 29 16:43:29 2013
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
+import javax.ws.rs.RuntimeType;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.core.Configurable;
@@ -118,6 +119,9 @@ public class ClientBuilderImpl extends C
 
     @Override
     public ClientBuilder withConfig(Configuration cfg) {
+        if (cfg.getRuntimeType() != RuntimeType.CLIENT) {
+            throw new IllegalArgumentException();
+        }
         configImpl = new ClientConfigurableImpl<ClientBuilder>(this, cfg);
         return this;
     }

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientConfigurableImpl.java Mon Jul 29 16:43:29 2013
@@ -19,7 +19,6 @@
 
 package org.apache.cxf.jaxrs.client.spec;
 
-import javax.ws.rs.RuntimeType;
 import javax.ws.rs.client.ClientRequestFilter;
 import javax.ws.rs.client.ClientResponseFilter;
 import javax.ws.rs.core.Configurable;
@@ -30,6 +29,7 @@ import javax.ws.rs.ext.ReaderInterceptor
 import javax.ws.rs.ext.WriterInterceptor;
 
 import org.apache.cxf.jaxrs.impl.ConfigurableImpl;
+import org.apache.cxf.jaxrs.impl.ConfigurationImpl;
 
 public class ClientConfigurableImpl<C extends Configurable<C>> extends ConfigurableImpl<C> {
     private static final Class<?>[] CLIENT_FILTER_INTERCEPTOR_CLASSES = 
@@ -46,6 +46,6 @@ public class ClientConfigurableImpl<C ex
     }
     
     public ClientConfigurableImpl(C configurable, Configuration config) {
-        super(configurable, RuntimeType.CLIENT, CLIENT_FILTER_INTERCEPTOR_CLASSES, config);
+        super(configurable, CLIENT_FILTER_INTERCEPTOR_CLASSES, new ConfigurationImpl(config));
     }
 }

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java Mon Jul 29 16:43:29 2013
@@ -19,9 +19,10 @@
 package org.apache.cxf.jaxrs.client.spec;
 
 import java.net.URI;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.Map;
-import java.util.UUID;
+import java.util.Set;
 
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
@@ -33,7 +34,9 @@ import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.Link;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriBuilderException;
 
+import org.apache.cxf.jaxrs.client.ClientProviderFactory;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
 
@@ -41,7 +44,7 @@ public class ClientImpl implements Clien
     private Configurable<Client> configImpl;
     private TLSConfiguration secConfig;
     private boolean closed;
-    private WebClient template;
+    private Set<WebClient> baseClients = new HashSet<WebClient>();
     public ClientImpl(Configuration config,
                       TLSConfiguration secConfig) {
         configImpl = new ClientConfigurableImpl<Client>(this, config);
@@ -51,10 +54,10 @@ public class ClientImpl implements Clien
     @Override
     public void close() {
         if (!closed) {
-            if (template != null) {
-                template.close();
-                template = null;
+            for (WebClient wc : baseClients) {
+                wc.close();
             }
+            baseClients = null;
             closed = true;
         }
         
@@ -69,29 +72,10 @@ public class ClientImpl implements Clien
     @Override
     public WebTarget target(UriBuilder builder) {
         checkClosed();
-        initWebClientTemplateIfNeeded();
-        return new WebTargetImpl(builder, getConfiguration(), template);
-    }
-
-    private void initWebClientTemplateIfNeeded() {
-        // This is done to make the creation of individual targets really easy
-        if (template == null) {
-            JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
-            // To make sure that each Client has its own set of JAX-RS providers
-            // We may end up having CXF AbstractClient specific ClientProviderFactory
-            // if even WebTargets will be allowed to have its own specific providers
-            
-            bean.setAddress("http://tempuri/" + UUID.randomUUID().toString());
-            
-            Configuration cfg = getConfiguration();
-            bean.setProperties(cfg.getProperties());
-            bean.setProviders(new LinkedList<Object>(cfg.getInstances()));
-            
-            this.template = bean.createWebClient();
-            WebClient.getConfig(template).getConduit();
-        }
+        return new WebTargetImpl(builder, getConfiguration());
     }
     
+    
     @Override
     public WebTarget target(String address) {
         return target(UriBuilder.fromUri(address));
@@ -179,25 +163,51 @@ public class ClientImpl implements Clien
     class WebTargetImpl implements WebTarget {
         private Configurable<WebTarget> configImpl;
         private UriBuilder uriBuilder;
-        private WebClient template; 
+        private WebClient targetClient;
+        
+        
+        public WebTargetImpl(UriBuilder uriBuilder, 
+                             Configuration config) {
+            this(uriBuilder, config, null);
+        }
         
         public WebTargetImpl(UriBuilder uriBuilder, 
-                              Configuration config, 
-                              WebClient template) {
-            configImpl = new ClientConfigurableImpl<WebTarget>(this, config);
+                             Configuration config,
+                             WebClient targetClient) {
+            this.configImpl = new ClientConfigurableImpl<WebTarget>(this, config);
             this.uriBuilder = uriBuilder.clone();
-            this.template = template;
+            this.targetClient = targetClient;
         }
         
         @Override
         public Builder request() {
-            checkClosed();
-            WebClient wc = WebClient.fromClient(template).to(uriBuilder.build().toString(), false);
-            WebClient.getConfig(wc).getRequestContext().putAll(
-                configImpl.getConfiguration().getProperties());
-            // Can WebTarget have its own specific providers ?
+            ClientImpl.this.checkClosed();
+            
+            initTargetClientIfNeeded(); 
+            // API gives options to register new providers between 
+            // individual requests (sigh) or on per-WebTarget basis so we have to
+            // register directly on the endpoint-specific ClientFactory
+            ClientProviderFactory pf = 
+                ClientProviderFactory.getInstance(WebClient.getConfig(targetClient).getEndpoint());
+            pf.setUserProviders(new LinkedList<Object>(configImpl.getConfiguration().getInstances()));
             
-            return new InvocationBuilderImpl(wc);
+            // Collect the properties which may have been reset the requests
+            WebClient.getConfig(targetClient).getRequestContext().putAll(configImpl.getConfiguration().getProperties());
+            
+            // start building the invocation
+            return new InvocationBuilderImpl(WebClient.fromClient(targetClient));
+        }
+        
+        private void initTargetClientIfNeeded() {
+            URI uri = uriBuilder.build();
+            if (targetClient == null) {
+                JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+                bean.setAddress(uri.toString());
+                targetClient = bean.createWebClient();
+                ClientImpl.this.baseClients.add(targetClient);
+            } else if (!targetClient.getCurrentURI().equals(uri)) {
+                targetClient.to(uri.toString(), false);
+            }
         }
 
         @Override
@@ -212,13 +222,13 @@ public class ClientImpl implements Clien
 
         @Override
         public URI getUri() {
-            checkClosed();
+            ClientImpl.this.checkClosed();
             return uriBuilder.build();
         }
 
         @Override
         public UriBuilder getUriBuilder() {
-            checkClosed();
+            ClientImpl.this.checkClosed();
             return uriBuilder.clone();
         }
 
@@ -259,7 +269,7 @@ public class ClientImpl implements Clien
 
         @Override
         public WebTarget resolveTemplates(Map<String, Object> templatesMap, boolean encodeSlash) {
-            checkClosed();
+            ClientImpl.this.checkClosed();
             if (templatesMap.isEmpty()) {
                 return this;
             }
@@ -268,7 +278,7 @@ public class ClientImpl implements Clien
 
         @Override
         public WebTarget resolveTemplatesFromEncoded(Map<String, Object> templatesMap) {
-            checkClosed();
+            ClientImpl.this.checkClosed();
             if (templatesMap.isEmpty()) {
                 return this;
             }
@@ -276,7 +286,20 @@ public class ClientImpl implements Clien
         }
         
         private WebTarget newWebTarget(UriBuilder newBuilder) {
-            return new WebTargetImpl(newBuilder, getConfiguration(), template);
+            boolean complete = false;
+            if (targetClient != null) {
+                try {
+                    newBuilder.build();
+                    complete = true;
+                } catch (UriBuilderException ex) {
+                    //the builder still has unresolved vars
+                }
+            }
+            if (!complete) {
+                return new WebTargetImpl(newBuilder, getConfiguration());
+            }
+            WebClient newClient = WebClient.fromClient(targetClient);
+            return new WebTargetImpl(newBuilder, getConfiguration(), newClient);
         }
         
         @Override

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java?rev=1508129&r1=1508128&r2=1508129&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java Mon Jul 29 16:43:29 2013
@@ -130,6 +130,17 @@ public class JAXRS20ClientServerBookTest
     }
     
     @Test
+    public void testGetBookWebTargetProvider() {
+        String address = "http://localhost:" + PORT + "/bookstore/bookheaders";
+        Client client = ClientBuilder.newClient();
+        client.register(new BookInfoReader());
+        BookInfo book = client.target(address).path("simple")
+            .request("application/xml").get(BookInfo.class);
+        assertEquals(124L, book.getId());
+        
+    }
+    
+    @Test
     public void testGetBookSyncWithAsync() {
         String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple";
         doTestGetBook(address, true);