From d874336e83cedf720a95b4ef6d4f013c29b5d322 Mon Sep 17 00:00:00 2001 From: AntCode97 Date: Wed, 29 May 2024 14:47:10 +0900 Subject: [PATCH] modify to use URLEncodedUtils per version per Classpath --- .../transport/endpoints/SimpleEndpoint.java | 5 +- .../opensearch/client/util/PathEncoder.java | 50 +++++++++++++++++++ .../client/opensearch/model/EndpointTest.java | 28 +++++++++-- .../client/util/PathEncoderTest.java | 31 ++++++++++++ 4 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 java-client/src/main/java/org/opensearch/client/util/PathEncoder.java create mode 100644 java-client/src/test/java/org/opensearch/client/util/PathEncoderTest.java diff --git a/java-client/src/main/java/org/opensearch/client/transport/endpoints/SimpleEndpoint.java b/java-client/src/main/java/org/opensearch/client/transport/endpoints/SimpleEndpoint.java index e7bc433b80..6409c845bc 100644 --- a/java-client/src/main/java/org/opensearch/client/transport/endpoints/SimpleEndpoint.java +++ b/java-client/src/main/java/org/opensearch/client/transport/endpoints/SimpleEndpoint.java @@ -32,14 +32,13 @@ package org.opensearch.client.transport.endpoints; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; import java.util.function.Function; import org.opensearch.client.json.JsonpDeserializer; import org.opensearch.client.opensearch._types.ErrorResponse; import org.opensearch.client.transport.JsonEndpoint; +import org.opensearch.client.util.PathEncoder; public class SimpleEndpoint implements JsonEndpoint { @@ -134,6 +133,6 @@ public static RuntimeException noPathTemplateFound(String what) { } public static void pathEncode(String src, StringBuilder dest) { - dest.append(URLEncoder.encode(src, StandardCharsets.UTF_8)); + dest.append(PathEncoder.encode(src)); } } diff --git a/java-client/src/main/java/org/opensearch/client/util/PathEncoder.java b/java-client/src/main/java/org/opensearch/client/util/PathEncoder.java new file mode 100644 index 0000000000..d64e83ca1f --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/util/PathEncoder.java @@ -0,0 +1,50 @@ +package org.opensearch.client.util; + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Collections; + +public class PathEncoder { + + private final static String httpClient4UtilClassName = "org.apache.http.client.utils.URLEncodedUtils"; + private final static String httpClient5UtilClassName = "org.apache.hc.core5.net.URLEncodedUtils"; + private static final boolean isHttpClient5UtilPresent = isPresent(httpClient5UtilClassName); + + public static String encode(String uri) { + if (isHttpClient5UtilPresent) { + return encodeByUtilClass(uri, httpClient5UtilClassName); + } else { + return encodeByUtilClass(uri, httpClient4UtilClassName); + } + } + + private static String encodeByUtilClass(String uri, String className) { + try { + Method formatSegments = Class.forName(className).getMethod("formatSegments", Iterable.class, Charset.class); + String invoke = (String) formatSegments.invoke(null, Collections.singletonList(uri), StandardCharsets.UTF_8); + return invoke.substring(1); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("Failed to encode URI using " + className, e); + } + } + + private static boolean isPresent(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + +} diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/model/EndpointTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/model/EndpointTest.java index e434e12b85..547e608732 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/model/EndpointTest.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/model/EndpointTest.java @@ -51,10 +51,19 @@ public void testArrayPathParameter() { assertEquals("/a/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); req = RefreshRequest.of(b -> b.index("a", "b")); - assertEquals("/a%2Cb/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + if (isHttpClient5Present()) { + assertEquals("/a%2Cb/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + + } else { + assertEquals("/a,b/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + } req = RefreshRequest.of(b -> b.index("a", "b", "c")); - assertEquals("/a%2Cb%2Cc/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + if (isHttpClient5Present()) { + assertEquals("/a%2Cb%2Cc/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + } else { + assertEquals("/a,b,c/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + } } @Test @@ -65,7 +74,11 @@ public void testPathEncoding() { assertEquals("/a%2Fb/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); req = RefreshRequest.of(b -> b.index("a/b", "c/d")); - assertEquals("/a%2Fb%2Cc%2Fd/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + if (isHttpClient5Present()) { + assertEquals("/a%2Fb%2Cc%2Fd/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + } else { + assertEquals("/a%2Fb,c%2Fd/_refresh", RefreshRequest._ENDPOINT.requestUrl(req)); + } } @@ -84,4 +97,13 @@ public void testArrayQueryParameter() { req = RefreshRequest.of(b -> b.expandWildcards(ExpandWildcard.All, ExpandWildcard.Closed)); assertEquals("all,closed", RefreshRequest._ENDPOINT.queryParameters(req).get("expand_wildcards")); } + + private static boolean isHttpClient5Present() { + try { + Class.forName("org.apache.hc.core5.net.URLEncodedUtils"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } } diff --git a/java-client/src/test/java/org/opensearch/client/util/PathEncoderTest.java b/java-client/src/test/java/org/opensearch/client/util/PathEncoderTest.java new file mode 100644 index 0000000000..d6e90d3a2c --- /dev/null +++ b/java-client/src/test/java/org/opensearch/client/util/PathEncoderTest.java @@ -0,0 +1,31 @@ +package org.opensearch.client.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class PathEncoderTest { + + @Test + public void testEncode() { + // Test with a simple string + String simpleString = "test"; + String encodedSimpleString = PathEncoder.encode(simpleString); + assertEquals(simpleString, encodedSimpleString); + + // Test with a string that contains special characters + String specialString = "a/b"; + String encodedSpecialString = PathEncoder.encode(specialString); + assertEquals("a%2Fb", encodedSpecialString); + + // Test with a string that contains alphanumeric characters + String alphanumericString = "abc123"; + String encodedAlphanumericString = PathEncoder.encode(alphanumericString); + assertEquals("abc123", encodedAlphanumericString); + + // Test with a string that contains multiple segments + String multiSegmentString = "a/b/c/_refresh"; + String encodedMultiSegmentString = PathEncoder.encode(multiSegmentString); + assertEquals("a%2Fb%2Fc%2F_refresh", encodedMultiSegmentString); + } +}