Consumes and produces value should be now properly changed (#4175)

* Consumes and produces value should be now properly changed

Signed-off-by: David Kral <david.k.kral@oracle.com>
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 c70f7e4..3189e8f 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
@@ -31,7 +31,6 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
@@ -605,15 +604,18 @@
 
             validateParameters();
             validateHeaderDuplicityNames();
-            Optional<ParamModel> entity = parameterModels.stream()
-                    .filter(ParamModel::isEntity)
-                    .findFirst();
-            if (returnType.getType() instanceof Class && JsonValue.class.isAssignableFrom((Class<?>) returnType.getType())
-                    || (
-                    entity.isPresent() && entity.get().getType() instanceof Class
-                            && JsonValue.class.isAssignableFrom((Class<?>) entity.get().getType()))) {
-                this.consumes = new String[] {MediaType.APPLICATION_JSON};
+
+            if (isJsonValue(returnType.getType())) {
+                this.produces = new String[] {MediaType.APPLICATION_JSON};
             }
+
+            parameterModels.stream()
+                    .filter(ParamModel::isEntity)
+                    .map(ParamModel::getType)
+                    .filter(this::isJsonValue)
+                    .findFirst()
+                    .ifPresent(paramModel -> this.consumes = new String[] {MediaType.APPLICATION_JSON});
+
             return new MethodModel(this);
         }
 
@@ -669,5 +671,9 @@
                 names.add(headerName);
             }
         }
+
+        private boolean isJsonValue(Type type) {
+            return type instanceof Class && JsonValue.class.isAssignableFrom((Class<?>) type);
+        }
     }
 }
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java
index 0f6f8f6..0cb3ad9 100644
--- a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResource.java
@@ -19,9 +19,12 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.json.JsonValue;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
 
 /**
  * Created by David Kral.
@@ -41,6 +44,15 @@
     @POST
     String postAppendValue(String value);
 
+    @POST
+    @Path("getJson")
+    @Consumes(MediaType.APPLICATION_JSON)
+    JsonValue someJsonOperation(JsonValue jsonValue);
+
+    @GET
+    @Path("stringEntity")
+    JsonValue jsonValue();
+
     default String sayHi() {
         return "Hi";
     }
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java
index 10c1a45..e3150a8 100644
--- a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ApplicationResourceImpl.java
@@ -21,6 +21,8 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.json.JsonValue;
+
 /**
  * Created by David Kral.
  */
@@ -43,4 +45,14 @@
         return null;
     }
 
+    @Override
+    public JsonValue someJsonOperation(JsonValue jsonValue) {
+        return null;
+    }
+
+    @Override
+    public JsonValue jsonValue() {
+        return null;
+    }
+
 }
diff --git a/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java
new file mode 100644
index 0000000..7f0363f
--- /dev/null
+++ b/tests/integration/microprofile/rest-client/src/test/java/org/glassfish/jersey/restclient/ConsumesAndProducesTest.java
@@ -0,0 +1,77 @@
+package org.glassfish.jersey.restclient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import javax.json.Json;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.eclipse.microprofile.rest.client.RestClientBuilder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+import org.junit.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Created by David Kral.
+ */
+public class ConsumesAndProducesTest extends JerseyTest {
+    @Override
+    protected ResourceConfig configure() {
+        enable(TestProperties.LOG_TRAFFIC);
+        return new ResourceConfig(ApplicationResourceImpl.class);
+    }
+
+    @Test
+    public void testWithEntity() throws URISyntaxException {
+        ApplicationResource app = RestClientBuilder.newBuilder()
+                .baseUri(new URI("http://localhost:9998"))
+                .register(new TestClientRequestFilter(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON))
+                .build(ApplicationResource.class);
+
+        app.someJsonOperation(Json.createValue(1));
+    }
+
+    @Test
+    public void testWithoutEntity() throws URISyntaxException {
+        ApplicationResource app = RestClientBuilder.newBuilder()
+                .baseUri(new URI("http://localhost:9998"))
+                .register(new TestClientRequestFilter(MediaType.APPLICATION_JSON, MediaType.WILDCARD))
+                .build(ApplicationResource.class);
+
+        app.jsonValue();
+    }
+
+    private class TestClientRequestFilter implements ClientRequestFilter {
+
+        private final String expectedAccept;
+        private final String expectedContentType;
+
+        TestClientRequestFilter(String expectedAccept, String expectedContentType) {
+            this.expectedAccept = expectedAccept;
+            this.expectedContentType = expectedContentType;
+        }
+
+        @Override
+        public void filter(ClientRequestContext requestContext) {
+            assertTrue(requestContext.getHeaders().containsKey("Accept"));
+            List<Object> accept = requestContext.getHeaders().get("Accept");
+            assertTrue(accept.contains(expectedAccept) || accept.contains(MediaType.valueOf(expectedAccept)));
+
+            assertTrue(requestContext.getHeaders().containsKey("Content-Type"));
+            List<Object> contentType = requestContext.getHeaders().get("Content-Type");
+            assertEquals(contentType.size(), 1);
+            assertTrue(contentType.contains(expectedContentType) || contentType.contains(MediaType.valueOf(expectedContentType)));
+
+            requestContext.abortWith(Response.ok().build());
+        }
+    }
+
+}