diff --git a/.github/workflows/ci-maven.yaml b/.github/workflows/ci-maven.yaml index 2540ce063b..7c0ed6333d 100644 --- a/.github/workflows/ci-maven.yaml +++ b/.github/workflows/ci-maven.yaml @@ -151,6 +151,21 @@ jobs: # Exclude the root project run: mvn -B -ntp fmt:check + compatibility: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: 11 + distribution: temurin + cache: maven + - run: java -version + - name: Compatibility check + # package jar so that gapic-generator-java module can use + # testlib modules of gax + run: mvn package clirr:check -DskipTests + showcase: runs-on: ubuntu-22.04 strategy: diff --git a/gax-java/dependencies.properties b/gax-java/dependencies.properties index 1b8608303a..c69108447e 100644 --- a/gax-java/dependencies.properties +++ b/gax-java/dependencies.properties @@ -40,17 +40,17 @@ maven.io_opencensus_opencensus_api=io.opencensus:opencensus-api:0.31.1 maven.io_opencensus_opencensus_contrib_grpc_metrics=io.opencensus:opencensus-contrib-grpc-metrics:0.31.1 maven.io_opencensus_opencensus_contrib_http_util=io.opencensus:opencensus-contrib-http-util:0.31.1 maven.io_netty_netty_tcnative_boringssl_static=io.netty:netty-tcnative-boringssl-static:2.0.59.Final -maven.io_netty_netty_handler=io.netty:netty-handler:4.1.89.Final -maven.io_netty_netty_common=io.netty:netty-common:4.1.89.Final -maven.io_netty_netty_codec_socks=io.netty:netty-codec-socks:4.1.89.Final -maven.io_netty_netty_codec_http2=io.netty:netty-codec-http2:4.1.89.Final -maven.io_netty_netty_codec_http=io.netty:netty-codec-http:4.1.89.Final -maven.io_netty_netty_codec=io.netty:netty-codec:4.1.89.Final -maven.io_netty_netty_buffer=io.netty:netty-buffer:4.1.89.Final -maven.io_netty_netty_resolver=io.netty:netty-resolver:4.1.89.Final -maven.io_netty_netty_transport=io.netty:netty-transport:4.1.89.Final -maven.io_netty_netty_handler_proxy=io.netty:netty-handler-proxy:4.1.89.Final -maven.io_netty_netty_transport_native_unix_common=io.netty:netty-transport-native-unix-common:4.1.89.Final +maven.io_netty_netty_handler=io.netty:netty-handler:4.1.90.Final +maven.io_netty_netty_common=io.netty:netty-common:4.1.90.Final +maven.io_netty_netty_codec_socks=io.netty:netty-codec-socks:4.1.90.Final +maven.io_netty_netty_codec_http2=io.netty:netty-codec-http2:4.1.90.Final +maven.io_netty_netty_codec_http=io.netty:netty-codec-http:4.1.90.Final +maven.io_netty_netty_codec=io.netty:netty-codec:4.1.90.Final +maven.io_netty_netty_buffer=io.netty:netty-buffer:4.1.90.Final +maven.io_netty_netty_resolver=io.netty:netty-resolver:4.1.90.Final +maven.io_netty_netty_transport=io.netty:netty-transport:4.1.90.Final +maven.io_netty_netty_handler_proxy=io.netty:netty-handler-proxy:4.1.90.Final +maven.io_netty_netty_transport_native_unix_common=io.netty:netty-transport-native-unix-common:4.1.90.Final maven.io_perfmark_perfmark_api=io.perfmark:perfmark-api:0.26.0 maven.org_apache_tomcat_annotations_api=org.apache.tomcat:annotations-api:6.0.53 maven.com_google_code_gson_gson=com.google.code.gson:gson:2.10.1 diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java index 2edb4ceb2e..cc0ca4c20d 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java @@ -172,7 +172,7 @@ HttpRequest createHttpRequest() throws IOException { jsonFactory.createJsonParser(requestBody).parse(tokenRequest); jsonHttpContent = new JsonHttpContent(jsonFactory, tokenRequest) - .setMediaType((new HttpMediaType("application/json"))); + .setMediaType((new HttpMediaType("application/json; charset=utf-8"))); } else { // Force underlying HTTP lib to set Content-Length header to avoid 411s. // See EmptyContent.java. diff --git a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java index f68b11feba..4e825d679d 100644 --- a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java +++ b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java @@ -36,6 +36,8 @@ import com.google.longrunning.ListOperationsRequest; import com.google.protobuf.Empty; import com.google.protobuf.Field; +import com.google.protobuf.util.JsonFormat; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; @@ -177,4 +179,67 @@ public void testRequestUrlUnnormalizedPatch() throws IOException { Truth.assertThat(httpRequest.getRequestMethod()).isEqualTo("POST"); Truth.assertThat(httpRequest.getHeaders().get("X-HTTP-Method-Override")).isEqualTo("PATCH"); } + + /* + We use a separate RequestFormatter because formatting the body requests is what sets the charset to be UTF-8. + The other tests above do not have a set a body request and instead send an EmptyContent (null Type/ CharSet) + */ + @Test + public void testUnicodeValuesInBody() throws IOException { + HttpRequestFormatter bodyRequestFormatter = + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/name/{name=*}", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + serializer.putPathParam(fields, "name", request.getName()); + return fields; + }) + .setQueryParamsExtractor(request -> new HashMap<>()) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build(), true)) + .build(); + + Field bodyRequestMessage = + Field.newBuilder() + .setName("feline ☺ → ←") + .setNumber(2) + .setDefaultValue("bird ☺ → ←") + .setJsonName("mouse ☺ → ←") + .setTypeUrl("small ☺ → ←") + .build(); + + ApiMethodDescriptor methodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("house.cat.get") + .setHttpMethod("PUT") + .setRequestFormatter(bodyRequestFormatter) + .setResponseParser(responseParser) + .build(); + + HttpRequestRunnable httpRequestRunnable = + new HttpRequestRunnable<>( + bodyRequestMessage, + methodDescriptor, + "www.googleapis.com/animals/v1/projects", + HttpJsonCallOptions.newBuilder().build(), + new MockHttpTransport(), + HttpJsonMetadata.newBuilder().build(), + (result) -> {}); + + HttpRequest httpRequest = httpRequestRunnable.createHttpRequest(); + Truth.assertThat(httpRequest.getContent().getType()) + .isEqualTo("application/json; charset=utf-8"); + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + // writeTo() uses the Charset when writing to the stream + httpRequest.getContent().writeTo(byteArrayOutputStream); + String output = byteArrayOutputStream.toString(); + Field.Builder expectedBuilder = Field.newBuilder(); + JsonFormat.parser().merge(output, expectedBuilder); + Field result = expectedBuilder.build(); + Truth.assertThat(result).isEqualTo(bodyRequestMessage); + } + } } diff --git a/java-iam/pom.xml b/java-iam/pom.xml index 4d43b05cb9..ef5dcabae0 100644 --- a/java-iam/pom.xml +++ b/java-iam/pom.xml @@ -98,7 +98,7 @@ com.google.cloud google-iam-policy - 1.9.4-SNAPSHOT + 1.11.0 com.google.api.grpc