Skip to content

Commit e74f5c3

Browse files
authored
[7.17] Fix spurious JSON event emitted by JsonpUtils.copy() (#601)
1 parent 2b22f0c commit e74f5c3

File tree

4 files changed

+150
-3
lines changed

4 files changed

+150
-3
lines changed

java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ public static void copy(JsonParser parser, JsonGenerator generator, JsonParser.E
175175

176176
case START_ARRAY:
177177
generator.writeStartArray();
178-
generator.writeStartObject();
179178
while ((event = parser.next()) != Event.END_ARRAY) {
180179
copy(parser, generator, event);
181180
}

java-client/src/test/java/co/elastic/clients/elasticsearch/ElasticsearchTestServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public ElasticsearchTestServer(String... plugins) {
7777
}
7878

7979
public synchronized ElasticsearchTestServer start() {
80-
Version version = Version.VERSION.major() < 8 ? new Version(7,17,5,false) : new Version(8,3,3,false);
80+
Version version = Version.VERSION.major() < 8 ? new Version(7,17,10,false) : new Version(8,3,3,false);
8181

8282
// Note we could use version.major() + "." + version.minor() + "-SNAPSHOT" but plugins won't install on a snapshot version
8383
String esImage = "docker.elastic.co/elasticsearch/elasticsearch:" + version;

java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@
2020
package co.elastic.clients.elasticsearch.spec_issues;
2121

2222
import co.elastic.clients.documentation.usage.Product;
23+
import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
2324
import co.elastic.clients.elasticsearch.ElasticsearchClient;
2425
import co.elastic.clients.elasticsearch.ElasticsearchTestServer;
2526
import co.elastic.clients.elasticsearch._types.ErrorResponse;
27+
import co.elastic.clients.elasticsearch._types.Refresh;
2628
import co.elastic.clients.elasticsearch._types.Script;
2729
import co.elastic.clients.elasticsearch._types.analysis.LimitTokenCountTokenFilter;
2830
import co.elastic.clients.elasticsearch._types.mapping.Property;
2931
import co.elastic.clients.elasticsearch._types.mapping.RuntimeField;
3032
import co.elastic.clients.elasticsearch._types.mapping.RuntimeFieldType;
3133
import co.elastic.clients.elasticsearch.cluster.ClusterStatsResponse;
34+
import co.elastic.clients.elasticsearch.core.GetResponse;
3235
import co.elastic.clients.elasticsearch.core.SearchRequest;
3336
import co.elastic.clients.elasticsearch.core.SearchResponse;
3437
import co.elastic.clients.elasticsearch.core.search.Suggester;
@@ -40,12 +43,15 @@
4043
import co.elastic.clients.elasticsearch.snapshot.RestoreResponse;
4144
import co.elastic.clients.json.JsonData;
4245
import co.elastic.clients.json.JsonpDeserializer;
46+
import co.elastic.clients.util.BinaryData;
47+
import co.elastic.clients.util.ContentType;
4348
import jakarta.json.stream.JsonParser;
4449
import org.junit.jupiter.api.Disabled;
4550
import org.junit.jupiter.api.Test;
4651

4752
import java.io.InputStream;
4853
import java.io.StringReader;
54+
import java.nio.charset.StandardCharsets;
4955

5056
/**
5157
* Test issues related to the API specifications.
@@ -54,6 +60,41 @@
5460
*/
5561
public class SpecIssuesTest extends ModelTestCase {
5662

63+
@Test
64+
public void i0575_asyncBinaryData() throws Exception {
65+
66+
ElasticsearchAsyncClient esAsyncClient = ElasticsearchTestServer.global().asyncClient();
67+
68+
String index = "binary-ingestion-test";
69+
String id = "foo-bar";
70+
71+
BinaryData data = BinaryData.of(
72+
("{\"id\":\"27082ce1-d9ab-404e-a810-f2894640edf4\",\"firstName\":\"Jesse\",\"lastName\":\"Pinkman\",\"addresses\":" +
73+
"[{\"street\":\"1001 Central Ave NE\",\"city\":\"Albuquerque\",\"state\":\"NM\",\"zip\":\"87106\"}]}").getBytes(),
74+
ContentType.APPLICATION_JSON
75+
);
76+
77+
esAsyncClient.index(i -> i
78+
.index(index)
79+
.id(id)
80+
.document(data)
81+
.refresh(Refresh.True)
82+
).get();
83+
84+
GetResponse<BinaryData> getResponse = esAsyncClient.get(g -> g
85+
.index(index)
86+
.id(id)
87+
, BinaryData.class
88+
).get();
89+
90+
assertEquals(id, getResponse.id());
91+
assertEquals(
92+
"{\"id\":\"27082ce1-d9ab-404e-a810-f2894640edf4\",\"firstName\":\"Jesse\",\"lastName\":\"Pinkman\",\"addresses\":" +
93+
"[{\"street\":\"1001 Central Ave NE\",\"city\":\"Albuquerque\",\"state\":\"NM\",\"zip\":\"87106\"}]}",
94+
new String(getResponse.source().asByteBuffer().array(), StandardCharsets.UTF_8)
95+
);
96+
}
97+
5798
@Test
5899
public void i0328_charFilter() throws Exception {
59100
// Both mappings and mappings_path are optional

java-client/src/test/java/co/elastic/clients/json/JsonpUtilsTest.java

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
import co.elastic.clients.elasticsearch.security.IndicesPrivileges;
2626
import co.elastic.clients.elasticsearch.security.RoleTemplateScript;
2727
import co.elastic.clients.elasticsearch.security.UserIndicesPrivileges;
28-
import co.elastic.clients.json.JsonpUtils;
2928
import co.elastic.clients.util.AllowForbiddenApis;
3029
import jakarta.json.JsonException;
3130
import jakarta.json.spi.JsonProvider;
3231
import jakarta.json.stream.JsonGenerator;
32+
import jakarta.json.stream.JsonParser;
3333
import org.junit.jupiter.api.Test;
3434

35+
import java.io.StringReader;
3536
import java.io.StringWriter;
3637
import java.net.URL;
3738
import java.util.Collections;
@@ -209,6 +210,47 @@ public void testJsonString() {
209210
}
210211
}
211212

213+
@Test
214+
public void testCopy() {
215+
// Tests round-tripping a json document that contains all event types and various kinds of nesting
216+
217+
String json = "{\n" +
218+
" \"p1\": \"str1\",\n" +
219+
" \"p2\": 42,\n" +
220+
" \"p3\": [\"str31\", \"str32\"],\n" +
221+
" \"p4\": {\n" +
222+
" \"p41\": \"str41\",\n" +
223+
" \"p42\": [\"str421\", \"str422\"],\n" +
224+
" \"p43\": {\n" +
225+
" \"p431\": \"str431\"\n" +
226+
" },\n" +
227+
" \"p44\": true,\n" +
228+
" \"p45\": false,\n" +
229+
" \"p46\": 3.14\n" +
230+
" },\n" +
231+
" \"p5\": [{\n" +
232+
" \"p51\": {\n" +
233+
" \"p511\": \"str511\"\n" +
234+
" }\n" +
235+
" }],\n" +
236+
" \"p6\": null\n" +
237+
"}\n";
238+
239+
json = normalizeIndent(json);
240+
241+
JsonProvider provider = JsonpUtils.provider();
242+
243+
JsonParser parser = provider.createParser(new StringReader(json));
244+
StringWriter sw = new StringWriter();
245+
JsonGenerator generator = provider.createGenerator(sw);
246+
247+
JsonpUtils.copy(parser, generator);
248+
parser.close();
249+
generator.close();
250+
251+
assertEquals(json, sw.toString());
252+
}
253+
212254
private static String orNullHelper(Consumer<JsonGenerator> c) {
213255
StringWriter sw = new StringWriter();
214256
JsonGenerator generator = JsonpUtils.provider().createGenerator(sw);
@@ -221,4 +263,69 @@ private static String orNullHelper(Consumer<JsonGenerator> c) {
221263

222264
return sw.toString();
223265
}
266+
267+
/**
268+
* Normalizes the whitespace and indentation of a JSON string by parsing it and copying it to a string generator.
269+
*/
270+
private static String normalizeIndent(String json) {
271+
JsonParser parser = JsonpUtils.provider().createParser(new StringReader(json));
272+
StringWriter sw = new StringWriter();
273+
JsonGenerator generator = JsonpUtils.provider().createGenerator(sw);
274+
275+
copyAll(parser, generator);
276+
277+
parser.close();
278+
generator.close();
279+
return sw.toString();
280+
}
281+
282+
private static void copyAll(JsonParser parser, JsonGenerator generator) {
283+
while(parser.hasNext()) {
284+
switch (parser.next()) {
285+
case START_OBJECT:
286+
generator.writeStartObject();
287+
break;
288+
289+
case END_OBJECT:
290+
generator.writeEnd();
291+
break;
292+
293+
case START_ARRAY:
294+
generator.writeStartArray();
295+
break;
296+
297+
case END_ARRAY:
298+
generator.writeEnd();
299+
break;
300+
301+
case KEY_NAME:
302+
generator.writeKey(parser.getString());
303+
break;
304+
305+
case VALUE_STRING:
306+
generator.write(parser.getString());
307+
break;
308+
309+
case VALUE_NULL:
310+
generator.writeNull();
311+
break;
312+
313+
case VALUE_TRUE:
314+
generator.write(true);
315+
break;
316+
317+
case VALUE_FALSE:
318+
generator.write(false);
319+
break;
320+
321+
case VALUE_NUMBER:
322+
if (parser.isIntegralNumber()) {
323+
generator.write(parser.getLong());
324+
} else {
325+
generator.write(parser.getBigDecimal());
326+
}
327+
break;
328+
}
329+
}
330+
}
224331
}

0 commit comments

Comments
 (0)