diff --git a/rest5-client/build.gradle.kts b/rest5-client/build.gradle.kts index 0cd314feb..79bc5b4c9 100644 --- a/rest5-client/build.gradle.kts +++ b/rest5-client/build.gradle.kts @@ -138,8 +138,6 @@ signing { } dependencies { - val jacksonVersion = "2.18.3" - // Apache 2.0 // https://hc.apache.org/httpcomponents-client-ga/ api("org.apache.httpcomponents.client5","httpclient5","5.4.4") @@ -151,9 +149,9 @@ dependencies { testImplementation("org.apache.commons:commons-lang3:3.14.0") testImplementation("junit:junit:4.13.2") - // Apache 2.0 - // https://github.com/FasterXML/jackson - implementation("com.fasterxml.jackson.core", "jackson-core", jacksonVersion) + // EPL-2.0 + // https://github.com/eclipse-ee4j/parsson + implementation("org.eclipse.parsson:jakarta.json:1.1.7") // // Apache-2.0 // testImplementation("commons-io:commons-io:2.17.0") diff --git a/rest5-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSniffer.java b/rest5-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSniffer.java index 73e4185c5..6e9d88ef7 100644 --- a/rest5-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSniffer.java +++ b/rest5-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSniffer.java @@ -19,10 +19,10 @@ package co.elastic.clients.transport.rest5_client.low_level.sniffer; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; +import jakarta.json.Json; +import jakarta.json.stream.JsonParser; +import jakarta.json.stream.JsonParserFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hc.core5.http.HttpEntity; @@ -63,7 +63,7 @@ public final class ElasticsearchNodesSniffer implements NodesSniffer { private final Rest5Client restClient; private final Request request; private final Scheme scheme; - private final JsonFactory jsonFactory = new JsonFactory(); + private final JsonParserFactory jsonFactory = Json.createParserFactory(Map.of()); /** * Creates a new instance of the Elasticsearch sniffer. It will use the provided {@link Rest5Client} to fetch the hosts, @@ -107,29 +107,28 @@ public List sniff() throws IOException { return readHosts(response.getEntity(), scheme, jsonFactory); } - static List readHosts(HttpEntity entity, Scheme scheme, JsonFactory jsonFactory) throws IOException { + static List readHosts(HttpEntity entity, Scheme scheme, JsonParserFactory jsonFactory) throws IOException { try (InputStream inputStream = entity.getContent()) { JsonParser parser = jsonFactory.createParser(inputStream); - if (parser.nextToken() != JsonToken.START_OBJECT) { + if (parser.next() != JsonParser.Event.START_OBJECT) { throw new IOException("expected data to start with an object"); } List nodes = new ArrayList<>(); - while (parser.nextToken() != JsonToken.END_OBJECT) { - if (parser.getCurrentToken() == JsonToken.START_OBJECT) { - if ("nodes".equals(parser.getCurrentName())) { - while (parser.nextToken() != JsonToken.END_OBJECT) { - JsonToken token = parser.nextToken(); - assert token == JsonToken.START_OBJECT; - String nodeId = parser.getCurrentName(); + while (parser.next() != JsonParser.Event.END_OBJECT) { + if (parser.currentEvent() == JsonParser.Event.KEY_NAME && "nodes".equals(parser.getString())) { + parser.next(); // from KEY_NAME to START_OBJECT nodes + assert parser.currentEvent() == JsonParser.Event.START_OBJECT; + while (parser.next() != JsonParser.Event.END_OBJECT) { + String nodeId = parser.getString(); Node node = readNode(nodeId, parser, scheme); if (node != null) { nodes.add(node); } } - } else { - parser.skipChildren(); } - } + else if (parser.currentEvent() == JsonParser.Event.START_OBJECT) { + parser.skipObject(); + } } return nodes; } @@ -157,14 +156,15 @@ private static Node readNode(String nodeId, JsonParser parser, Scheme scheme) th final Set roles = new TreeSet<>(); String fieldName = null; - while (parser.nextToken() != JsonToken.END_OBJECT) { - if (parser.getCurrentToken() == JsonToken.FIELD_NAME) { - fieldName = parser.getCurrentName(); - } else if (parser.getCurrentToken() == JsonToken.START_OBJECT) { + while (parser.next() != JsonParser.Event.END_OBJECT) { + if (parser.currentEvent() == JsonParser.Event.KEY_NAME) { + fieldName = parser.getString(); + } else if (parser.currentEvent() == JsonParser.Event.START_OBJECT) { if ("http".equals(fieldName)) { - while (parser.nextToken() != JsonToken.END_OBJECT) { - if (parser.getCurrentToken() == JsonToken.VALUE_STRING && "publish_address".equals(parser.getCurrentName())) { - String address = parser.getValueAsString(); + while (parser.next() != JsonParser.Event.END_OBJECT) { + if (parser.currentEvent() == JsonParser.Event.KEY_NAME && "publish_address".equals(parser.getString())) { + parser.next(); // from KEY_NAME to VALUE_STRING + String address = parser.getString(); String host; URI publishAddressAsURI; @@ -178,45 +178,49 @@ private static Node readNode(String nodeId, JsonParser parser, Scheme scheme) th host = publishAddressAsURI.getHost(); } publishedHost = new HttpHost(publishAddressAsURI.getScheme(), host, publishAddressAsURI.getPort()); - } else if (parser.currentToken() == JsonToken.START_ARRAY && "bound_address".equals(parser.getCurrentName())) { - while (parser.nextToken() != JsonToken.END_ARRAY) { - URI boundAddressAsURI = URI.create(scheme + "://" + parser.getValueAsString()); + } else if (parser.currentEvent() == JsonParser.Event.KEY_NAME && "bound_address".equals(parser.getString())) { + parser.next(); // from KEY_NAME to START_ARRAY + assert parser.currentEvent() == JsonParser.Event.START_ARRAY; + while (parser.next() != JsonParser.Event.END_ARRAY) { + URI boundAddressAsURI = URI.create(scheme + "://" + parser.getString()); boundHosts.add( new HttpHost(boundAddressAsURI.getScheme(), boundAddressAsURI.getHost(), boundAddressAsURI.getPort()) ); } - } else if (parser.getCurrentToken() == JsonToken.START_OBJECT) { - parser.skipChildren(); + } else if (parser.currentEvent() == JsonParser.Event.START_OBJECT) { + parser.skipObject(); } } } else if ("attributes".equals(fieldName)) { - while (parser.nextToken() != JsonToken.END_OBJECT) { - if (parser.getCurrentToken() == JsonToken.VALUE_STRING) { - String oldValue = protoAttributes.put(parser.getCurrentName(), parser.getValueAsString()); + while (parser.next() != JsonParser.Event.END_OBJECT) { + if (parser.currentEvent() == JsonParser.Event.KEY_NAME) { + String key = parser.getString(); + parser.next(); // from KEY_NAME to VALUE_STRING + String value = parser.getString(); + String oldValue = protoAttributes.put(key, value); if (oldValue != null) { - throw new IOException("repeated attribute key [" + parser.getCurrentName() + "]"); + throw new IOException("repeated attribute key [" + parser.currentEvent().name() + "]"); } - } else { - parser.skipChildren(); } } - } else { - parser.skipChildren(); } - } else if (parser.currentToken() == JsonToken.START_ARRAY) { + else if (fieldName != null) { // it's an unknown object that needs to be skipped + parser.skipObject(); + } + } else if (parser.currentEvent() == JsonParser.Event.START_ARRAY) { if ("roles".equals(fieldName)) { sawRoles = true; - while (parser.nextToken() != JsonToken.END_ARRAY) { - roles.add(parser.getText()); + while (parser.next() != JsonParser.Event.END_ARRAY) { + roles.add(parser.getString()); } } else { - parser.skipChildren(); + parser.skipArray(); } - } else if (parser.currentToken().isScalarValue()) { + } else if (parser.currentEvent().name().equals(JsonParser.Event.VALUE_STRING.name())) { if ("version".equals(fieldName)) { - version = parser.getText(); + version = parser.getString(); } else if ("name".equals(fieldName)) { - name = parser.getText(); + name = parser.getString(); } } } diff --git a/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferParseTests.java b/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferParseTests.java index e2ecc3c24..b1b9f841b 100644 --- a/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferParseTests.java +++ b/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferParseTests.java @@ -21,7 +21,7 @@ import co.elastic.clients.transport.rest5_client.low_level.Node; import co.elastic.clients.transport.rest5_client.low_level.RestClientTestCase; -import com.fasterxml.jackson.core.JsonFactory; +import jakarta.json.Json; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpHost; @@ -56,7 +56,8 @@ private void checkFile(String file, Node... expected) throws IOException { } try { HttpEntity entity = new InputStreamEntity(in, ContentType.APPLICATION_JSON); - List nodes = ElasticsearchNodesSniffer.readHosts(entity, ElasticsearchNodesSniffer.Scheme.HTTP, new JsonFactory()); + List nodes = ElasticsearchNodesSniffer.readHosts(entity, + ElasticsearchNodesSniffer.Scheme.HTTP, Json.createParserFactory(Map.of())); /* * Use these assertions because the error messages are nicer * than hasItems and we know the results are in order because @@ -136,7 +137,8 @@ public void testParsingPublishAddressWithPreES7Format() throws IOException { InputStream in = this.getClass().getResourceAsStream("es6_nodes_publication_address_format.json"); HttpEntity entity = new InputStreamEntity(in, ContentType.APPLICATION_JSON); - List nodes = ElasticsearchNodesSniffer.readHosts(entity, ElasticsearchNodesSniffer.Scheme.HTTP, new JsonFactory()); + List nodes = ElasticsearchNodesSniffer.readHosts(entity, + ElasticsearchNodesSniffer.Scheme.HTTP, Json.createParserFactory(Map.of())); assertEquals("127.0.0.1", nodes.get(0).getHost().getHostName()); assertEquals(9200, nodes.get(0).getHost().getPort()); @@ -148,7 +150,8 @@ public void testParsingPublishAddressWithES7Format() throws IOException { InputStream in = this.getClass().getResourceAsStream("es7_nodes_publication_address_format.json"); HttpEntity entity = new InputStreamEntity(in, ContentType.APPLICATION_JSON); - List nodes = ElasticsearchNodesSniffer.readHosts(entity, ElasticsearchNodesSniffer.Scheme.HTTP, new JsonFactory()); + List nodes = ElasticsearchNodesSniffer.readHosts(entity, + ElasticsearchNodesSniffer.Scheme.HTTP, Json.createParserFactory(Map.of())); assertEquals("elastic.test", nodes.get(0).getHost().getHostName()); assertEquals(9200, nodes.get(0).getHost().getPort()); diff --git a/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferTests.java b/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferTests.java index 02f1b67e2..d47afe5c9 100644 --- a/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferTests.java +++ b/rest5-client/src/test/java/co/elastic/clients/transport/rest5_client/low_level/sniffer/ElasticsearchNodesSnifferTests.java @@ -24,12 +24,13 @@ import co.elastic.clients.transport.rest5_client.low_level.ResponseException; import co.elastic.clients.transport.rest5_client.low_level.Rest5Client; import co.elastic.clients.transport.rest5_client.low_level.RestClientTestCase; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; +import jakarta.json.Json; +import jakarta.json.stream.JsonGenerator; +import jakarta.json.stream.JsonGeneratorFactory; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.core5.http.HttpHost; import org.elasticsearch.mocksocket.MockHttpServer; @@ -129,10 +130,10 @@ public void testSniffNodes() throws IOException { Response response = e.getResponse(); if (sniffResponse.isFailure) { final String errorPrefix = "method [GET], host [" - + httpHost - + "], URI [/_nodes/http?timeout=" - + sniffRequestTimeout - + "ms], status line "; + + httpHost + + "], URI [/_nodes/http?timeout=" + + sniffRequestTimeout + + "ms], status line "; assertThat(e.getMessage(), startsWith(errorPrefix)); assertThat(e.getMessage(), containsString(Integer.toString(sniffResponse.nodesInfoResponseCode))); assertThat(response.getHost(), equalTo(httpHost)); @@ -183,18 +184,18 @@ public void handle(HttpExchange httpExchange) throws IOException { private static SniffResponse buildSniffResponse(ElasticsearchNodesSniffer.Scheme scheme) throws IOException { int numNodes = randomIntBetween(1, 5); List nodes = new ArrayList<>(numNodes); - JsonFactory jsonFactory = new JsonFactory(); + JsonGeneratorFactory jsonFactory = Json.createGeneratorFactory(Map.of()); StringWriter writer = new StringWriter(); JsonGenerator generator = jsonFactory.createGenerator(writer); generator.writeStartObject(); if (getRandom().nextBoolean()) { - generator.writeStringField("cluster_name", "elasticsearch"); + generator.write("cluster_name", "elasticsearch"); } if (getRandom().nextBoolean()) { - generator.writeObjectFieldStart("bogus_object"); - generator.writeEndObject(); + generator.writeStartObject("bogus_object"); + generator.writeEnd(); } - generator.writeObjectFieldStart("nodes"); + generator.writeStartObject("nodes"); for (int i = 0; i < numNodes; i++) { String nodeId = randomAsciiLettersOfLengthBetween(5, 10); String host = "host" + i; @@ -256,91 +257,89 @@ private static SniffResponse buildSniffResponse(ElasticsearchNodesSniffer.Scheme attributes ); - generator.writeObjectFieldStart(nodeId); + generator.writeStartObject(nodeId); if (getRandom().nextBoolean()) { - generator.writeObjectFieldStart("bogus_object"); - generator.writeEndObject(); + generator.writeStartObject("bogus_object"); + generator.writeEnd(); } if (getRandom().nextBoolean()) { - generator.writeArrayFieldStart("bogus_array"); + generator.writeStartArray("bogus_array"); generator.writeStartObject(); - generator.writeEndObject(); - generator.writeEndArray(); + generator.writeEnd(); + generator.writeEnd(); } boolean isHttpEnabled = rarely() == false; if (isHttpEnabled) { nodes.add(node); - generator.writeObjectFieldStart("http"); - generator.writeArrayFieldStart("bound_address"); + generator.writeStartObject("http"); + generator.writeStartArray("bound_address"); for (HttpHost bound : boundHosts) { - generator.writeString(bound.toHostString()); + generator.write(bound.toHostString()); } - generator.writeEndArray(); + generator.writeEnd(); if (getRandom().nextBoolean()) { - generator.writeObjectFieldStart("bogus_object"); - generator.writeEndObject(); + generator.writeStartObject("bogus_object"); + generator.writeEnd(); } - generator.writeStringField("publish_address", publishHost.toHostString()); + generator.write("publish_address", publishHost.toHostString()); if (getRandom().nextBoolean()) { - generator.writeNumberField("max_content_length_in_bytes", 104857600); + generator.write("max_content_length_in_bytes", 104857600); } - generator.writeEndObject(); + generator.writeEnd(); } List roles = Arrays.asList( "master", "data", "ingest", "data_content", "data_hot", "data_warm", "data_cold", "data_frozen"); Collections.shuffle(roles, getRandom()); - generator.writeArrayFieldStart("roles"); + generator.writeStartArray("roles"); for (String role : roles) { if ("master".equals(role) && node.getRoles().isMasterEligible()) { - generator.writeString("master"); + generator.write("master"); } if ("data".equals(role) && node.getRoles().hasDataRole()) { - generator.writeString("data"); + generator.write("data"); } if ("data_content".equals(role) && node.getRoles().hasDataContentRole()) { - generator.writeString("data_content"); + generator.write("data_content"); } if ("data_hot".equals(role) && node.getRoles().hasDataHotRole()) { - generator.writeString("data_hot"); + generator.write("data_hot"); } if ("data_warm".equals(role) && node.getRoles().hasDataWarmRole()) { - generator.writeString("data_warm"); + generator.write("data_warm"); } if ("data_cold".equals(role) && node.getRoles().hasDataColdRole()) { - generator.writeString("data_cold"); + generator.write("data_cold"); } if ("data_frozen".equals(role) && node.getRoles().hasDataFrozenRole()) { - generator.writeString("data_frozen"); + generator.write("data_frozen"); } if ("ingest".equals(role) && node.getRoles().isIngest()) { - generator.writeString("ingest"); + generator.write("ingest"); } } - generator.writeEndArray(); + generator.writeEnd(); - generator.writeFieldName("version"); - generator.writeString(node.getVersion()); - generator.writeFieldName("name"); - generator.writeString(node.getName()); + generator.write("version",node.getVersion()); + generator.write("name", node.getName()); if (numAttributes > 0) { - generator.writeObjectFieldStart("attributes"); + generator.writeStartObject("attributes"); for (Map.Entry> entry : attributes.entrySet()) { if (entry.getValue().size() == 1) { - generator.writeStringField(entry.getKey(), entry.getValue().get(0)); + generator.write(entry.getKey(), entry.getValue().get(0)); } else { for (int v = 0; v < entry.getValue().size(); v++) { - generator.writeStringField(entry.getKey() + "." + v, entry.getValue().get(v)); + generator.write(entry.getKey() + "." + v, entry.getValue().get(v)); } } } - generator.writeEndObject(); + generator.writeEnd(); } - generator.writeEndObject(); + generator.writeEnd(); } - generator.writeEndObject(); - generator.writeEndObject(); + generator.writeEnd(); + generator.writeEnd(); generator.close(); return SniffResponse.buildResponse(writer.toString(), nodes); }