This is an automated email from the ASF dual-hosted git repository. johndament pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 76be95e176dec480226d0cf3b8b2f27c28f7a53e Author: John D. Ament <[email protected]> AuthorDate: Sat Dec 16 09:00:45 2017 -0500 [CXF-7579] Introduce a dedicated proxy for MicroProfile Move exception handling into a protected method to be overridden Move proxy creation into a method as well Minor code clean up to use proper sorting --- .../apache/cxf/jaxrs/provider/ProviderFactory.java | 8 +- .../apache/cxf/jaxrs/client/ClientProxyImpl.java | 2 +- .../cxf/jaxrs/client/JAXRSClientFactoryBean.java | 21 ++-- rt/rs/microprofile-client/pom.xml | 41 ++++--- .../microprofile/client/ContractComparator.java | 53 +++++++++ .../client/CxfTypeSafeClientBuilder.java | 14 ++- .../client/MicroProfileClientFactoryBean.java | 94 +++++++++++----- .../client/MicroProfileClientProviderFactory.java | 120 +++++++++++++++++++++ .../microprofile/client/cdi/RestClientBean.java | 11 +- .../client/proxy/MicroProfileClientProxyImpl.java | 65 +++++++++++ .../client/CxfTypeSafeClientBuilderTest.java | 47 +++++++- systests/microprofile/client/weld/pom.xml | 24 ++++- 12 files changed, 430 insertions(+), 70 deletions(-) diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java index e1af3fb..4fd6657 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java @@ -657,14 +657,14 @@ public abstract class ProviderFactory { */ private void sortReaders() { if (!customComparatorAvailable(MessageBodyReader.class)) { - Collections.sort(messageReaders, new MessageBodyReaderComparator()); + messageReaders.sort(new MessageBodyReaderComparator()); } else { doCustomSort(messageReaders); } } private <T> void sortWriters() { if (!customComparatorAvailable(MessageBodyWriter.class)) { - Collections.sort(messageWriters, new MessageBodyWriterComparator()); + messageWriters.sort(new MessageBodyWriterComparator()); } else { doCustomSort(messageWriters); } @@ -703,11 +703,11 @@ public abstract class ProviderFactory { } List<T> theProviders = (List<T>)listOfProviders; Comparator<? super T> theComparator = (Comparator<? super T>)theProviderComparator; - Collections.sort(theProviders, theComparator); + theProviders.sort(theComparator); } private void sortContextResolvers() { - Collections.sort(contextResolvers, new ContextResolverComparator()); + contextResolvers.sort(new ContextResolverComparator()); } diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java index 508e430..d7aacb9 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java @@ -298,7 +298,7 @@ public class ClientProxyImpl extends AbstractClient implements return index; } - private void checkResponse(Method m, Response r, Message inMessage) throws Throwable { + protected void checkResponse(Method m, Response r, Message inMessage) throws Throwable { Throwable t = null; int status = r.getStatus(); diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java index a783bf9..f36f5a5 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java @@ -306,15 +306,7 @@ public class JAXRSClientFactoryBean extends AbstractJAXRSFactoryBean { boolean isRoot = cri.getURITemplate() != null; ClientProxyImpl proxyImpl = null; ClientState actualState = getActualState(); - if (actualState == null) { - proxyImpl = - new ClientProxyImpl(URI.create(getAddress()), proxyLoader, cri, isRoot, - inheritHeaders, varValues); - } else { - proxyImpl = - new ClientProxyImpl(actualState, proxyLoader, cri, isRoot, - inheritHeaders, varValues); - } + proxyImpl = createClientProxy(cri, isRoot, actualState, varValues); initClient(proxyImpl, ep, actualState == null); ClassLoader theLoader = proxyLoader == null ? cri.getServiceClass().getClassLoader() : proxyLoader; @@ -341,6 +333,17 @@ public class JAXRSClientFactoryBean extends AbstractJAXRSFactoryBean { } + protected ClientProxyImpl createClientProxy(ClassResourceInfo cri, boolean isRoot, + ClientState actualState, Object[] varValues) { + if (actualState == null) { + return new ClientProxyImpl(URI.create(getAddress()), proxyLoader, cri, isRoot, + inheritHeaders, varValues); + } else { + return new ClientProxyImpl(actualState, proxyLoader, cri, isRoot, + inheritHeaders, varValues); + } + } + protected ConduitSelector getConduitSelector(Endpoint ep) { ConduitSelector cs = getConduitSelector(); if (cs == null) { diff --git a/rt/rs/microprofile-client/pom.xml b/rt/rs/microprofile-client/pom.xml index a893fb9..402a528 100644 --- a/rt/rs/microprofile-client/pom.xml +++ b/rt/rs/microprofile-client/pom.xml @@ -100,6 +100,12 @@ <version>1.0-SNAPSHOT</version> </dependency> <dependency> + <groupId>org.eclipse.microprofile.rest.client</groupId> + <artifactId>microprofile-rest-client-tck</artifactId> + <version>1.0-SNAPSHOT</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.eclipse.microprofile.config</groupId> <artifactId>microprofile-config-api</artifactId> <version>1.1</version> @@ -121,23 +127,6 @@ <optional>true</optional> </dependency> <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-core</artifactId> - <scope>provided</scope> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - <scope>provided</scope> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.easymock</groupId> - <artifactId>easymock</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <scope>test</scope> @@ -179,6 +168,24 @@ </dependencies> <profiles> <profile> + <id>release-repo</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <repositories> + <repository> + <id>mp-rest-client</id> + <url>https://oss.sonatype.org/content/repositories/orgeclipsemicroprofile-1037/</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + <releases> + <enabled>true</enabled> + </releases> + </repository> + </repositories> + </profile> + <profile> <id>java9</id> <activation> <jdk>9</jdk> diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/ContractComparator.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/ContractComparator.java new file mode 100644 index 0000000..5ef4fb5 --- /dev/null +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/ContractComparator.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.microprofile.client; + +import java.util.Comparator; +import java.util.Map; +import org.apache.cxf.jaxrs.utils.AnnotationUtils; +import static org.apache.cxf.microprofile.client.MicroProfileClientConfigurableImpl.CONTRACTS; + +class ContractComparator implements Comparator<Object> { + private MicroProfileClientFactoryBean microProfileClientFactoryBean; + + ContractComparator(MicroProfileClientFactoryBean microProfileClientFactoryBean) { + this.microProfileClientFactoryBean = microProfileClientFactoryBean; + } + + @Override + public int compare(Object oLeft, Object oRight) { + int left = getPriority(oLeft.getClass()); + int right = getPriority(oRight.getClass()); + return left - right; + } + + private int getPriority(Class<?> clazz) { + Map<Class<?>, Integer> contracts = microProfileClientFactoryBean.getConfiguration() + .getContracts(clazz); + if (contracts != null && !contracts.isEmpty()) { + for (Class<?> providerClass : CONTRACTS) { + Integer priority = contracts.get(providerClass); + if (priority != null) { + return priority; + } + } + } + return AnnotationUtils.getBindingPriority(clazz); + } +} diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java index 904731c..40f5cc9 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java @@ -24,7 +24,7 @@ import java.util.Objects; import javax.ws.rs.core.Configurable; import javax.ws.rs.core.Configuration; import org.eclipse.microprofile.rest.client.RestClientBuilder; -import org.eclipse.microprofile.rest.client.annotation.RegisterProviders; +import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; public class CxfTypeSafeClientBuilder implements RestClientBuilder, Configurable<RestClientBuilder> { private String baseUri; @@ -42,12 +42,16 @@ public class CxfTypeSafeClientBuilder implements RestClientBuilder, Configurable if (baseUri == null) { throw new IllegalStateException("baseUrl not set"); } - RegisterProviders providers = aClass.getAnnotation(RegisterProviders.class); + RegisterProvider[] providers = aClass.getAnnotationsByType(RegisterProvider.class); Configuration config = configImpl.getConfiguration(); if (providers != null) { - for (Class<?> c : providers.value()) { - if (!config.isRegistered(c)) { - register(c); + for (RegisterProvider provider : providers) { + if (!config.isRegistered(provider.value())) { + if (provider.priority() == -1) { + register(provider.value()); + } else { + register(provider.value(), provider.priority()); + } } } } diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientFactoryBean.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientFactoryBean.java index 3d89549..7f662ff 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientFactoryBean.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientFactoryBean.java @@ -18,51 +18,91 @@ */ package org.apache.cxf.microprofile.client; +import java.net.URI; import java.util.ArrayList; -import java.util.Comparator; +import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; +import java.util.Set; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.client.ClientResponseFilter; import javax.ws.rs.core.Configuration; + +import org.apache.cxf.common.util.ClassHelper; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.jaxrs.client.AbstractClient; +import org.apache.cxf.jaxrs.client.ClientProxyImpl; +import org.apache.cxf.jaxrs.client.ClientState; import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean; -import org.apache.cxf.jaxrs.utils.AnnotationUtils; -import static org.apache.cxf.microprofile.client.MicroProfileClientConfigurableImpl.CONTRACTS; +import org.apache.cxf.jaxrs.model.ClassResourceInfo; +import org.apache.cxf.jaxrs.model.FilterProviderInfo; +import org.apache.cxf.microprofile.client.proxy.MicroProfileClientProxyImpl; public class MicroProfileClientFactoryBean extends JAXRSClientFactoryBean { + private final ContractComparator comparator; private Configuration configuration; + private ClassLoader proxyLoader; + private boolean inheritHeaders; public MicroProfileClientFactoryBean(Configuration configuration, String baseUri, Class<?> aClass) { super(); this.configuration = configuration; + this.comparator = new ContractComparator(this); super.setAddress(baseUri); super.setServiceClass(aClass); - super.setProviderComparator(new ContractComparator()); - List<Object> providerClasses = new ArrayList<>(); - providerClasses.addAll(configuration.getClasses()); - providerClasses.addAll(configuration.getInstances()); - super.setProviders(providerClasses); + super.setProviderComparator(comparator); + List<Object> providers = new ArrayList<>(); + providers.addAll(processProviders()); + super.setProviders(providers); + } + + @Override + public void setClassLoader(ClassLoader loader) { + super.setClassLoader(loader); + this.proxyLoader = loader; } - private class ContractComparator implements Comparator<Object> { - @Override - public int compare(Object o1, Object o2) { - int left = getPriority(o1.getClass()); - int right = getPriority(o2.getClass()); - return left - right; + @Override + public void setInheritHeaders(boolean inheritHeaders) { + super.setInheritHeaders(inheritHeaders); + this.inheritHeaders = inheritHeaders; + } + + @Override + protected void initClient(AbstractClient client, Endpoint ep, boolean addHeaders) { + super.initClient(client, ep, addHeaders); + MicroProfileClientProviderFactory factory = MicroProfileClientProviderFactory.createInstance(getBus(), + comparator); + ep.put(MicroProfileClientProviderFactory.CLIENT_FACTORY_NAME, factory); + } + + @Override + protected ClientProxyImpl createClientProxy(ClassResourceInfo cri, boolean isRoot, + ClientState actualState, Object[] varValues) { + if (actualState == null) { + return new MicroProfileClientProxyImpl(URI.create(getAddress()), proxyLoader, cri, isRoot, + inheritHeaders, varValues); + } else { + return new MicroProfileClientProxyImpl(actualState, proxyLoader, cri, isRoot, + inheritHeaders, varValues); } + } - private int getPriority(Class<?> clazz) { - for (Class<?> providerClass : CONTRACTS) { - Map<Class<?>, Integer> contracts = MicroProfileClientFactoryBean.this. - configuration.getContracts(providerClass); - if (contracts != null) { - Integer priority = contracts.get(clazz); - if (priority != null) { - return priority; - } - } + Configuration getConfiguration() { + return configuration; + } + + private Set<Object> processProviders() { + Set<Object> providers = new LinkedHashSet<>(); + for (Object provider : configuration.getInstances()) { + Class<?> providerCls = ClassHelper.getRealClass(bus, provider); + if (provider instanceof ClientRequestFilter || provider instanceof ClientResponseFilter) { + FilterProviderInfo<Object> filter = new FilterProviderInfo<>(providerCls, providerCls, + provider, bus, configuration.getContracts(providerCls)); + providers.add(filter); + } else { + providers.add(provider); } - return AnnotationUtils.getBindingPriority(clazz); } + return providers; } - } diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java new file mode 100644 index 0000000..ec24efc --- /dev/null +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/MicroProfileClientProviderFactory.java @@ -0,0 +1,120 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.microprofile.client; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import javax.ws.rs.core.Configuration; +import org.apache.cxf.Bus; +import org.apache.cxf.BusFactory; +import org.apache.cxf.common.util.ClassHelper; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.jaxrs.model.ProviderInfo; +import org.apache.cxf.jaxrs.provider.ProviderFactory; +import org.apache.cxf.message.Message; +import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; + +public final class MicroProfileClientProviderFactory extends ProviderFactory { + static final String CLIENT_FACTORY_NAME = MicroProfileClientProviderFactory.class.getName(); + private List<ProviderInfo<ResponseExceptionMapper<?>>> responseExceptionMappers = + new ArrayList<ProviderInfo<ResponseExceptionMapper<?>>>(1); + private final ContractComparator comparator; + + private MicroProfileClientProviderFactory(Bus bus, ContractComparator comparator) { + super(bus); + this.comparator = comparator; + } + + public static MicroProfileClientProviderFactory createInstance(Bus bus, ContractComparator comparator) { + if (bus == null) { + bus = BusFactory.getThreadDefaultBus(); + } + MicroProfileClientProviderFactory factory = new MicroProfileClientProviderFactory(bus, comparator); + ProviderFactory.initFactory(factory); + factory.setBusProviders(); + return factory; + } + + public static MicroProfileClientProviderFactory getInstance(Message m) { + Endpoint e = m.getExchange().getEndpoint(); + return getInstance(e); + } + + public static MicroProfileClientProviderFactory getInstance(Endpoint e) { + return (MicroProfileClientProviderFactory)e.get(CLIENT_FACTORY_NAME); + } + + @Override + protected void setProviders(boolean custom, boolean busGlobal, Object... providers) { + List<ProviderInfo<?>> theProviders = + prepareProviders(custom, busGlobal, providers, null); + super.setCommonProviders(theProviders); + for (ProviderInfo<?> provider : theProviders) { + Class<?> providerCls = ClassHelper.getRealClass(getBus(), provider.getProvider()); + + if (ResponseExceptionMapper.class.isAssignableFrom(providerCls)) { + addProviderToList(responseExceptionMappers, provider); + } + + } + responseExceptionMappers.sort(comparator); + + injectContextProxies(responseExceptionMappers); + } + + @SuppressWarnings("unchecked") + public List<ResponseExceptionMapper<?>> createResponseExceptionMapper(Message m, Class<?> paramType) { + + List<ResponseExceptionMapper<?>> candidates = new LinkedList<>(); + + for (ProviderInfo<ResponseExceptionMapper<?>> em : responseExceptionMappers) { + if (handleMapper(em, paramType, m, ResponseExceptionMapper.class, true)) { + candidates.add(em.getProvider()); + } + } + if (candidates.size() == 0) { + return Collections.emptyList(); + } + candidates.sort(new ResponseExceptionMapperComparator()); + return Collections.unmodifiableList(candidates); + } + + @Override + public void clearProviders() { + super.clearProviders(); + responseExceptionMappers.clear(); + } + + @Override + public Configuration getConfiguration(Message m) { + return (Configuration)m.getExchange().getOutMessage() + .getContextualProperty(Configuration.class.getName()); + } + + private class ResponseExceptionMapperComparator implements Comparator<ResponseExceptionMapper<?>> { + + @Override + public int compare(ResponseExceptionMapper<?> oLeft, ResponseExceptionMapper<?> oRight) { + return oLeft.getPriority() - oRight.getPriority(); + } + } +} diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java index 83f7cde..7baec1c 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java @@ -23,15 +23,19 @@ import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; import javax.enterprise.context.Dependent; import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Default; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.InjectionPoint; import javax.enterprise.inject.spi.PassivationCapable; +import javax.enterprise.util.AnnotationLiteral; import org.apache.cxf.microprofile.client.CxfTypeSafeClientBuilder; import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.ConfigProvider; @@ -40,6 +44,7 @@ import org.eclipse.microprofile.rest.client.inject.RestClient; public class RestClientBean implements Bean<Object>, PassivationCapable { public static final String REST_URL_FORMAT = "%s/mp-rest/url"; public static final String REST_SCOPE_FORMAT = "%s/mp-rest/scope"; + private static final Default DEFAULT_LITERAL = new DefaultLiteral(); private final Class<?> clientInterface; private final Class<? extends Annotation> scope; private final BeanManager beanManager; @@ -94,7 +99,7 @@ public class RestClientBean implements Bean<Object>, PassivationCapable { @Override public Set<Annotation> getQualifiers() { - return Collections.singleton(RestClient.LITERAL); + return new HashSet<>(Arrays.asList(DEFAULT_LITERAL, RestClient.RestClientLiteral.LITERAL)); } @Override @@ -150,4 +155,8 @@ public class RestClientBean implements Bean<Object>, PassivationCapable { + " has multiple scopes defined " + possibleScopes); } } + + private static final class DefaultLiteral extends AnnotationLiteral<Default> implements Default { + + } } diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java new file mode 100644 index 0000000..17da4e1 --- /dev/null +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.microprofile.client.proxy; + +import java.lang.reflect.Method; +import java.net.URI; +import java.util.List; +import javax.ws.rs.core.Response; +import org.apache.cxf.jaxrs.client.ClientProxyImpl; +import org.apache.cxf.jaxrs.client.ClientState; +import org.apache.cxf.jaxrs.model.ClassResourceInfo; +import org.apache.cxf.message.Message; +import org.apache.cxf.microprofile.client.MicroProfileClientProviderFactory; +import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; + +public class MicroProfileClientProxyImpl extends ClientProxyImpl { + public MicroProfileClientProxyImpl(URI baseURI, ClassLoader loader, ClassResourceInfo cri, + boolean isRoot, boolean inheritHeaders, Object... varValues) { + super(baseURI, loader, cri, isRoot, inheritHeaders, varValues); + } + + public MicroProfileClientProxyImpl(ClientState initialState, ClassLoader loader, ClassResourceInfo cri, + boolean isRoot, boolean inheritHeaders, Object... varValues) { + super(initialState, loader, cri, isRoot, inheritHeaders, varValues); + } + + @Override + protected void checkResponse(Method m, Response r, Message inMessage) throws Throwable { + MicroProfileClientProviderFactory factory = MicroProfileClientProviderFactory.getInstance(inMessage); + List<ResponseExceptionMapper<?>> mappers = factory.createResponseExceptionMapper(inMessage, + Throwable.class); + for (ResponseExceptionMapper<?> mapper : mappers) { + if (mapper.handles(r.getStatus(), r.getHeaders())) { + Throwable t = mapper.toThrowable(r); + if (t instanceof RuntimeException) { + throw t; + } else if (t != null && m.getExceptionTypes() != null) { + // its a checked exception, make sure its declared + for (Class c : m.getExceptionTypes()) { + if (t.getClass().isAssignableFrom(c)) { + throw t; + } + } + // TODO Log the unhandled declarable + } + } + } + } +} diff --git a/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java b/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java index e903f09..c6bfaf2 100644 --- a/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java +++ b/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java @@ -17,6 +17,7 @@ * under the License. */ package org.apache.cxf.microprofile.client; + import java.net.URL; import javax.ws.rs.core.Response; import org.apache.cxf.microprofile.client.mock.HighPriorityClientReqFilter; @@ -24,9 +25,15 @@ import org.apache.cxf.microprofile.client.mock.HighPriorityMBW; import org.apache.cxf.microprofile.client.mock.LowPriorityClientReqFilter; import org.apache.cxf.microprofile.client.mock.MyClient; import org.eclipse.microprofile.rest.client.RestClientBuilder; - +import org.eclipse.microprofile.rest.client.tck.interfaces.InterfaceWithoutProvidersDefined; +import org.eclipse.microprofile.rest.client.tck.providers.TestClientRequestFilter; +import org.eclipse.microprofile.rest.client.tck.providers.TestClientResponseFilter; +import org.eclipse.microprofile.rest.client.tck.providers.TestMessageBodyReader; +import org.eclipse.microprofile.rest.client.tck.providers.TestMessageBodyWriter; +import org.eclipse.microprofile.rest.client.tck.providers.TestParamConverterProvider; +import org.eclipse.microprofile.rest.client.tck.providers.TestReaderInterceptor; +import org.eclipse.microprofile.rest.client.tck.providers.TestWriterInterceptor; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; public class CxfTypeSafeClientBuilderTest extends Assert { @@ -45,15 +52,47 @@ public class CxfTypeSafeClientBuilderTest extends Assert { } @Test - @Ignore public void testConfigPriorityOverrides() throws Exception { RestClientBuilder builder = RestClientBuilder.newBuilder(); builder.register(HighPriorityClientReqFilter.class); // annotation priority of 10 - builder.register(LowPriorityClientReqFilter.class, 5); // overriding priority to be 5 (preferred) + builder.register(LowPriorityClientReqFilter.class, 5); + // overriding priority to be 5 (preferred) + assertTrue(builder.getConfiguration().isRegistered(LowPriorityClientReqFilter.class)); MyClient c = builder.baseUrl(new URL("http://localhost/null")).build(MyClient.class); Response r = c.get(); assertEquals("low", r.readEntity(String.class)); } + + @Test + public void testInvokesPostOperationWithRegisteredProviders() throws Exception { + String inputBody = "input body will be removed"; + String expectedResponseBody = TestMessageBodyReader.REPLACED_BODY; + + InterfaceWithoutProvidersDefined api = new CxfTypeSafeClientBuilder() + .register(TestClientRequestFilter.class) + .register(TestClientResponseFilter.class) + .register(TestMessageBodyReader.class, 4999) + .register(TestMessageBodyWriter.class) + .register(TestParamConverterProvider.class) + .register(TestReaderInterceptor.class) + .register(TestWriterInterceptor.class) + .baseUrl(new URL("http://localhost/null")) + .build(InterfaceWithoutProvidersDefined.class); + + Response response = api.executePost(inputBody); + + String body = response.readEntity(String.class); + + response.close(); + + assertEquals(expectedResponseBody, body); + + assertEquals(TestClientResponseFilter.getAndResetValue(), 1); + assertEquals(TestClientRequestFilter.getAndResetValue(), 1); + assertEquals(TestReaderInterceptor.getAndResetValue(), 1); + assertEquals(TestWriterInterceptor.getAndResetValue(), 1); + } + /** using for test coverage @Override public RestClientBuilder register(Class<?> componentClass, int priority) { diff --git a/systests/microprofile/client/weld/pom.xml b/systests/microprofile/client/weld/pom.xml index 7df726e..10f8ddf 100644 --- a/systests/microprofile/client/weld/pom.xml +++ b/systests/microprofile/client/weld/pom.xml @@ -120,14 +120,34 @@ <dependency>org.eclipse.microprofile.rest.client:microprofile-rest-client-tck</dependency> </dependenciesToScan> <excludes> - <exclude>org.eclipse.microprofile.rest.client.tck.AdditionalRegistrationTest</exclude> <exclude>org.eclipse.microprofile.rest.client.tck.CallMultipleMappersTest</exclude> <exclude>org.eclipse.microprofile.rest.client.tck.DefaultExceptionMapperTest</exclude> <exclude>org.eclipse.microprofile.rest.client.tck.ExceptionMapperTest</exclude> <exclude>org.eclipse.microprofile.rest.client.tck.InvokeWithJsonPProviderTest</exclude> + <exclude>org.eclipse.microprofile.rest.client.tck.InvalidInterfaceTest</exclude> </excludes> </configuration> </plugin> </plugins> </build> -</project> \ No newline at end of file + <profiles> + <profile> + <id>release-repo</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <repositories> + <repository> + <id>mp-rest-client</id> + <url>https://oss.sonatype.org/content/repositories/orgeclipsemicroprofile-1037/</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + <releases> + <enabled>true</enabled> + </releases> + </repository> + </repositories> + </profile> + </profiles> +</project> -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
