diff --git a/bom/pom.xml b/bom/pom.xml index ab758c75c3..afc591cbfa 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -250,7 +250,7 @@ ${project.version} - org.glassfish.jersey.ext + org.glassfish.jersey.ext.microprofile jersey-mp-rest-client ${project.version} diff --git a/ext/microprofile/mp-rest-client/pom.xml b/ext/microprofile/mp-rest-client/pom.xml index 2bf5598c59..e0e7c40689 100644 --- a/ext/microprofile/mp-rest-client/pom.xml +++ b/ext/microprofile/mp-rest-client/pom.xml @@ -20,8 +20,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - jersey-microprofile - org.glassfish.jersey.ext + project + org.glassfish.jersey.ext.microprofile 2.29.payara-p3-SNAPSHOT 4.0.0 @@ -146,16 +146,26 @@ org.apache.maven.plugins maven-surefire-plugin - - - - tck-suite.xml - - + + + + tck + + test + + test + + + + tck-suite.xml + + + + uk.co.deliverymind diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ConfigWrapper.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ConfigWrapper.java index 466ab38895..597990e9b6 100644 --- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ConfigWrapper.java +++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ConfigWrapper.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + package org.glassfish.jersey.microprofile.restclient; import java.util.Collection; diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ExecutorServiceWrapper.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ExecutorServiceWrapper.java index c3a8dd66ae..54599e8d94 100644 --- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ExecutorServiceWrapper.java +++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/ExecutorServiceWrapper.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + package org.glassfish.jersey.microprofile.restclient; import java.util.Collection; diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java index e7a292593c..fa240f5df9 100644 --- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java +++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/MethodModel.java @@ -83,7 +83,6 @@ class MethodModel { private final InterfaceModel interfaceModel; private final Method method; - private final Class returnType; private final String httpMethod; private final String path; private final String[] produces; @@ -102,7 +101,6 @@ class MethodModel { */ static MethodModel from(InterfaceModel interfaceModel, Method method) { return new Builder(interfaceModel, method) - .returnType(method.getGenericReturnType()) .httpMethod(parseHttpMethod(interfaceModel, method)) .pathValue(method.getAnnotation(Path.class)) .produces(method.getAnnotation(Produces.class)) @@ -115,7 +113,6 @@ static MethodModel from(InterfaceModel interfaceModel, Method method) { private MethodModel(Builder builder) { this.method = builder.method; this.interfaceModel = builder.interfaceModel; - this.returnType = builder.returnType; this.httpMethod = builder.httpMethod; this.path = builder.pathValue; this.produces = builder.produces; @@ -124,12 +121,18 @@ private MethodModel(Builder builder) { this.clientHeaders = builder.clientHeaders; this.invocationInterceptors = builder.invocationInterceptors; if (httpMethod.isEmpty()) { - subResourceModel = RestClientModel.from(returnType, - interfaceModel.getResponseExceptionMappers(), - interfaceModel.getParamConverterProviders(), - interfaceModel.getAsyncInterceptors(), - interfaceModel.getInjectionManager(), - interfaceModel.getBeanManager()); + Type returnType = method.getGenericReturnType(); + if (returnType instanceof Class) { + subResourceModel = RestClientModel.from((Class) returnType, + interfaceModel.getResponseExceptionMappers(), + interfaceModel.getParamConverterProviders(), + interfaceModel.getAsyncInterceptors(), + interfaceModel.getInjectionManager(), + interfaceModel.getBeanManager()); + } else { + throw new IllegalArgumentException("Subresource represented by method " + method.getName() + + " must be non-generic class"); + } } else { subResourceModel = null; } @@ -177,7 +180,7 @@ Object invokeMethod(WebTarget classLevelTarget, Method method, Object[] args) { WebTarget webTarget = webTargetAtomicReference.get(); if (httpMethod.isEmpty()) { //sub resource method - return subResourceProxy(webTarget, returnType); + return subResourceProxy(webTarget); } webTarget = addQueryParams(webTarget, args); webTarget = addMatrixParams(webTarget, args); @@ -211,12 +214,12 @@ private Object synchronousCall(Invocation.Builder builder, Object entity, Method evaluateResponse(response, method); - if (returnType.equals(Void.class)) { + if (method.getReturnType().equals(Void.class)) { return null; - } else if (returnType.equals(Response.class)) { + } else if (method.getReturnType().equals(Response.class)) { return response; } - return response.readEntity(returnType); + return response.readEntity(new GenericType<>(method.getGenericReturnType())); } private CompletableFuture asynchronousCall(Invocation.Builder builder, Object entity, Method method) { @@ -237,9 +240,9 @@ private CompletableFuture asynchronousCall(Invocation.Builder builder, Object en interfaceModel.getAsyncInterceptors().forEach(AsyncInvocationInterceptor::removeContext); try { evaluateResponse(response, method); - if (returnType.equals(Void.class)) { + if (actualTypeArgument.equals(Void.class)) { result.complete(null); - } else if (returnType.equals(Response.class)) { + } else if (actualTypeArgument.equals(Response.class)) { result.complete(response); } else { result.complete(response.readEntity(new GenericType<>(actualTypeArgument))); @@ -257,9 +260,10 @@ private CompletableFuture asynchronousCall(Invocation.Builder builder, Object en } @SuppressWarnings("unchecked") - private T subResourceProxy(WebTarget webTarget, Class subResourceType) { - return (T) Proxy.newProxyInstance(subResourceType.getClassLoader(), - new Class[] {subResourceType}, + private T subResourceProxy(WebTarget webTarget) { + Class subResourceClass = subResourceModel.getRestClientClass(); + return (T) Proxy.newProxyInstance(subResourceClass.getClassLoader(), + new Class[] {subResourceClass}, new ProxyInvocationHandler(webTarget, subResourceModel) ); } @@ -460,7 +464,6 @@ private static class Builder { private final InterfaceModel interfaceModel; private final Method method; - private Class returnType; private String httpMethod; private String pathValue; private String[] produces; @@ -505,21 +508,6 @@ private void filterAllInterceptorAnnotations() { } } - /** - * Return type of the method. - * - * @param returnType Method return type - * @return updated Builder instance - */ - Builder returnType(Type returnType) { - if (returnType instanceof ParameterizedType) { - this.returnType = (Class) ((ParameterizedType) returnType).getActualTypeArguments()[0]; - } else { - this.returnType = (Class) returnType; - } - return this; - } - /** * HTTP method of the method. * @@ -603,7 +591,7 @@ MethodModel build() { Optional entity = parameterModels.stream() .filter(ParamModel::isEntity) .findFirst(); - if (JsonValue.class.isAssignableFrom(returnType) + if (JsonValue.class.isAssignableFrom(method.getReturnType()) || ( entity.isPresent() && entity.get().getType() instanceof Class && JsonValue.class.isAssignableFrom((Class) entity.get().getType()))) { diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java index 4e81ca3833..94c86fb166 100644 --- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java +++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientModel.java @@ -102,6 +102,10 @@ Object invokeMethod(WebTarget baseWebTarget, Method method, Object[] args) { } } + Class getRestClientClass() { + return interfaceModel.getRestClientClass(); + } + private static Map parseMethodModels(InterfaceModel classModel) { Map methodMap = new HashMap<>(); for (Method method : classModel.getRestClientClass().getMethods()) { diff --git a/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResource.java b/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResource.java index caf3bb650e..b2a6a25cde 100644 --- a/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResource.java +++ b/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResource.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -16,12 +17,19 @@ package org.glassfish.jersey.microprofile.restclient; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import java.util.List; +import java.util.Map; /** - * Created by David Kral. + * @author David Kral + * @author Patrik Dudits */ @Path("resource") @@ -33,6 +41,20 @@ public interface ApplicationResource { @POST String postAppendValue(String value); + @Path("list/{size}") + @GET + List list(@PathParam("size") int size); + + @Path("intmap/{size}") + @GET + Map map(@PathParam("size") int size); + + @Path("list") + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + Map acceptList(List numbers); + default String sayHi() { return "Hi"; } diff --git a/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResourceImpl.java b/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResourceImpl.java index 4194b40e8c..93cfd06786 100644 --- a/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResourceImpl.java +++ b/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/ApplicationResourceImpl.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -16,8 +17,16 @@ package org.glassfish.jersey.microprofile.restclient; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + /** - * Created by David Kral. + * @author David Kral + * @author Patrik Dudits */ public class ApplicationResourceImpl implements ApplicationResource { @Override @@ -29,4 +38,21 @@ public String getValue() { public String postAppendValue(String value) { return null; } + + @Override + public List list(int size) { + return IntStream.rangeClosed(1, size).mapToObj(i -> "int" + i).collect(Collectors.toList()); + } + + @Override + public Map map(int size) { + return IntStream.rangeClosed(1, size).mapToObj(i -> i).collect(Collectors.toMap(String::valueOf, Function.identity())); + } + + @Override + public Map acceptList(List numbers) { + Map result = new HashMap<>(); + result.put("size", numbers != null ? numbers.size() : -1); + return result; + } } diff --git a/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/RestClientModelTest.java b/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/RestClientModelTest.java index 046f528e23..6f24978510 100644 --- a/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/RestClientModelTest.java +++ b/ext/microprofile/mp-rest-client/src/test/java/org/glassfish/jersey/microprofile/restclient/RestClientModelTest.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -18,6 +19,8 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Map; import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.glassfish.jersey.server.ResourceConfig; @@ -28,7 +31,8 @@ import static org.junit.Assert.assertEquals; /** - * Created by David Kral. + * @author David Kral + * @author Patrik Dudits */ public class RestClientModelTest extends JerseyTest { @Override @@ -45,4 +49,33 @@ public void testGetIt() throws URISyntaxException { assertEquals("This is default value!", app.getValue()); assertEquals("Hi", app.sayHi()); } + + @Test + public void testList() { + ApplicationResource app = RestClientBuilder.newBuilder() + .baseUri(URI.create("http://localhost:9998")) + .build(ApplicationResource.class); + assertEquals(Arrays.asList("int1", "int2", "int3"), app.list(3)); + } + + @Test + public void testMap() { + ApplicationResource app = RestClientBuilder.newBuilder() + .baseUri(URI.create("http://localhost:9998")) + .build(ApplicationResource.class); + Map map = app.map(20); + assertEquals(20, map.size()); + for (Map.Entry entry : map.entrySet()) { + assertEquals(entry.getKey(), entry.getValue().toString()); + } + } + + @Test + public void testListParameter() { + ApplicationResource app = RestClientBuilder.newBuilder() + .baseUri(URI.create("http://localhost:9998")) + .build(ApplicationResource.class); + Map result = app.acceptList(Arrays.asList(1, 2, 3, 4, 5)); + assertEquals(5, result.get("size").intValue()); + } } diff --git a/ext/microprofile/pom.xml b/ext/microprofile/pom.xml index 314d1efe01..7143024fe5 100644 --- a/ext/microprofile/pom.xml +++ b/ext/microprofile/pom.xml @@ -9,7 +9,8 @@ 4.0.0 - jersey-microprofile + org.glassfish.jersey.ext.microprofile + project pom