diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-11-23 16:07:43 +0100 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2023-11-23 16:12:51 +0100 |
commit | ef535f6c51393d945d9fe07de38de224d5ae443f (patch) | |
tree | 2f5976537a200aebbf6644b8e1ef93f2c669319d | |
parent | f966346429c85fc31c8ea962b518e02a19f77f46 (diff) |
jackson 2.16 changes some of its default settings so we consolidate our use of the ObjectMapper.
Unless special options are used, use a common instance, or create via factory metod.
88 files changed, 349 insertions, 393 deletions
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/hostinfo/HostInfo.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/hostinfo/HostInfo.java index 226979eb2b9..8816aa6c75d 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/hostinfo/HostInfo.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/hostinfo/HostInfo.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.core.hostinfo; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -17,7 +18,7 @@ import java.util.logging.Logger; public class HostInfo { private static final Logger log = Logger.getLogger(HostInfo.class.getName()); - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.createMapper(); private String rawCreationString = "NOT SET"; static { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/Response.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/Response.java index 89b1cf78b3e..636d01dbfa3 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/Response.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/Response.java @@ -45,11 +45,11 @@ public class Response { } @Override - public String getId() { return id; } + public String id() { return id; } @Override - public String getReason() { return reason; } + public String reason() { return reason; } @Override - public String toString() { return getId() +": " + getReason(); } + public String toString() { return id() +": " + reason(); } } public static class Link implements SubUnitList { private final Map<String, String> links = new LinkedHashMap<>(); diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequest.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequest.java index 04a0e762331..06a74b34f96 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequest.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequest.java @@ -71,14 +71,14 @@ public class SetNodeStateRequest extends Request<SetResponse> { static NodeState getRequestedNodeState(Map<String, UnitState> newStates, Node n) throws StateRestApiException { UnitState newState = newStates.get("user"); if (newState == null) throw new InvalidContentException("No new user state given in request"); - State state = switch (newState.getId().toLowerCase()) { + State state = switch (newState.id().toLowerCase()) { case "up" -> State.UP; case "retired" -> State.RETIRED; case "maintenance" -> State.MAINTENANCE; case "down" -> State.DOWN; - default -> throw new InvalidContentException("Invalid user state '" + newState.getId() + "' given."); + default -> throw new InvalidContentException("Invalid user state '" + newState.id() + "' given."); }; - return new NodeState(n.getType(), state).setDescription(newState.getReason()); + return new NodeState(n.getType(), state).setDescription(newState.reason()); } @Override diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/ContentClusterHtmlRendererTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/ContentClusterHtmlRendererTest.java index 6d05a7cd963..33b6820db4d 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/ContentClusterHtmlRendererTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/ContentClusterHtmlRendererTest.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.core; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import com.google.common.collect.Sets; import com.yahoo.vdslib.state.ClusterState; import com.yahoo.vespa.clustercontroller.core.hostinfo.HostInfo; @@ -38,7 +38,7 @@ public class ContentClusterHtmlRendererTest { for (int x = 0; x < 10; x++) { NodeInfo nodeInfo = new DistributorNodeInfo(contentCluster, x, "dist " + x, null); - String json = new ObjectMapper().writeValueAsString(Map.of("vtag", Map.of("version", "release1" + (x == 2 ? "bad" : "")))); + String json = Jackson.mapper().writeValueAsString(Map.of("vtag", Map.of("version", "release1" + (x == 2 ? "bad" : "")))); nodeInfo.setHostInfo(HostInfo.createHostInfo(json)); distributorNodeInfoByIndex.put(x, nodeInfo); } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/SetNodeStateTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/SetNodeStateTest.java index 862ab36fb3c..15d1425202e 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/SetNodeStateTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/SetNodeStateTest.java @@ -64,17 +64,17 @@ public class SetNodeStateTest extends StateRestApiTest { final String reason) { newStates.put(type, new UnitState() { @Override - public String getId() { + public String id() { return state; } @Override - public String getReason() { + public String reason() { return reason; } @Override - public String toString() { return getId() +": " + getReason(); } + public String toString() { return id() +": " + reason(); } }); return this; } @@ -117,9 +117,9 @@ public class SetNodeStateTest extends StateRestApiTest { restAPI.setUnitState(new SetUnitStateRequestImpl("music").setNewState("user", state, reason)); for (int index : new int[]{1, 2, 3, 5, 7}) { UnitResponse response = restAPI.getState(new StateRequest("music/storage/" + index, 0)); - String actualState = response.getCurrentState().getStatePerType().get("user").getId(); + String actualState = response.getCurrentState().getStatePerType().get("user").id(); assertThat(actualState, is(state.toLowerCase())); - String actualReason = response.getCurrentState().getStatePerType().get("user").getReason(); + String actualReason = response.getCurrentState().getStatePerType().get("user").reason(); assertThat(actualReason, is(reason)); } } @@ -264,8 +264,8 @@ public class SetNodeStateTest extends StateRestApiTest { Response.NodeResponse nodeResponse = (Response.NodeResponse) response; UnitState unitState = nodeResponse.getStatePerType().get(type); assertNotNull(unitState, "No such type " + type + " at path " + path); - assertEquals(state.toString().toLowerCase(), unitState.getId()); - assertEquals(reason, unitState.getReason()); + assertEquals(state.toString().toLowerCase(), unitState.id()); + assertEquals(reason, unitState.reason()); } private void assertSetUnitState(int index, State state, String failureReason) throws StateRestApiException { diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequestTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequestTest.java index 26ac5325f29..e5543de0546 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequestTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/requests/SetNodeStateRequestTest.java @@ -127,8 +127,8 @@ public class SetNodeStateRequestTest { NodeState storageNodeState = new NodeState(NodeType.STORAGE, storageWantedState); when(storageNodeInfo.getUserWantedState()).thenReturn(storageNodeState); - when(unitState.getId()).thenReturn(wantedStateString); - when(unitState.getReason()).thenReturn(REASON); + when(unitState.id()).thenReturn(wantedStateString); + when(unitState.reason()).thenReturn(REASON); when(cluster.calculateEffectOfNewState(any(), any(), any(), any(), any(), anyBoolean())).thenReturn(result); diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonHttpResult.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonHttpResult.java index f62c97696ba..aa59ef6fbf9 100644 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonHttpResult.java +++ b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonHttpResult.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.utils.communication.http; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -8,7 +9,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; public class JsonHttpResult extends HttpResult { - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); private JsonNode json; private boolean failedParsing = false; diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/response/UnitState.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/response/UnitState.java index b734e763698..8b2e6d8d202 100644 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/response/UnitState.java +++ b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/response/UnitState.java @@ -3,7 +3,7 @@ package com.yahoo.vespa.clustercontroller.utils.staterestapi.response; public interface UnitState { - String getId(); - String getReason(); + String id(); + String reason(); } diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonReader.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonReader.java index ba641bf0deb..78932cb4272 100644 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonReader.java +++ b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonReader.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.utils.staterestapi.server; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest; import com.yahoo.vespa.clustercontroller.utils.staterestapi.errors.InvalidContentException; @@ -15,31 +15,13 @@ import java.util.Map; public class JsonReader { - private static final ObjectMapper mapper = new ObjectMapper(); - - private static class UnitStateImpl implements UnitState { - - private final String id; - private final String reason; - - public UnitStateImpl(String id, String reason) { - this.id = id; - this.reason = reason; - } + private record UnitStateImpl(String id, String reason) implements UnitState { @Override - public String getId() { - return id; + public String toString() { + return id() + ": " + reason(); } - @Override - public String getReason() { - return reason; - } - - @Override - public String toString() { return getId() +": " + getReason(); } - } static class SetRequestData { @@ -60,7 +42,7 @@ public class JsonReader { } public SetRequestData getStateRequestData(HttpRequest request) throws Exception { - JsonNode json = mapper.readTree(request.getPostContent().toString()); + JsonNode json = Jackson.mapper().readTree(request.getPostContent().toString()); final boolean probe = json.has("probe") && json.get("probe").booleanValue(); diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonWriter.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonWriter.java index 64e17873ae2..5c2c90b2b9c 100644 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonWriter.java +++ b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/server/JsonWriter.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.utils.staterestapi.server; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.vespa.clustercontroller.utils.staterestapi.response.CurrentUnitState; @@ -19,8 +19,6 @@ import java.util.Map; public class JsonWriter { - private static final ObjectMapper mapper = new ObjectMapper(); - private String pathPrefix = "/"; public JsonWriter() { } @@ -33,7 +31,7 @@ public class JsonWriter { } public JsonNode createJson(UnitResponse data) { - ObjectNode json = new ObjectNode(mapper.getNodeFactory()); + ObjectNode json = new ObjectNode(Jackson.mapper().getNodeFactory()); fillInJson(data, json); return json; } @@ -65,8 +63,8 @@ public class JsonWriter { ObjectNode stateJson = json.putObject("state"); Map<String, UnitState> state = stateData.getStatePerType(); state.forEach((stateType, unitState) -> stateJson.putObject(stateType) - .put("state", unitState.getId()) - .put("reason", unitState.getReason())); + .put("state", unitState.id()) + .put("reason", unitState.reason())); } public void fillInJson(Map<String, SubUnitList> subUnitMap, ObjectNode json) { @@ -94,11 +92,11 @@ public class JsonWriter { } public JsonNode createErrorJson(String description) { - return new ObjectNode(mapper.getNodeFactory()).put("message", description); + return new ObjectNode(Jackson.mapper().getNodeFactory()).put("message", description); } public JsonNode createJson(SetResponse setResponse) { - return new ObjectNode(mapper.getNodeFactory()).put("wasModified", setResponse.getWasModified()) + return new ObjectNode(Jackson.mapper().getNodeFactory()).put("wasModified", setResponse.getWasModified()) .put("reason", setResponse.getReason()); } diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/DummyStateApi.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/DummyStateApi.java index 88f1b49f92e..a73e20b8755 100644 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/DummyStateApi.java +++ b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/DummyStateApi.java @@ -125,11 +125,11 @@ public class DummyStateApi implements StateRestAPI { Map<String, UnitState> m = new LinkedHashMap<>(); m.put("current", new UnitState() { @Override - public String getId() { return node.state; } + public String id() { return node.state; } @Override - public String getReason() { return node.reason; } + public String reason() { return node.reason; } @Override - public String toString() { return getId() +": " + getReason(); } + public String toString() { return id() +": " + reason(); } }); return m; } @@ -192,8 +192,8 @@ public class DummyStateApi implements StateRestAPI { if (newState.size() != 1 || !newState.containsKey("current")) { throw new InvalidContentException("Only state of type 'current' is allowed to be set."); } - n.state = newState.get("current").getId(); - n.reason = newState.get("current").getReason(); + n.state = newState.get("current").id(); + n.reason = newState.get("current").reason(); String reason = String.format("DummyStateAPI %s call", request.getResponseWait().getName()); return new SetResponse(reason, true); } diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/StateRestAPITest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/StateRestAPITest.java index 97d9531a28f..f5166cab25a 100644 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/StateRestAPITest.java +++ b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/staterestapi/StateRestAPITest.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.utils.staterestapi; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -30,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.fail; public class StateRestAPITest { - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); private static void populateDummyBackend(DummyBackend backend) { backend.addCluster(new DummyBackend.Cluster("foo") diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java index 160b8a3d43b..3391af1a4e0 100644 --- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java +++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.application.provider; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.io.IOUtils; @@ -29,7 +30,7 @@ public class FilesApplicationFile extends ApplicationFile { private static final Logger log = Logger.getLogger("FilesApplicationFile"); private final File file; - private final ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper = Jackson.mapper(); public FilesApplicationFile(Path path, File file) { super(path); diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxMemoryStats.java b/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxMemoryStats.java index c45d69f02cb..73838c399ca 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxMemoryStats.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxMemoryStats.java @@ -2,8 +2,8 @@ package com.yahoo.config.model.api; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.path.Path; @@ -19,7 +19,6 @@ import java.util.Optional; public record OnnxMemoryStats(long vmSize, long vmRss, long mallocPeak, long mallocCurrent) { private static final String VM_SIZE_FIELD = "vm_size", VM_RSS_FIELD = "vm_rss", MALLOC_PEAK_FIELD = "malloc_peak", MALLOC_CURRENT_FIELD = "malloc_current"; - private static final ObjectMapper jsonParser = new ObjectMapper(); /** Parse output from `vespa-analyze-onnx-model --probe-types` */ public static OnnxMemoryStats fromJson(JsonNode json) { @@ -31,7 +30,7 @@ public record OnnxMemoryStats(long vmSize, long vmRss, long mallocPeak, long mal /** @see #fromJson(JsonNode) */ public static OnnxMemoryStats fromJson(ApplicationFile file) throws IOException { - return fromJson(jsonParser.readTree(file.createReader())); + return fromJson(Jackson.mapper().readTree(file.createReader())); } public static Path memoryStatsFilePath(Path modelPath) { @@ -42,7 +41,7 @@ public record OnnxMemoryStats(long vmSize, long vmRss, long mallocPeak, long mal public long peakMemoryUsage() { return Long.max(vmSize, Long.max(vmRss, Long.max(mallocPeak, mallocCurrent))); } public JsonNode toJson() { - return jsonParser.createObjectNode().put(VM_SIZE_FIELD, vmSize).put(VM_RSS_FIELD, vmRss) + return Jackson.mapper().createObjectNode().put(VM_SIZE_FIELD, vmSize).put(VM_RSS_FIELD, vmRss) .put(MALLOC_PEAK_FIELD, mallocPeak).put(MALLOC_CURRENT_FIELD, mallocCurrent); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelInfo.java b/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelInfo.java index c622b4d58b4..59779df5ea2 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelInfo.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelInfo.java @@ -1,11 +1,11 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.ml; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.io.IOUtils; @@ -91,7 +91,7 @@ public class OnnxModelInfo { resolveUnknownDimensionSizes(inputTypes, symbolicSizes, unboundSizes); TensorType type = TensorType.empty; - if (inputTypes.size() > 0 && onnxTypeInfo.needModelProbe(symbolicSizes)) { + if (!inputTypes.isEmpty() && onnxTypeInfo.needModelProbe(symbolicSizes)) { type = OnnxModelProbe.probeModel(app, Path.fromString(modelPath), onnxName, inputTypes); } if (type.equals(TensorType.empty)) { @@ -242,8 +242,7 @@ public class OnnxModelInfo { } static public OnnxModelInfo jsonToModelInfo(String json, ApplicationPackage app) throws IOException { - ObjectMapper m = new ObjectMapper(); - JsonNode root = m.readTree(json); + JsonNode root = Jackson.mapper().readTree(json); Map<String, OnnxTypeInfo> inputs = new HashMap<>(); Map<String, OnnxTypeInfo> outputs = new HashMap<>(); Set<String> initializers = new HashSet<>(); @@ -306,32 +305,30 @@ public class OnnxModelInfo { } private static String onnxValueTypeToString(Onnx.TensorProto.DataType dataType) { - switch (dataType) { - case FLOAT: return "float"; - case DOUBLE: return "double"; + return switch (dataType) { + case FLOAT -> "float"; + case DOUBLE -> "double"; // Imperfect conversion, for now: - case BOOL: return "float"; - case INT8: return "float"; - case INT16: return "float"; - case INT32: return "float"; - case INT64: return "float"; - case UINT8: return "float"; - case UINT16: return "float"; - case UINT32: return "float"; - case UINT64: return "float"; - default: - throw new IllegalArgumentException("A ONNX tensor with data type " + dataType + - " cannot be converted to a Vespa tensor type"); - } + case BOOL -> "float"; + case INT8 -> "float"; + case INT16 -> "float"; + case INT32 -> "float"; + case INT64 -> "float"; + case UINT8 -> "float"; + case UINT16 -> "float"; + case UINT32 -> "float"; + case UINT64 -> "float"; + default -> throw new IllegalArgumentException("A ONNX tensor with data type " + dataType + + " cannot be converted to a Vespa tensor type"); + }; } private static TensorType.Value stringToValueType(String type) { - switch (type) { - case "float": return TensorType.Value.FLOAT; - case "double": return TensorType.Value.DOUBLE; - default: - throw new IllegalArgumentException("Unknown tensor value type: " + type); - } + return switch (type) { + case "float" -> TensorType.Value.FLOAT; + case "double" -> TensorType.Value.DOUBLE; + default -> throw new IllegalArgumentException("Unknown tensor value type: " + type); + }; } public static String asValidIdentifier(String str) { @@ -389,7 +386,7 @@ public class OnnxModelInfo { onnxDimensionSize = unknownSizes.iterator().next(); } } - if (onnxDimensionSize < 0 && unboundSizes != null && unboundSizes.size() > 0) { + if (onnxDimensionSize < 0 && unboundSizes != null && !unboundSizes.isEmpty()) { onnxDimensionSize = unboundSizes.iterator().next(); } if (onnxDimensionSize <= 0) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelProbe.java b/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelProbe.java index 0f89a839a26..c341149f5a2 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelProbe.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelProbe.java @@ -1,11 +1,11 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.ml; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.api.OnnxMemoryStats; @@ -31,7 +31,6 @@ import java.util.Map; public class OnnxModelProbe { private static final String binary = "vespa-analyze-onnx-model"; - private static final ObjectMapper jsonParser = new ObjectMapper(); static TensorType probeModel(ApplicationPackage app, Path modelPath, String outputName, Map<String, TensorType> inputTypes) { TensorType outputType = TensorType.empty; @@ -155,6 +154,6 @@ public class OnnxModelProbe { throw new IllegalArgumentException("Error from '" + binary + "'. Return code: " + returnCode + ". " + "Output: '" + output + "'"); } - return jsonParser.readTree(output.toString()); + return Jackson.mapper().readTree(output.toString()); } } diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java index 45c49dddbf0..5afe519841b 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.configserver.flags.http; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -16,7 +17,7 @@ import java.io.OutputStream; * @author hakonhall */ public class DefinedFlag extends HttpResponse { - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); private final FlagDefinition flagDefinition; diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlags.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlags.java index 93a7abc8348..732cf582e24 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlags.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlags.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.configserver.flags.http; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.container.jdisc.HttpResponse; @@ -16,7 +17,7 @@ import java.util.List; * @author hakonhall */ public class DefinedFlags extends HttpResponse { - private static ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); private static final Comparator<FlagDefinition> sortByFlagId = Comparator.comparing(flagDefinition -> flagDefinition.getUnboundFlag().id()); private final List<FlagDefinition> flags; diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagDataListResponse.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagDataListResponse.java index 3530075442f..49d5b00f716 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagDataListResponse.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagDataListResponse.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.configserver.flags.http; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -20,7 +21,7 @@ import static com.yahoo.yolean.Exceptions.uncheck; * @author hakonhall */ public class FlagDataListResponse extends HttpResponse { - private static ObjectMapper mapper = new ObjectMapper(); + private static ObjectMapper mapper = Jackson.mapper(); private final String flagsV1Uri; private final TreeMap<FlagId, FlagData> flags; diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java index 0a779a3cd5f..ebeb0e711bf 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java @@ -1,9 +1,9 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.application; +import ai.vespa.json.Jackson; import ai.vespa.util.http.hc5.VespaAsyncHttpClientBuilder; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.component.AbstractComponent; import com.yahoo.component.annotation.Inject; import com.yahoo.concurrent.DaemonThreadFactory; @@ -79,7 +79,6 @@ public class ConfigConvergenceChecker extends AbstractComponent { private final ExecutorService responseHandlerExecutor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("config-convergence-checker-response-handler-")); - private final ObjectMapper jsonMapper = new ObjectMapper(); @Inject public ConfigConvergenceChecker() {} @@ -220,7 +219,7 @@ public class ConfigConvergenceChecker extends AbstractComponent { int statusCode = response.getCode(); if (statusCode != HttpStatus.SC_OK) throw new IOException("Expected status code 200, got " + statusCode); if (response.getBody() == null) throw new IOException("Response has no content"); - return generationFromContainerState(jsonMapper.readTree(response.getBodyText())); + return generationFromContainerState(Jackson.mapper().readTree(response.getBodyText())); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/DefaultClusterReindexingStatusClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/DefaultClusterReindexingStatusClient.java index a72a430a694..4a7d07f2d8e 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/DefaultClusterReindexingStatusClient.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/DefaultClusterReindexingStatusClient.java @@ -1,9 +1,9 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.application; +import ai.vespa.json.Jackson; import ai.vespa.util.http.hc5.VespaAsyncHttpClientBuilder; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.concurrent.CompletableFutures; import com.yahoo.concurrent.DaemonThreadFactory; import com.yahoo.config.model.api.PortInfo; @@ -42,8 +42,6 @@ import static com.yahoo.yolean.Exceptions.uncheck; */ public class DefaultClusterReindexingStatusClient implements ClusterReindexingStatusClient { - private static final ObjectMapper mapper = new ObjectMapper(); - private final Executor executor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("cluster-controller-reindexing-client-")); private final CloseableHttpAsyncClient httpClient = createHttpClient(); @@ -101,7 +99,7 @@ public class DefaultClusterReindexingStatusClient implements ClusterReindexingSt } private static Map<String, ClusterReindexing> toClusterReindexing(byte[] requestBody) throws IOException { - JsonNode jsonNode = mapper.readTree(requestBody); + JsonNode jsonNode = Jackson.mapper().readTree(requestBody); Map<String, ClusterReindexing> clusters = new HashMap<>(); for (var clusterNames = jsonNode.get("clusters").fieldNames(); clusterNames.hasNext(); ) { String clusterName = clusterNames.next(); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationFile.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationFile.java index 959e12cfcad..adbe5f256c4 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationFile.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationFile.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.zookeeper; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.io.IOUtils; @@ -29,7 +30,7 @@ class ZKApplicationFile extends ApplicationFile { private static final Logger log = Logger.getLogger("ZKApplicationFile"); private final ZKApplication zkApp; - private final ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper = Jackson.mapper(); public ZKApplicationFile(Path path, ZKApplication app) { super(path); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java index 756ed52c316..d350f1c2ca0 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java @@ -1,10 +1,9 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.http.status; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.cloud.config.ConfigserverConfig; -import com.yahoo.config.model.NullConfigModelRegistry; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.vespa.config.server.http.SessionHandlerTest; @@ -23,8 +22,6 @@ import static org.junit.Assert.assertEquals; */ public class StatusHandlerTest { - private final ObjectMapper mapper = new ObjectMapper(); - @Test public void require_that_handler_works() throws IOException { ModelFactoryRegistry modelFactoryRegistry = new ModelFactoryRegistry(List.of(VespaModelFactory.createTestFactory())); @@ -32,7 +29,7 @@ public class StatusHandlerTest { StatusHandler handler = new StatusHandler(StatusHandler.testContext(), modelFactoryRegistry, configserverConfig); HttpResponse response = handler.handle(HttpRequest.createTestRequest("/status", GET)); - JsonNode jsonNode = mapper.readTree(SessionHandlerTest.getRenderedString(response)); + JsonNode jsonNode = Jackson.mapper().readTree(SessionHandlerTest.getRenderedString(response)); assertEquals(configserverConfig.rpcport(), jsonNode.get("configserverConfig").get("rpcport").asInt()); assertEquals(configserverConfig.applicationDirectory(), jsonNode.get("configserverConfig").get("applicationDirectory").asText()); diff --git a/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java b/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java index b553763c2b5..650555bf427 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java +++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/ErrorResponse.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.handler.metrics; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -16,15 +17,13 @@ public class ErrorResponse extends JsonResponse { private static final Logger log = Logger.getLogger(ErrorResponse.class.getName()); - private static final ObjectMapper objectMapper = new ObjectMapper(); - public ErrorResponse(int code, String message) { super(code, asErrorJson(message != null ? message : "<null>")); } static String asErrorJson(String message) { try { - return objectMapper.writeValueAsString(Map.of("error", message)); + return Jackson.mapper().writeValueAsString(Map.of("error", message)); } catch (JsonProcessingException e) { log.log(WARNING, "Could not encode error message to json:", e); return "Could not encode error message to json, check the log for details."; diff --git a/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java b/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java index d0c1197b91e..d94a4e64bd3 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java +++ b/container-core/src/main/java/com/yahoo/container/handler/metrics/HttpHandlerBase.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.handler.metrics; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.container.jdisc.HttpRequest; @@ -31,7 +31,6 @@ import static java.util.logging.Level.WARNING; */ public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler implements CapabilityRequiringRequestHandler { - private static final ObjectMapper jsonMapper = new ObjectMapper(); private final Duration defaultTimeout; protected HttpHandlerBase(Executor executor) { @@ -85,6 +84,7 @@ public abstract class HttpHandlerBase extends ThreadedHttpRequestHandler impleme base.append(":").append(port); } String uriBase = base.toString(); + var jsonMapper = Jackson.mapper(); ArrayNode linkList = jsonMapper.createArrayNode(); for (String api : resources) { ObjectNode resource = jsonMapper.createObjectNode(); diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java index 876c3657b9d..dff03f920b1 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/HostLifeGatherer.java @@ -1,13 +1,11 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.jdisc.state; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.component.Vtag; -import java.io.IOException; -import java.nio.file.Path; import java.time.Instant; /** @@ -15,9 +13,8 @@ import java.time.Instant; */ public class HostLifeGatherer { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - public static JsonNode getHostLifePacket() { + var jsonMapper = Jackson.mapper(); ObjectNode jsonObject = jsonMapper.createObjectNode(); jsonObject.put("timestamp", Instant.now().getEpochSecond()); jsonObject.put("application", "host_life"); diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java index b94fadec213..a682dcd3965 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/MetricsPacketsHandler.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.jdisc.state; +import ai.vespa.json.Jackson; import ai.vespa.metrics.set.InfrastructureMetricSet; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -51,7 +52,7 @@ import static com.yahoo.container.jdisc.state.StateHandler.getSnapshotProviderOr */ public class MetricsPacketsHandler extends AbstractRequestHandler { - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); static final String APPLICATION_KEY = "application"; static final String TIMESTAMP_KEY = "timestamp"; @@ -226,8 +227,7 @@ public class MetricsPacketsHandler extends AbstractRequestHandler { MetricValue value = metric.getValue(); if (value instanceof CountMetric) { metrics.put(name + ".count", ((CountMetric) value).getCount()); - } else if (value instanceof GaugeMetric) { - GaugeMetric gauge = (GaugeMetric) value; + } else if (value instanceof GaugeMetric gauge) { metrics.put(name + ".average", sanitizeDouble(gauge.getAverage())) .put(name + ".last", sanitizeDouble(gauge.getLast())) .put(name + ".max", sanitizeDouble(gauge.getMax())) @@ -252,8 +252,7 @@ public class MetricsPacketsHandler extends AbstractRequestHandler { MetricValue value = metric.getValue(); if (value instanceof CountMetric) { metrics.put(name + ".count", ((CountMetric) value).getCount()); - } else if (value instanceof GaugeMetric) { - GaugeMetric gauge = (GaugeMetric) value; + } else if (value instanceof GaugeMetric gauge) { metrics.put(name + ".average", sanitizeDouble(gauge.getAverage())); metrics.put(name + ".last", sanitizeDouble(gauge.getLast())); metrics.put(name + ".max", sanitizeDouble(gauge.getMax())); @@ -262,7 +261,7 @@ public class MetricsPacketsHandler extends AbstractRequestHandler { metrics.put(name + ".count", gauge.getCount()); if (gauge.getPercentiles().isPresent()) { for (Tuple2<String, Double> prefixAndValue : gauge.getPercentiles().get()) { - metrics.put(name + "." + prefixAndValue.first + "percentile", prefixAndValue.second.doubleValue()); + metrics.put(name + "." + prefixAndValue.first + "percentile", prefixAndValue.second); } } } else { diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java index 045b13e5d63..281acfdce0f 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.jdisc.state; +import ai.vespa.json.Jackson; import ai.vespa.metrics.ContainerMetrics; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -45,7 +46,7 @@ import static com.yahoo.container.jdisc.state.JsonUtil.sanitizeDouble; */ public class StateHandler extends AbstractRequestHandler implements CapabilityRequiringRequestHandler { - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); public static final String STATE_API_ROOT = "/state/v1"; private static final String METRICS_PATH = "metrics"; @@ -73,7 +74,7 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe static SnapshotProvider getSnapshotProviderOrThrow(ComponentRegistry<SnapshotProvider> preprocessors) { List<SnapshotProvider> allPreprocessors = preprocessors.allComponents(); - if (allPreprocessors.size() > 0) { + if (!allPreprocessors.isEmpty()) { return allPreprocessors.get(0); } else { throw new IllegalArgumentException("At least one snapshot provider is required."); diff --git a/container-core/src/main/java/com/yahoo/container/logging/JSONFormatter.java b/container-core/src/main/java/com/yahoo/container/logging/JSONFormatter.java index adf44e8b384..13964931779 100644 --- a/container-core/src/main/java/com/yahoo/container/logging/JSONFormatter.java +++ b/container-core/src/main/java/com/yahoo/container/logging/JSONFormatter.java @@ -1,10 +1,10 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.logging; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.yolean.trace.TraceNode; import java.io.IOException; @@ -32,10 +32,10 @@ public class JSONFormatter implements LogWriter<RequestLogEntry> { private final JsonFactory generatorFactory; - private static Logger logger = Logger.getLogger(JSONFormatter.class.getName()); + private static final Logger logger = Logger.getLogger(JSONFormatter.class.getName()); public JSONFormatter() { - generatorFactory = new JsonFactory(new ObjectMapper()); + generatorFactory = new JsonFactory(Jackson.mapper()); } @Override diff --git a/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java b/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java index 407fa7860f6..0ca26671446 100644 --- a/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java +++ b/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java @@ -1,10 +1,10 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.logging; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.container.logging.ConnectionLogEntry.SslHandshakeFailure.ExceptionEntry; import java.io.IOException; @@ -20,7 +20,7 @@ import java.util.Optional; */ class JsonConnectionLogWriter implements LogWriter<ConnectionLogEntry> { - private final JsonFactory jsonFactory = new JsonFactory(new ObjectMapper()); + private final JsonFactory jsonFactory = new JsonFactory(Jackson.mapper()); @Override public void write(ConnectionLogEntry record, OutputStream outputStream) throws IOException { diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/filter/util/FilterUtils.java b/container-core/src/main/java/com/yahoo/jdisc/http/filter/util/FilterUtils.java index 1698613a264..665254ad2ca 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/filter/util/FilterUtils.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/filter/util/FilterUtils.java @@ -1,23 +1,18 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.filter.util; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import com.yahoo.jdisc.Response; import com.yahoo.jdisc.handler.ContentChannel; import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.Cookie; -import com.yahoo.jdisc.http.filter.DiscFilterRequest; -import com.yahoo.jdisc.http.server.jetty.RequestUtils; import java.io.UncheckedIOException; -import java.net.URI; -import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.util.List; -import java.util.Optional; /** * Helper methods for auth0/okta request filters. @@ -26,17 +21,6 @@ import java.util.Optional; */ public class FilterUtils { - private static final ObjectMapper mapper = new ObjectMapper(); - - public static boolean isDifferentOrigin(DiscFilterRequest request) { - try { - String origin = request.getHeader("Origin"); - if (origin != null && !URI.create(origin).getHost().equals(request.getServerName())) - return true; - } catch (RuntimeException ignored) { } - return false; - } - public static void sendRedirectResponse(ResponseHandler handler, List<Cookie> cookies, String location) { Response response = createResponse(Response.Status.FOUND, cookies); response.headers().add("Location", location); @@ -47,6 +31,7 @@ public class FilterUtils { Response response = createResponse(code, cookies); ContentChannel contentChannel = handler.handleResponse(response); try { + var mapper = Jackson.mapper(); ObjectNode jsonNode = mapper.createObjectNode(); jsonNode.set("message", TextNode.valueOf(message)); byte[] jsonBytes = mapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(jsonNode); @@ -64,15 +49,4 @@ public class FilterUtils { return response; } - public static URI createUriFromRequest(DiscFilterRequest request, String path, Optional<String> hostOverride) { - try { - // Prefer local port as observed by client over local listen port - int port = Optional.ofNullable((Integer)request.getAttribute(RequestUtils.JDICS_REQUEST_PORT)) - .orElse(request.getUri().getPort()); - String host = hostOverride.orElse(request.getServerName()); - return new URI(request.getScheme(), null, host, port, path, null, null); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } } diff --git a/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java b/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java index 2fa55a3dd59..e1acf4708c1 100644 --- a/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java +++ b/container-core/src/test/java/com/yahoo/container/handler/metrics/MetricsV2HandlerTest.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.handler.metrics; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import com.yahoo.container.jdisc.RequestHandlerTestDriver; @@ -33,8 +33,6 @@ import static org.junit.jupiter.api.Assertions.*; */ public class MetricsV2HandlerTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static final String URI_BASE = "http://localhost"; private static final String V2_URI = URI_BASE + V2_PATH; @@ -80,7 +78,7 @@ public class MetricsV2HandlerTest { @Test void v2_response_contains_values_uri() throws Exception { String response = testDriver.sendRequest(V2_URI).readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = Jackson.mapper().readTree(response); assertTrue(root.has("resources")); ArrayNode resources = (ArrayNode) root.get("resources"); @@ -100,7 +98,7 @@ public class MetricsV2HandlerTest { @Test void invalid_path_yields_error_response() throws Exception { String response = testDriver.sendRequest(V2_URI + "/invalid").readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = Jackson.mapper().readTree(response); assertTrue(root.has("error")); assertTrue(root.get("error").textValue().startsWith("No content")); } @@ -127,7 +125,7 @@ public class MetricsV2HandlerTest { private JsonNode getResponseAsJson(String consumer) { String response = testDriver.sendRequest(VALUES_URI + consumerQuery(consumer)).readAll(); try { - return jsonMapper.readTree(response); + return Jackson.mapper().readTree(response); } catch (IOException e) { fail("Failed to create json object: " + e.getMessage()); throw new RuntimeException(e); diff --git a/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java b/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java index e206188dcd8..9e0f9685328 100644 --- a/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java +++ b/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusV1HandlerTest.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.handler.metrics; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import com.yahoo.container.jdisc.RequestHandlerTestDriver; @@ -28,8 +28,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class PrometheusV1HandlerTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static final String URI_BASE = "http://localhost"; private static final String V1_URI = URI_BASE + PrometheusV1Handler.V1_PATH; @@ -76,7 +74,7 @@ public class PrometheusV1HandlerTest { @Test void v1_response_contains_values_uri() throws Exception { String response = testDriver.sendRequest(V1_URI).readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = Jackson.mapper().readTree(response); assertTrue(root.has("resources")); ArrayNode resources = (ArrayNode) root.get("resources"); @@ -96,7 +94,7 @@ public class PrometheusV1HandlerTest { @Test void invalid_path_yields_error_response() throws Exception { String response = testDriver.sendRequest(V1_URI + "/invalid").readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = Jackson.mapper().readTree(response); assertTrue(root.has("error")); assertTrue(root.get("error").textValue().startsWith("No content")); } diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/MetricsPacketsHandlerTest.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/MetricsPacketsHandlerTest.java index 3eeb8cb7e80..e0251b81463 100644 --- a/container-core/src/test/java/com/yahoo/container/jdisc/state/MetricsPacketsHandlerTest.java +++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/MetricsPacketsHandlerTest.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.jdisc.state; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.container.jdisc.RequestHandlerTestDriver; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -238,7 +238,7 @@ public class MetricsPacketsHandlerTest extends StateHandlerTestBase { private List<JsonNode> toJsonPackets(String response) throws Exception { List<JsonNode> jsonPackets = new ArrayList<>(); String[] packets = response.split(PACKET_SEPARATOR); - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); for (String packet : packets) { jsonPackets.add(mapper.readTree(mapper.getFactory().createParser(packet))); } diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTestBase.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTestBase.java index 56a6d49f398..4b6ce82a940 100644 --- a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTestBase.java +++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTestBase.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.jdisc.state; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.container.core.ApplicationMetadataConfig; @@ -60,7 +60,7 @@ public class StateHandlerTestBase { } JsonNode requestAsJson(String requestUri) throws Exception { - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); return mapper.readTree(mapper.getFactory().createParser(requestAsString(requestUri))); } diff --git a/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java b/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java index e2cdfe7c728..f96ef1f2768 100644 --- a/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java +++ b/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.handler.observability; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -54,7 +55,7 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler handler); } - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); private final JsonNode applicationJson; private final JsonNode clientsJson; @@ -271,7 +272,7 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { return ret; } - private class IgnoredContent implements ContentChannel { + private static class IgnoredContent implements ContentChannel { @Override public void write(ByteBuffer buf, CompletionHandler handler) { handler.completed(); diff --git a/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java b/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java index c188f611b1d..c2e51590de4 100644 --- a/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java +++ b/container-disc/src/main/java/com/yahoo/container/usability/BindingsOverviewHandler.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.usability; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -32,7 +33,7 @@ import java.util.Map; */ public class BindingsOverviewHandler extends AbstractRequestHandler { - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); private final JdiscBindingsConfig bindingsConfig; @@ -54,21 +55,17 @@ public class BindingsOverviewHandler extends AbstractRequestHandler { statusToReturn = com.yahoo.jdisc.Response.Status.OK; } - FastContentWriter writer = new FastContentWriter(new ResponseDispatch() { + try (FastContentWriter writer = new FastContentWriter(new ResponseDispatch() { @Override protected com.yahoo.jdisc.Response newResponse() { com.yahoo.jdisc.Response response = new com.yahoo.jdisc.Response(statusToReturn); response.headers().add("Content-Type", List.of("application/json")); return response; } - }.connect(handler)); - - try { + }.connect(handler))) { writer.write(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(json)); } catch (JsonProcessingException e) { throw new RuntimeException(e); - } finally { - writer.close(); } return new IgnoredContent(); diff --git a/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java b/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java index 2fc032c0e44..d04ddc0c2ac 100644 --- a/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java +++ b/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.handler; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonFactoryBuilder; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParseException; @@ -42,11 +43,9 @@ class Json2SingleLevelMap { } private static ObjectMapper createMapper() { - var jsonFactory = new JsonFactoryBuilder() + return Jackson.createMapper(new JsonFactoryBuilder() .streamReadConstraints(StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build()) - .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) - .build(); - return new ObjectMapper(jsonFactory); + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true)); } Map<String, String> parse() { diff --git a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java index 2a44250904b..e2fc5baa4e3 100644 --- a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java +++ b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java @@ -1,13 +1,13 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonFactoryBuilder; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.StreamReadConstraints; import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Preconditions; import com.yahoo.container.logging.TraceRenderer; import com.yahoo.data.JsonProducer; @@ -177,11 +177,9 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> { } private static JsonFactory createGeneratorFactory() { - var factory = new JsonFactoryBuilder() - .streamReadConstraints(StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build()) - .build(); - factory.setCodec(new ObjectMapper(factory).disable(FLUSH_AFTER_WRITE_VALUE)); - return factory; + return Jackson.createMapper(new JsonFactoryBuilder() + .streamReadConstraints(StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build())) + .disable(FLUSH_AFTER_WRITE_VALUE).getFactory(); } @Override @@ -358,7 +356,7 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> { generator.writeNumberField(RELEVANCE, hit.getRelevance().getScore()); - if (hit.types().size() > 0) { + if (!hit.types().isEmpty()) { generator.writeArrayFieldStart(TYPES); for (String t : hit.types()) { generator.writeString(t); @@ -505,7 +503,7 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> { private boolean shouldRenderJsonCallback() { String jsonCallback = getJsonCallback(); - return jsonCallback != null && !"".equals(jsonCallback); + return jsonCallback != null && !jsonCallback.isEmpty(); } private String getJsonCallback() { diff --git a/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java index 9159728e24a..0ac527c6ce1 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.handler; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -44,7 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class JSONSearchHandlerTestCase { - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); private static final String testDir = "src/test/java/com/yahoo/search/handler/test/config"; private static final String myHostnameHeader = "my-hostname-header"; diff --git a/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java index a726a7d3c46..6c976011db1 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import com.yahoo.concurrent.Receiver; import com.yahoo.processing.response.Data; import com.yahoo.processing.response.DataList; @@ -88,8 +88,6 @@ public class AsyncGroupPopulationTestCase { } private static class InstrumentedGroup extends HitGroup { - private static final long serialVersionUID = 4585896586414935558L; - InstrumentedGroup(String id) { super(id, new Relevance(1), new ObservableIncoming<Hit>()); ((ObservableIncoming<Hit>) incoming()).assignOwner(this); @@ -135,9 +133,8 @@ public class AsyncGroupPopulationTestCase { Boolean b = f.get(); assertTrue(b); String rawGot = Utf8.toString(out.toByteArray()); - ObjectMapper m = new ObjectMapper(); - Map<?, ?> expected = m.readValue(rawExpected, Map.class); - Map<?, ?> got = m.readValue(rawGot, Map.class); + Map<?, ?> expected = Jackson.mapper().readValue(rawExpected, Map.class); + Map<?, ?> got = Jackson.mapper().readValue(rawGot, Map.class); assertEquals(expected, got); } diff --git a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java index 63fbc6568c0..73cd958ee33 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.Chain; @@ -90,8 +90,6 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class JsonRendererTestCase { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static ThreadPoolExecutor executor; private static JsonRenderer blueprint; private JsonRenderer renderer; @@ -571,7 +569,7 @@ public class JsonRendererTestCase { execution.search(q); new Execution(new Chain<>(), execution.context()); String summary = render(execution, r); - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<String, Object> exp = m.readValue(expected, Map.class); Map<String, Object> gen = m.readValue(summary, Map.class); @@ -1187,7 +1185,7 @@ public class JsonRendererTestCase { + "}"; Result r = newEmptyResult(); Hit h = new Hit("json objects"); - ObjectNode j = jsonMapper.createObjectNode(); + ObjectNode j = Jackson.mapper().createObjectNode(); JSONString s = new JSONString("{\"a\": \"b\"}"); Slime slime = new Slime(); Cursor c = slime.setObject(); @@ -1613,7 +1611,7 @@ public class JsonRendererTestCase { assertEquals("", validateJSON(expected)); assertEquals("", validateJSON(generated)); - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<String, Object> exp = m.readValue(expected, Map.class); Map<String, Object> gen = m.readValue(generated, Map.class); assertEquals(exp, gen); @@ -1621,7 +1619,7 @@ public class JsonRendererTestCase { private String validateJSON(String presumablyValidJson) { try { - jsonMapper.readTree(presumablyValidJson); + Jackson.mapper().readTree(presumablyValidJson); return ""; } catch (IOException e) { return e.getMessage(); diff --git a/container-search/src/test/java/com/yahoo/select/SelectTestCase.java b/container-search/src/test/java/com/yahoo/select/SelectTestCase.java index 655c47b4e6e..35609d1e209 100644 --- a/container-search/src/test/java/com/yahoo/select/SelectTestCase.java +++ b/container-search/src/test/java/com/yahoo/select/SelectTestCase.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.select; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -48,7 +49,7 @@ import static org.junit.jupiter.api.Assertions.*; */ public class SelectTestCase { - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); private final SelectParser parser = new SelectParser(new ParserEnvironment()); diff --git a/document/src/test/java/com/yahoo/document/DocumentTestCase.java b/document/src/test/java/com/yahoo/document/DocumentTestCase.java index 679c9284a20..09feed57d92 100644 --- a/document/src/test/java/com/yahoo/document/DocumentTestCase.java +++ b/document/src/test/java/com/yahoo/document/DocumentTestCase.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.document; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.document.datatypes.Array; import com.yahoo.document.datatypes.BoolFieldValue; import com.yahoo.document.datatypes.ByteFieldValue; @@ -29,10 +29,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.Set; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -960,7 +958,7 @@ public class DocumentTestCase extends DocumentTestCaseBase { setUpSertestDocType(); Document doc = getSertestDocument(); String json = doc.toJson(); - Map<String, Object> parsed = new ObjectMapper().readValue(json, new TypeReference<>() { + Map<String, Object> parsed = Jackson.mapper().readValue(json, new TypeReference<>() { }); assertEquals(parsed.get("id"), "id:ns:sertest::foobar"); assertTrue(parsed.get("fields") instanceof Map); diff --git a/document/src/test/java/com/yahoo/document/json/JsonWriterTestCase.java b/document/src/test/java/com/yahoo/document/json/JsonWriterTestCase.java index 0e8f3bbaf47..c713048f2ef 100644 --- a/document/src/test/java/com/yahoo/document/json/JsonWriterTestCase.java +++ b/document/src/test/java/com/yahoo/document/json/JsonWriterTestCase.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.document.json; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.io.JsonStringEncoder; @@ -241,7 +242,7 @@ public class JsonWriterTestCase { String docId = "id:unittest:testmap::whee"; Document doc = readDocumentFromJson(docId, fields); - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<?, ?> generated = m.readValue(JsonWriter.toByteArray(doc), Map.class); assertEquals(docId, generated.get("id")); // and from here on down there will be lots of unchecked casting and @@ -262,7 +263,7 @@ public class JsonWriterTestCase { // we have to do everything by hand to check, as maps are unordered, but // are serialized as an ordered structure - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<?, ?> generated = m.readValue(JsonWriter.toByteArray(doc), Map.class); assertEquals(docId, generated.get("id")); // and from here on down there will be lots of unchecked casting and @@ -311,7 +312,7 @@ public class JsonWriterTestCase { String fields = "{ \"actualMapStringToArrayOfInt\": { \"bamse\": [1, 2, 3] }}"; Document doc = readDocumentFromJson(docId, fields); - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<?, ?> generated = m.readValue(JsonWriter.toByteArray(doc), Map.class); assertEquals(docId, generated.get("id")); // and from here on down there will be lots of unchecked casting and @@ -331,7 +332,7 @@ public class JsonWriterTestCase { // we have to do everything by hand to check, as maps are unordered, but // are serialized as an ordered structure - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<?, ?> generated = m.readValue(JsonWriter.toByteArray(doc), Map.class); assertEquals(docId, generated.get("id")); // and from here on down there will be lots of unchecked casting and @@ -354,7 +355,7 @@ public class JsonWriterTestCase { } private void assertEqualJson(byte[] expected, byte[] generated) throws IOException { - ObjectMapper m = new ObjectMapper(); + var m = Jackson.mapper(); Map<?, ?> exp = m.readValue(expected, Map.class); Map<?, ?> gen = m.readValue(generated, Map.class); if (! exp.equals(gen)) { diff --git a/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java index 3441c3707fd..f2bc90a487e 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -86,7 +87,7 @@ public class JsonNodeRawFlag implements RawFlag { // ObjectMapper is a heavy-weight object so we construct it only when we need it return mapper.updateAndGet((objectMapper) -> { if (objectMapper != null) return objectMapper; - return new ObjectMapper(); + return Jackson.mapper(); }); } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagData.java b/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagData.java index 5a2a4e56559..cf2cb6795ee 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagData.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagData.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags.json.wire; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -24,7 +25,7 @@ public class WireFlagData { @JsonProperty("rules") public List<WireRule> rules; @JsonProperty("attributes") public Map<String, String> defaultFetchVector; - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); public byte[] serializeToBytes() { return uncheck(() -> mapper.writeValueAsBytes(this)); diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagDataList.java b/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagDataList.java index e7c3ce1a6f6..1e18b36a531 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagDataList.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/wire/WireFlagDataList.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags.json.wire; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -21,7 +22,7 @@ public class WireFlagDataList { @JsonProperty("flags") public List<WireFlagData> flags = new ArrayList<>(); - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); public void serializeToOutputStream(OutputStream outputStream) { uncheck(() -> mapper.writeValue(outputStream, this)); diff --git a/flags/src/test/java/com/yahoo/vespa/flags/custom/ClusterCapacityTest.java b/flags/src/test/java/com/yahoo/vespa/flags/custom/ClusterCapacityTest.java index 1d2e550aa7a..e078506ce21 100644 --- a/flags/src/test/java/com/yahoo/vespa/flags/custom/ClusterCapacityTest.java +++ b/flags/src/test/java/com/yahoo/vespa/flags/custom/ClusterCapacityTest.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags.custom; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -13,7 +13,7 @@ public class ClusterCapacityTest { @Test void serialization() throws IOException { ClusterCapacity clusterCapacity = new ClusterCapacity(7, 1.2, 3.4, 5.6, null, "fast", "local", "x86_64", null); - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); String json = mapper.writeValueAsString(clusterCapacity); assertEquals(""" {"count":7,"vcpu":1.2,"memoryGb":3.4,"diskGb":5.6,"diskSpeed":"fast","storageType":"local","architecture":"x86_64"}""", @@ -33,7 +33,7 @@ public class ClusterCapacityTest { @Test void serialization2() throws IOException { ClusterCapacity clusterCapacity = new ClusterCapacity(7, 1.2, 3.4, 5.6, 2.3, "any", "remote", "arm64", null); - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); String json = mapper.writeValueAsString(clusterCapacity); assertEquals(""" {"count":7,"vcpu":1.2,"memoryGb":3.4,"diskGb":5.6,"bandwidthGbps":2.3,"diskSpeed":"any","storageType":"remote","architecture":"arm64"}""", @@ -53,7 +53,7 @@ public class ClusterCapacityTest { @Test void serialization3() throws IOException { ClusterCapacity clusterCapacity = new ClusterCapacity(7, 1.2, 3.4, 5.6, 2.3, "any", "remote", "arm64", "admin"); - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); String json = mapper.writeValueAsString(clusterCapacity); assertEquals(""" {"count":7,"vcpu":1.2,"memoryGb":3.4,"diskGb":5.6,"bandwidthGbps":2.3,"diskSpeed":"any","storageType":"remote","architecture":"arm64","clusterType":"admin"}""", @@ -74,7 +74,7 @@ public class ClusterCapacityTest { @Test void serializationWithNoNodeResources() throws IOException { ClusterCapacity clusterCapacity = new ClusterCapacity(7, null, null, null, null, null, null, null, null); - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); String json = mapper.writeValueAsString(clusterCapacity); assertEquals("{\"count\":7,\"diskSpeed\":\"fast\",\"storageType\":\"any\",\"architecture\":\"x86_64\"}", json); diff --git a/flags/src/test/java/com/yahoo/vespa/flags/custom/SharedHostTest.java b/flags/src/test/java/com/yahoo/vespa/flags/custom/SharedHostTest.java index 45145923ab9..66edad3fe36 100644 --- a/flags/src/test/java/com/yahoo/vespa/flags/custom/SharedHostTest.java +++ b/flags/src/test/java/com/yahoo/vespa/flags/custom/SharedHostTest.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags.custom; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -21,7 +21,7 @@ public class SharedHostTest { } private void verifySerialization(SharedHost sharedHost) throws IOException { - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); String json = mapper.writeValueAsString(sharedHost); SharedHost deserialized = mapper.readValue(json, SharedHost.class); assertEquals(sharedHost, deserialized); diff --git a/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java b/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java index 6f4a4ff4e63..6e2b4b80d4b 100644 --- a/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java +++ b/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags.json; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.node.JsonNodeType; import com.yahoo.vespa.flags.json.wire.WireCondition; import com.yahoo.vespa.flags.json.wire.WireFlagData; @@ -98,8 +98,8 @@ public class SerializationTest { assertThat(wireData.defaultFetchVector.get("node-type"), equalTo("nt1")); // Verify serialization of RawFlag == serialization by ObjectMapper - ObjectMapper mapper = new ObjectMapper(); - String serializedWithObjectMapper = mapper.writeValueAsString(mapper.readTree(json)); + var mapper = Jackson.mapper(); + String serializedWithObjectMapper = Jackson.mapper().writeValueAsString(mapper.readTree(json)); assertThat(wireData.serializeToJson(), equalTo(serializedWithObjectMapper)); // Unfortunately the order of attributes members are different... diff --git a/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBase.java b/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBase.java index 510a47e6dd9..f1bf748ae8b 100644 --- a/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBase.java +++ b/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBase.java @@ -1,9 +1,9 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.filter.security.base; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.component.AbstractComponent; import com.yahoo.jdisc.Response; @@ -27,7 +27,6 @@ import java.util.logging.Logger; public abstract class JsonSecurityRequestFilterBase extends AbstractComponent implements SecurityRequestFilter { private static final Logger log = Logger.getLogger(JsonSecurityRequestFilterBase.class.getName()); - private static final ObjectMapper mapper = new ObjectMapper(); @Override public final void filter(DiscFilterRequest request, ResponseHandler handler) { @@ -37,10 +36,9 @@ public abstract class JsonSecurityRequestFilterBase extends AbstractComponent im protected abstract Optional<ErrorResponse> filter(DiscFilterRequest request); - protected ObjectMapper jsonMapper() { return mapper; } - private void writeResponse(DiscFilterRequest request, ErrorResponse error, ResponseHandler responseHandler) { JsonNode json; + var mapper = Jackson.mapper(); if (error.customJson != null) { json = error.customJson; } else { diff --git a/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBaseTest.java b/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBaseTest.java index c6006c1d483..22a77692da3 100644 --- a/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBaseTest.java +++ b/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/base/JsonSecurityRequestFilterBaseTest.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.filter.security.base; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.container.jdisc.RequestHandlerTestDriver; import com.yahoo.jdisc.Response; import com.yahoo.jdisc.http.filter.DiscFilterRequest; @@ -20,7 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; */ public class JsonSecurityRequestFilterBaseTest { - private final ObjectMapper mapper = new ObjectMapper(); @Test void filter_renders_errors_as_json() throws IOException { @@ -36,7 +35,7 @@ public class JsonSecurityRequestFilterBaseTest { assertNotNull(response); assertEquals(statusCode, response.getStatus()); - JsonNode jsonNode = mapper.readTree(responseHandler.readAll()); + JsonNode jsonNode = Jackson.mapper().readTree(responseHandler.readAll()); assertEquals(message, jsonNode.get("message").asText()); assertEquals(statusCode, jsonNode.get("code").asInt()); } diff --git a/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java b/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java index f3d0f59dd4c..3924bf8322b 100644 --- a/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java +++ b/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.filter.security.rule; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.container.jdisc.RequestHandlerTestDriver.MockResponseHandler; import com.yahoo.jdisc.Metric; @@ -31,8 +31,6 @@ import static org.mockito.Mockito.verify; */ class RuleBasedRequestFilterTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - @Test void matches_rule_that_allows_all_methods_and_paths() { RuleBasedFilterConfig config = new RuleBasedFilterConfig.Builder() @@ -230,9 +228,9 @@ class RuleBasedRequestFilterTest { Response response = handler.getResponse(); assertNotNull(response); assertEquals(expectedCode, response.getStatus()); - ObjectNode expectedJson = jsonMapper.createObjectNode(); + ObjectNode expectedJson = Jackson.mapper().createObjectNode(); expectedJson.put("message", expectedMessage).put("code", expectedCode); - JsonNode actualJson = jsonMapper.readTree(handler.readAll().getBytes()); + JsonNode actualJson = Jackson.mapper().readTree(handler.readAll().getBytes()); assertEquals(expectedJson, actualJson); } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModel.java index a9ebd41fd36..59d1f9e5c83 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModel.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModel.java @@ -4,7 +4,6 @@ package ai.vespa.metricsproxy.metric.model.json; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; @@ -22,9 +21,8 @@ public class GenericApplicationModel { public List<GenericJsonModel> nodes; public String serialize() { - ObjectMapper mapper = JacksonUtil.createObjectMapper(); try { - return mapper.writeValueAsString(this); + return JacksonUtil.objectMapper().writeValueAsString(this); } catch (IOException e) { throw new JsonRenderingException("Could not render application nodes. Check the log for details.", e); } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java index ffb9813d257..c4ba0f39a18 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; @@ -33,9 +32,8 @@ public class GenericJsonModel { public List<GenericService> services; public String serialize() { - ObjectMapper mapper = JacksonUtil.createObjectMapper(); try { - return mapper.writeValueAsString(this); + return JacksonUtil.objectMapper().writeValueAsString(this); } catch (IOException e) { throw new JsonRenderingException("Could not render metrics. Check the log for details.", e); } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java index 02f45010873..c32e90ecc9f 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java @@ -5,7 +5,6 @@ import ai.vespa.metricsproxy.http.application.Node; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import ai.vespa.metricsproxy.metric.model.ServiceId; import ai.vespa.metricsproxy.metric.model.StatusCode; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.ArrayList; @@ -18,7 +17,7 @@ import java.util.stream.Collectors; import static ai.vespa.metricsproxy.metric.ExternalMetrics.VESPA_NODE_SERVICE_ID; import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId; import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId; -import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.createObjectMapper; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.logging.Level.WARNING; @@ -87,8 +86,7 @@ public class GenericJsonUtil { public static List<MetricsPacket.Builder> toMetricsPackets(String jsonString) { try { - ObjectMapper mapper = createObjectMapper(); - GenericJsonModel jsonModel = mapper.readValue(jsonString, GenericJsonModel.class); + GenericJsonModel jsonModel = objectMapper().readValue(jsonString, GenericJsonModel.class); return toMetricsPackets(jsonModel); } catch (IOException e) { log.log(WARNING, "Could not create metrics packet from string:\n" + jsonString, e); diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java index 72835a44e7f..8eb7df20218 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/JacksonUtil.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.metricsproxy.metric.model.json; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.JsonSerializer; @@ -22,6 +23,7 @@ public class JacksonUtil { private static final ThreadLocal<DecimalFormat> withinLongRangeFormat = ThreadLocal.withInitial(JacksonUtil::createWithinLongRangeFormat); private static final ThreadLocal<DecimalFormat> outsideLongRangeFormat = ThreadLocal.withInitial(JacksonUtil::createOutsideLongRangeFormat); + private static final ObjectMapper objectMapper = createObjectMapper(); private static DecimalFormat createWithinLongRangeFormat() { DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.ENGLISH)); df.setMaximumFractionDigits(13); @@ -35,14 +37,17 @@ public class JacksonUtil { /** * Returns an object mapper with a custom floating point serializer to avoid scientific notation */ - public static ObjectMapper createObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); + private static ObjectMapper createObjectMapper() { + ObjectMapper mapper = Jackson.createMapper(); SimpleModule module = new SimpleModule("DoubleSerializer", new Version(1, 0, 0, "", null, null)); module.addSerializer(Double.class, new DoubleSerializer()); mapper.registerModule(module); return mapper; } + public static ObjectMapper objectMapper() { + return objectMapper; + } /** * Returns an object mapper with a custom floating point serializer to avoid scientific notation */ @@ -63,8 +68,8 @@ public class JacksonUtil { } public static class DoubleSerializer extends JsonSerializer<Double> { - private DecimalFormat withinLongRangeFormat = createWithinLongRangeFormat(); - private DecimalFormat outsideLongRangeFormat = createOutsideLongRangeFormat(); + private final DecimalFormat withinLongRangeFormat = createWithinLongRangeFormat(); + private final DecimalFormat outsideLongRangeFormat = createOutsideLongRangeFormat(); @Override public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeNumber(format(value, withinLongRangeFormat, outsideLongRangeFormat)); diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java index 6a88350d5ed..82049da5115 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtil.java @@ -9,7 +9,6 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.StreamWriteFeature; import com.fasterxml.jackson.core.util.MinimalPrettyPrinter; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -21,6 +20,7 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static java.util.Collections.emptyList; import static java.util.logging.Level.WARNING; @@ -56,9 +56,8 @@ public class YamasJsonUtil { */ public static List<MetricsPacket.Builder> toMetricsPackets(String jsonString) { List<MetricsPacket.Builder> packets = new ArrayList<>(); - try { - JsonParser jp = new JsonFactory().createParser(jsonString); - jp.setCodec(new ObjectMapper()); + var mapper = objectMapper(); + try (JsonParser jp = mapper.createParser(jsonString)) { while (jp.nextToken() != null) { YamasJsonModel jsonModel = jp.readValueAs(YamasJsonModel.class); packets.add(toMetricsPacketBuilder(jsonModel)); diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/MetricsParser.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/MetricsParser.java index 43011a24f8c..80ad2256b1c 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/MetricsParser.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/MetricsParser.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.metricsproxy.service; +import ai.vespa.json.Jackson; import ai.vespa.metricsproxy.metric.Metric; import ai.vespa.metricsproxy.metric.model.DimensionId; import ai.vespa.metricsproxy.metric.model.MetricId; @@ -31,14 +32,18 @@ public class MetricsParser { void accept(Metric metric); } - private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = Jackson.mapper(); public static void parse(String data, Collector consumer) throws IOException { - parse(jsonMapper.createParser(data), consumer); + try (JsonParser parser = jsonMapper.createParser(data)) { + parse(parser, consumer); + } } static void parse(InputStream data, Collector consumer) throws IOException { - parse(jsonMapper.createParser(data), consumer); + try (JsonParser parser = jsonMapper.createParser(data)) { + parse(parser, consumer); + } } // Top level 'metrics' object, with e.g. 'time', 'status' and 'metrics'. @@ -123,21 +128,19 @@ public class MetricsParser { for (parser.nextToken(); parser.getCurrentToken() != JsonToken.END_OBJECT; parser.nextToken()) { String fieldName = parser.getCurrentName(); JsonToken token = parser.nextToken(); - if (fieldName.equals("name")) { - name = parser.getText(); - } else if (fieldName.equals("description")) { - description = parser.getText(); - } else if (fieldName.equals("dimensions")) { - dim = parseDimensions(parser, uniqueDimensions); - } else if (fieldName.equals("values")) { - values = parseValues(parser); - } else { - if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) { - parser.skipChildren(); + switch (fieldName) { + case "name" -> name = parser.getText(); + case "description" -> description = parser.getText(); + case "dimensions" -> dim = parseDimensions(parser, uniqueDimensions); + case "values" -> values = parseValues(parser); + default -> { + if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) { + parser.skipChildren(); + } } } } - if (name.equals("")) { + if (name.isEmpty()) { throw new IOException("missing name for entry in 'values' array"); } for (Map.Entry<String, Number> value : values) { diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java index b3ade5074b8..2f4a807a4d0 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/RemoteHealthMetricFetcher.java @@ -1,9 +1,9 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.metricsproxy.service; +import ai.vespa.json.Jackson; import ai.vespa.metricsproxy.metric.HealthMetric; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.io.entity.EntityUtils; @@ -20,7 +20,6 @@ import java.util.logging.Logger; * @author Jo Kristian Bergum */ public class RemoteHealthMetricFetcher extends HttpMetricFetcher { - private static final ObjectMapper jsonMapper = new ObjectMapper(); private final static Logger log = Logger.getLogger(RemoteHealthMetricFetcher.class.getPackage().getName()); private final static String HEALTH_PATH = STATE_PATH + "health"; @@ -54,7 +53,7 @@ public class RemoteHealthMetricFetcher extends HttpMetricFetcher { private HealthMetric parse(InputStream data) { try { - JsonNode o = jsonMapper.readTree(data); + JsonNode o = Jackson.mapper().readTree(data); JsonNode status = o.get("status"); String code = status.get("code").asText(); String message = ""; diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java index c57fe836269..3a902767f29 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java @@ -10,7 +10,6 @@ import ai.vespa.metricsproxy.metric.model.json.GenericJsonModel; import ai.vespa.metricsproxy.metric.model.json.GenericMetrics; import ai.vespa.metricsproxy.metric.model.json.GenericService; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.yahoo.container.jdisc.RequestHandlerTestDriver; @@ -30,7 +29,7 @@ import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId; import static ai.vespa.metricsproxy.http.application.ApplicationMetricsHandler.METRICS_V1_PATH; import static ai.vespa.metricsproxy.http.application.ApplicationMetricsHandler.METRICS_VALUES_PATH; import static ai.vespa.metricsproxy.http.application.ApplicationMetricsHandler.PROMETHEUS_VALUES_PATH; -import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.createObjectMapper; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; import static com.github.tomakehurst.wiremock.client.WireMock.get; @@ -47,8 +46,6 @@ import static org.junit.Assert.fail; */ public class ApplicationMetricsHandlerTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static final String HOST = "localhost"; private static final String URI_BASE = "http://" + HOST; private static final String METRICS_V1_URI = URI_BASE + METRICS_V1_PATH; @@ -105,7 +102,7 @@ public class ApplicationMetricsHandlerTest { @Test public void v1_response_contains_values_uri() throws Exception { String response = testDriver.sendRequest(METRICS_V1_URI).readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = objectMapper().readTree(response); assertTrue(root.has("resources")); ArrayNode resources = (ArrayNode) root.get("resources"); @@ -121,7 +118,7 @@ public class ApplicationMetricsHandlerTest { @Test public void visually_inspect_values_response_metrics() throws Exception { String response = testDriver.sendRequest(METRICS_VALUES_URI).readAll(); - ObjectMapper mapper = createObjectMapper(); + var mapper = objectMapper(); var jsonModel = mapper.readValue(response, GenericApplicationModel.class); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonModel)); } @@ -202,14 +199,14 @@ public class ApplicationMetricsHandlerTest { @Test public void invalid_path_yields_error_response() throws Exception { String response = testDriver.sendRequest(METRICS_V1_URI + "/invalid").readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = objectMapper().readTree(response); assertTrue(root.has("error")); } private GenericApplicationModel getResponseAsJsonModel(String consumer) { String response = testDriver.sendRequest(METRICS_VALUES_URI + "?consumer=" + consumer).readAll(); try { - return createObjectMapper().readValue(response, GenericApplicationModel.class); + return objectMapper().readValue(response, GenericApplicationModel.class); } catch (IOException e) { fail("Failed to create json model: " + e.getMessage()); throw new RuntimeException(e); diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java index 692c4194bda..8e80dbddf9e 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/metrics/MetricsHandlerTestBase.java @@ -7,7 +7,6 @@ import ai.vespa.metricsproxy.metric.model.json.GenericMetrics; import ai.vespa.metricsproxy.metric.model.json.GenericService; import ai.vespa.metricsproxy.service.DownService; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import org.junit.Ignore; import org.junit.Test; @@ -19,7 +18,7 @@ import static ai.vespa.metricsproxy.metric.dimensions.PublicDimensions.INTERNAL_ import static ai.vespa.metricsproxy.metric.dimensions.PublicDimensions.REASON; import static ai.vespa.metricsproxy.metric.dimensions.PublicDimensions.SERVICE_ID; import static ai.vespa.metricsproxy.metric.model.StatusCode.DOWN; -import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.createObjectMapper; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static ai.vespa.metricsproxy.service.DummyService.METRIC_1; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -33,8 +32,6 @@ import static org.junit.Assert.fail; */ public abstract class MetricsHandlerTestBase<MODEL> extends HttpHandlerTestBase { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - static String rootUri; static String valuesUri; @@ -45,7 +42,7 @@ public abstract class MetricsHandlerTestBase<MODEL> extends HttpHandlerTestBase private MODEL getResponseAsJsonModel(String consumer) { String response = testDriver.sendRequest(valuesUri + "?consumer=" + consumer).readAll(); try { - return createObjectMapper().readValue(response, modelClass); + return objectMapper().readValue(response, modelClass); } catch (IOException e) { fail("Failed to create json model: " + e.getMessage()); throw new RuntimeException(e); @@ -59,14 +56,14 @@ public abstract class MetricsHandlerTestBase<MODEL> extends HttpHandlerTestBase @Test public void invalid_path_yields_error_response() throws Exception { String response = testDriver.sendRequest(rootUri + "/invalid").readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = objectMapper().readTree(response); assertTrue(root.has("error")); } @Test public void root_response_contains_values_uri() throws Exception { String response = testDriver.sendRequest(rootUri).readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = objectMapper().readTree(response); assertTrue(root.has("resources")); ArrayNode resources = (ArrayNode) root.get("resources"); @@ -80,7 +77,7 @@ public abstract class MetricsHandlerTestBase<MODEL> extends HttpHandlerTestBase @Test public void visually_inspect_values_response() throws Exception { String response = testDriver.sendRequest(valuesUri).readAll(); - ObjectMapper mapper = createObjectMapper(); + var mapper = objectMapper(); var jsonModel = mapper.readValue(response, modelClass); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonModel)); } diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java index f8e07c3f2ec..b36f521e4ac 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/prometheus/PrometheusHandlerTest.java @@ -4,7 +4,6 @@ package ai.vespa.metricsproxy.http.prometheus; import ai.vespa.metricsproxy.http.HttpHandlerTestBase; import ai.vespa.metricsproxy.service.DummyService; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.yahoo.container.jdisc.RequestHandlerTestDriver; import org.junit.BeforeClass; @@ -14,17 +13,15 @@ import org.junit.Test; import java.util.concurrent.Executors; import static ai.vespa.metricsproxy.metric.dimensions.PublicDimensions.REASON; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author gjoranv */ -@SuppressWarnings("UnstableApiUsage") public class PrometheusHandlerTest extends HttpHandlerTestBase { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static final String V1_URI = URI_BASE + PrometheusHandler.V1_PATH; private static final String VALUES_URI = URI_BASE + PrometheusHandler.VALUES_PATH; @@ -45,7 +42,7 @@ public class PrometheusHandlerTest extends HttpHandlerTestBase { @Test public void v1_response_contains_values_uri() throws Exception { String response = testDriver.sendRequest(V1_URI).readAll(); - JsonNode root = jsonMapper.readTree(response); + JsonNode root = objectMapper().readTree(response); assertTrue(root.has("resources")); ArrayNode resources = (ArrayNode) root.get("resources"); diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java index f773a1095cd..54736851b3f 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java @@ -4,7 +4,6 @@ package ai.vespa.metricsproxy.metric.model.json; import ai.vespa.metricsproxy.http.application.Node; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import ai.vespa.metricsproxy.metric.model.StatusCode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import java.io.IOException; @@ -16,7 +15,7 @@ import static ai.vespa.metricsproxy.metric.ExternalMetrics.VESPA_NODE_SERVICE_ID import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId; import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId; import static ai.vespa.metricsproxy.metric.model.ServiceId.toServiceId; -import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.createObjectMapper; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -90,7 +89,7 @@ public class GenericApplicationModelTest { assertEquals("service-dim-value", serviceMetrics.dimensions.get("service-dim")); // Visual inspection - System.out.println(createObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(nodeModel)); + System.out.println(objectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(nodeModel)); } private MetricsPacket createMetricsPacket(String service, Number metricsValue, boolean isNode) { @@ -112,8 +111,7 @@ public class GenericApplicationModelTest { } private static GenericApplicationModel genericJsonModelFromTestFile() throws IOException { - ObjectMapper mapper = createObjectMapper(); - return mapper.readValue(getFileContents(TEST_FILE), GenericApplicationModel.class); + return objectMapper().readValue(getFileContents(TEST_FILE), GenericApplicationModel.class); } } diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModelTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModelTest.java index cdcd049ecfc..9eb1ed8cd5a 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModelTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModelTest.java @@ -3,7 +3,6 @@ package ai.vespa.metricsproxy.metric.model.json; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import ai.vespa.metricsproxy.metric.model.StatusCode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import java.io.IOException; @@ -14,7 +13,7 @@ import static ai.vespa.metricsproxy.metric.ExternalMetrics.VESPA_NODE_SERVICE_ID import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId; import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId; import static ai.vespa.metricsproxy.metric.model.ServiceId.toServiceId; -import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.createObjectMapper; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -113,7 +112,7 @@ public class GenericJsonModelTest { assertEquals("service-dim-value", serviceMetrics.dimensions.get("service-dim")); // Visual inspection - System.out.println(createObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(jsonModel)); + System.out.println(objectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(jsonModel)); } @Test @@ -138,8 +137,7 @@ public class GenericJsonModelTest { } private GenericJsonModel genericJsonModelFromTestFile(String filename) throws IOException { - ObjectMapper mapper = createObjectMapper(); - return mapper.readValue(getFileContents(filename), GenericJsonModel.class); + return objectMapper().readValue(getFileContents(filename), GenericJsonModel.class); } @Test diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java index ae0f79746e5..8f3a99c1c68 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonModelTest.java @@ -16,6 +16,7 @@ import java.util.List; import static ai.vespa.metricsproxy.metric.model.ConsumerId.toConsumerId; import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId; import static ai.vespa.metricsproxy.metric.model.ServiceId.toServiceId; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -78,8 +79,7 @@ public class YamasJsonModelTest { // Read file that was taken from production (real -life example that is) String filename = getClass().getClassLoader().getResource("yamas-array-no-routing.json").getFile(); BufferedReader reader = Files.newBufferedReader(Paths.get(filename)); - ObjectMapper mapper = new ObjectMapper(); - YamasJsonModel jsonModel = mapper.readValue(reader, YamasJsonModel.class); + YamasJsonModel jsonModel = objectMapper().readValue(reader, YamasJsonModel.class); // Do some sanity checking assertNull(jsonModel.routing); @@ -104,8 +104,7 @@ public class YamasJsonModelTest { private YamasJsonModel getYamasJsonModel(String testFile) throws IOException { String filename = getClass().getClassLoader().getResource(testFile).getFile(); BufferedReader reader = Files.newBufferedReader(Paths.get(filename)); - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(reader, YamasJsonModel.class); + return objectMapper().readValue(reader, YamasJsonModel.class); } } diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java index 7281c674745..aa85277b3b7 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/YamasJsonUtilTest.java @@ -3,7 +3,6 @@ package ai.vespa.metricsproxy.metric.model.json; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import org.junit.Test; @@ -14,6 +13,7 @@ import java.util.Set; import static ai.vespa.metricsproxy.core.VespaMetrics.vespaMetricsConsumerId; import static ai.vespa.metricsproxy.http.ValuesFetcher.defaultMetricsConsumerId; import static ai.vespa.metricsproxy.metric.model.ServiceId.toServiceId; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.YAMAS_ROUTING; import static ai.vespa.metricsproxy.metric.model.json.YamasJsonUtil.toMetricsPackets; import static org.junit.Assert.assertEquals; @@ -24,12 +24,11 @@ import static org.junit.Assert.assertTrue; * @author gjoranv */ public class YamasJsonUtilTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); private static JsonNode metrics(MetricsPacket packet, boolean addStatus) throws IOException { return metrics(List.of(packet), addStatus).get(0); } private static ArrayNode metrics(List<MetricsPacket> packets, boolean addStatus) throws IOException { - return (ArrayNode) jsonMapper.readTree(YamasJsonUtil.toJson(packets, addStatus)).get("metrics"); + return (ArrayNode) objectMapper().readTree(YamasJsonUtil.toJson(packets, addStatus)).get("metrics"); } @Test diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java index b67967b7e04..20164b91a55 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/node/NodeMetricGathererTest.java @@ -5,7 +5,6 @@ import ai.vespa.metricsproxy.metric.model.ConsumerId; import ai.vespa.metricsproxy.metric.model.MetricId; import ai.vespa.metricsproxy.metric.model.MetricsPacket; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; @@ -13,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static org.junit.Assert.assertEquals; /** @@ -20,8 +20,6 @@ import static org.junit.Assert.assertEquals; */ public class NodeMetricGathererTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - @Test public void testJSONObjectIsCorrectlyConvertedToMetricsPacket() { List<MetricsPacket.Builder> builders = new ArrayList<>(); @@ -31,17 +29,17 @@ public class NodeMetricGathererTest { assertEquals("host_life", packet.service.id); assertEquals(123, packet.timestamp); - assertEquals(12l, packet.metrics().get(MetricId.toMetricId("uptime"))); - assertEquals(1l, packet.metrics().get(MetricId.toMetricId("alive"))); + assertEquals(12L, packet.metrics().get(MetricId.toMetricId("uptime"))); + assertEquals(1L, packet.metrics().get(MetricId.toMetricId("alive"))); assertEquals(Set.of(ConsumerId.toConsumerId("Vespa")), packet.consumers()); } private JsonNode generateHostLifePacket() { - ObjectNode jsonObject = jsonMapper.createObjectNode(); + ObjectNode jsonObject = objectMapper().createObjectNode(); jsonObject.put("timestamp", 123); jsonObject.put("application", "host_life"); - ObjectNode metrics = jsonMapper.createObjectNode(); + ObjectNode metrics = objectMapper().createObjectNode(); metrics.put("uptime", 12); metrics.put("alive", 1); jsonObject.set("metrics", metrics); diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java index 0b333db3c71..e6c3ca20e00 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java @@ -6,7 +6,6 @@ import ai.vespa.metricsproxy.metric.Metrics; import ai.vespa.metricsproxy.metric.model.ConsumerId; import ai.vespa.metricsproxy.service.VespaService; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.yahoo.jrt.Request; import com.yahoo.jrt.Spec; @@ -26,6 +25,7 @@ import static ai.vespa.metricsproxy.TestUtil.getFileContents; import static ai.vespa.metricsproxy.core.VespaMetrics.vespaMetricsConsumerId; import static ai.vespa.metricsproxy.metric.model.DimensionId.toDimensionId; import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId; +import static ai.vespa.metricsproxy.metric.model.json.JacksonUtil.objectMapper; import static ai.vespa.metricsproxy.rpc.IntegrationTester.CUSTOM_CONSUMER_ID; import static ai.vespa.metricsproxy.rpc.IntegrationTester.MONITORING_SYSTEM; import static ai.vespa.metricsproxy.rpc.IntegrationTester.SERVICE_1_CONFIG_ID; @@ -42,8 +42,6 @@ import static org.junit.Assert.assertTrue; */ public class RpcMetricsTest { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static final String METRICS_RESPONSE = getFileContents("metrics-storage-simple.json").trim(); private static final String EXTRA_APP = "extra"; private static final Duration RPC_INVOKE_TIMEOUT = Duration.ofSeconds(60); @@ -148,7 +146,7 @@ public class RpcMetricsTest { private static void verifyMetricsFromRpcRequest(VespaService service, RpcClient client) throws IOException { String jsonResponse = getMetricsForYamas(service.getMonitoringName().id, client).trim(); - ArrayNode metrics = (ArrayNode) jsonMapper.readTree(jsonResponse).get("metrics"); + ArrayNode metrics = (ArrayNode) objectMapper().readTree(jsonResponse).get("metrics"); assertEquals("Expected 3 metric messages", 3, metrics.size()); for (int i = 0; i < metrics.size() - 1; i++) { // The last "metric message" contains only status code/message JsonNode jsonObject = metrics.get(i); @@ -184,7 +182,7 @@ public class RpcMetricsTest { private void verifyMetricsFromRpcRequestForAllServices(RpcClient client) throws IOException { // Verify that metrics for all services can be retrieved in one request. String allServicesResponse = getMetricsForYamas(ALL_SERVICES, client).trim(); - ArrayNode allServicesMetrics = (ArrayNode) jsonMapper.readTree(allServicesResponse).get("metrics"); + ArrayNode allServicesMetrics = (ArrayNode) objectMapper().readTree(allServicesResponse).get("metrics"); assertEquals(5, allServicesMetrics.size()); } @@ -221,13 +219,13 @@ public class RpcMetricsTest { } private JsonNode findExtraMetricsObject(String jsonResponse) throws IOException { - ArrayNode metrics = (ArrayNode) jsonMapper.readTree(jsonResponse).get("metrics"); + ArrayNode metrics = (ArrayNode) objectMapper().readTree(jsonResponse).get("metrics"); for (int i = 0; i < metrics.size(); i++) { JsonNode jsonObject = metrics.get(i); assertTrue(jsonObject.has("application")); if (jsonObject.get("application").textValue().equals(EXTRA_APP)) return jsonObject; } - return jsonMapper.createObjectNode(); + return objectMapper().createObjectNode(); } private static String getMetricsForYamas(String service, RpcClient client) { diff --git a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMImporter.java b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMImporter.java index bbd0e090762..7e23f8c01c8 100644 --- a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMImporter.java +++ b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMImporter.java @@ -1,12 +1,12 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.rankingexpression.importer.lightgbm; +import ai.vespa.json.Jackson; import ai.vespa.rankingexpression.importer.ImportedModel; import ai.vespa.rankingexpression.importer.ModelImporter; import ai.vespa.rankingexpression.importer.configmodelview.ImportedMlModel; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.searchlib.rankingexpression.RankingExpression; import com.yahoo.searchlib.rankingexpression.parser.ParseException; @@ -20,7 +20,6 @@ import java.io.IOException; */ public class LightGBMImporter extends ModelImporter { - private final ObjectMapper objectMapper = new ObjectMapper(); @Override public boolean canImport(String modelPath) { File modelFile = new File(modelPath); @@ -33,8 +32,7 @@ public class LightGBMImporter extends ModelImporter { * Currently, we just check if the json has an element called "tree_info" */ private boolean probe(File modelFile) { - try { - JsonParser parser = objectMapper.createParser(modelFile); + try (JsonParser parser = Jackson.mapper().createParser(modelFile)) { while (parser.nextToken() != null) { JsonToken token = parser.getCurrentToken(); if (token == JsonToken.FIELD_NAME) { diff --git a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMParser.java b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMParser.java index 9b63d7f47e2..5eb6e2fb474 100644 --- a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMParser.java +++ b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/lightgbm/LightGBMParser.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.rankingexpression.importer.lightgbm; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; @@ -27,8 +28,8 @@ class LightGBMParser { private final List<String> featureNames; private final Map<Integer, List<String>> categoryValues; // pr feature index - LightGBMParser(String filePath) throws JsonProcessingException, IOException { - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + LightGBMParser(String filePath) throws IOException { + ObjectMapper mapper = Jackson.createMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); JsonNode root = mapper.readTree(new File(filePath)); objective = root.get("objective").asText("regression"); diff --git a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/xgboost/XGBoostParser.java b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/xgboost/XGBoostParser.java index cfb7c5b76bd..ad38a13d153 100644 --- a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/xgboost/XGBoostParser.java +++ b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/xgboost/XGBoostParser.java @@ -6,9 +6,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; /** * @author grace-lam @@ -26,7 +26,7 @@ class XGBoostParser { */ XGBoostParser(String filePath) throws JsonProcessingException, IOException { this.xgboostTrees = new ArrayList<>(); - ObjectMapper mapper = new ObjectMapper(); + var mapper = Jackson.mapper(); JsonNode forestNode = mapper.readTree(new File(filePath)); for (JsonNode treeNode : forestNode) { this.xgboostTrees.add(mapper.treeToValue(treeNode, XGBoostTree.class)); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java index d71a8934f46..f397bacc46f 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java @@ -1,11 +1,11 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.maintenance; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.collections.Tuple2; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; @@ -301,9 +301,8 @@ public class CapacityCheckerTester { public void populateNodeRepositoryFromJsonFile(Path path) throws IOException { byte[] jsonData = Files.readAllBytes(path); - ObjectMapper om = new ObjectMapper(); - NodeRepositoryModel repositoryModel = om.readValue(jsonData, NodeRepositoryModel.class); + NodeRepositoryModel repositoryModel = Jackson.mapper().readValue(jsonData, NodeRepositoryModel.class); List<NodeModel> nodeModels = repositoryModel.nodes; diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/json/WireHostInfo.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/json/WireHostInfo.java index 4065b2f8bba..dea1c87c97b 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/json/WireHostInfo.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/json/WireHostInfo.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.status.json; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -22,7 +23,7 @@ import static com.yahoo.yolean.Exceptions.uncheck; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) public class WireHostInfo { - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = Jackson.mapper(); @JsonProperty("status") public String status; @JsonProperty("suspendedSince") public Long suspendedSinceInMillis; diff --git a/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/HitsVerificationBenchmark.java b/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/HitsVerificationBenchmark.java index c6cabaa1a72..9bb8c743823 100644 --- a/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/HitsVerificationBenchmark.java +++ b/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/HitsVerificationBenchmark.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.predicate.benchmarks; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.yahoo.search.predicate.Config; @@ -145,7 +146,7 @@ public class HitsVerificationBenchmark { private static void writeOutputToStandardOut(Map<String, Object> output) { try { - ObjectMapper objectMapper = new ObjectMapper(); + ObjectMapper objectMapper = Jackson.createMapper(); objectMapper.enable(SerializationFeature.INDENT_OUTPUT); objectMapper.writeValue(System.out, output); } catch (IOException e) { diff --git a/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/PredicateIndexBenchmark.java b/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/PredicateIndexBenchmark.java index 16ee07f34a1..986bf76de48 100644 --- a/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/PredicateIndexBenchmark.java +++ b/predicate-search/src/main/java/com/yahoo/search/predicate/benchmarks/PredicateIndexBenchmark.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.predicate.benchmarks; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.google.common.collect.Iterators; @@ -239,7 +240,7 @@ public class PredicateIndexBenchmark { private static void writeOutputToStandardOut() { try { - ObjectMapper objectMapper = new ObjectMapper(); + ObjectMapper objectMapper = Jackson.createMapper(); objectMapper.enable(SerializationFeature.INDENT_OUTPUT); objectMapper.writeValue(System.out, output); } catch (IOException e) { diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptionsJsonSerializer.java b/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptionsJsonSerializer.java index b9454df4cee..b81f28651ce 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptionsJsonSerializer.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptionsJsonSerializer.java @@ -59,7 +59,7 @@ class TransportSecurityOptionsJsonSerializer { } List<AuthorizedPeer> authorizedPeersEntity = entity.authorizedPeers; if (authorizedPeersEntity != null) { - if (authorizedPeersEntity.size() == 0) { + if (authorizedPeersEntity.isEmpty()) { throw new IllegalArgumentException("'authorized-peers' cannot be empty"); } builder.withAuthorizedPeers(new AuthorizedPeers(toPeerPolicies(authorizedPeersEntity))); @@ -124,12 +124,12 @@ class TransportSecurityOptionsJsonSerializer { } private static RequiredPeerCredential.Field toField(CredentialField field) { - switch (field) { - case CN: return RequiredPeerCredential.Field.CN; - case SAN_DNS: return RequiredPeerCredential.Field.SAN_DNS; - case SAN_URI: return RequiredPeerCredential.Field.SAN_URI; - default: throw new IllegalArgumentException("Invalid field type: " + field); - } + return switch (field) { + case CN -> RequiredPeerCredential.Field.CN; + case SAN_DNS -> RequiredPeerCredential.Field.SAN_DNS; + case SAN_URI -> RequiredPeerCredential.Field.SAN_URI; + default -> throw new IllegalArgumentException("Invalid field type: " + field); + }; } private static TransportSecurityOptionsEntity toTransportSecurityOptionsEntity(TransportSecurityOptions options) { @@ -172,12 +172,12 @@ class TransportSecurityOptionsJsonSerializer { } private static CredentialField toField(RequiredPeerCredential.Field field) { - switch (field) { - case CN: return CredentialField.CN; - case SAN_DNS: return CredentialField.SAN_DNS; - case SAN_URI: return CredentialField.SAN_URI; - default: throw new IllegalArgumentException("Invalid field type: " + field); - } + return switch (field) { + case CN -> CredentialField.CN; + case SAN_DNS -> CredentialField.SAN_DNS; + case SAN_URI -> CredentialField.SAN_URI; + default -> throw new IllegalArgumentException("Invalid field type: " + field); + }; } private static IllegalArgumentException missingFieldException(String fieldName) { diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthClient.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthClient.java index 5d32264bd18..7d20a96873d 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthClient.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthClient.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.service.health; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import java.util.logging.Level; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; @@ -23,7 +23,6 @@ import static com.yahoo.yolean.Exceptions.uncheck; public class StateV1HealthClient implements AutoCloseable { private static final long MAX_CONTENT_LENGTH = 1L << 20; // 1 MB - private static final ObjectMapper MAPPER = new ObjectMapper(); private static final Logger logger = Logger.getLogger(StateV1HealthClient.class.getName()); private final ApacheHttpClient httpClient; private final Function<HttpEntity, String> getContentFunction; @@ -54,7 +53,7 @@ public class StateV1HealthClient implements AutoCloseable { throw new IllegalArgumentException("Content too long: " + contentLength + " bytes"); } String body = getContentFunction.apply(bodyEntity); - HealthResponse healthResponse = MAPPER.readValue(body, HealthResponse.class); + HealthResponse healthResponse = Jackson.mapper().readValue(body, HealthResponse.class); if (healthResponse.status == null || healthResponse.status.code == null) { return HealthInfo.fromHealthStatusCode(HealthResponse.Status.DEFAULT_STATUS); diff --git a/vdslib/src/test/java/com/yahoo/vdslib/distribution/DistributionTestFactory.java b/vdslib/src/test/java/com/yahoo/vdslib/distribution/DistributionTestFactory.java index 17c31658e7f..16d872850d7 100644 --- a/vdslib/src/test/java/com/yahoo/vdslib/distribution/DistributionTestFactory.java +++ b/vdslib/src/test/java/com/yahoo/vdslib/distribution/DistributionTestFactory.java @@ -1,8 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vdslib.distribution; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.config.subscription.ConfigGetter; @@ -21,8 +21,6 @@ import static org.junit.Assert.assertTrue; // TODO: Use config builder instead of ConfigGetter to create test config. public class DistributionTestFactory extends CrossPlatformTestFactory { - final ObjectMapper mapper = new ObjectMapper(); - private static final String testDirectory = "src/tests/distribution/testdata"; private int redundancy; private int nodeCount; @@ -177,7 +175,7 @@ public class DistributionTestFactory extends CrossPlatformTestFactory { } public String serialize() { - ObjectNode test = new ObjectNode(mapper.getNodeFactory()) + ObjectNode test = new ObjectNode(Jackson.mapper().getNodeFactory()) .put("cluster-state", state.toString()) .put("distribution", new StorDistributionConfig(distributionConfig).toString()) .put("node-type", nodeType.toString()) @@ -195,7 +193,7 @@ public class DistributionTestFactory extends CrossPlatformTestFactory { } public void parse(String serialized) throws Exception { - JsonNode json = mapper.readTree(serialized); + JsonNode json = Jackson.mapper().readTree(serialized); upStates = json.get("up-states").textValue(); nodeCount = json.get("redundancy").intValue(); redundancy = json.get("redundancy").intValue(); diff --git a/vespaclient-java/src/main/java/com/yahoo/vespa/filedistribution/status/FileDistributionStatusClient.java b/vespaclient-java/src/main/java/com/yahoo/vespa/filedistribution/status/FileDistributionStatusClient.java index 8bb3bda1cb4..6e688c7737e 100644 --- a/vespaclient-java/src/main/java/com/yahoo/vespa/filedistribution/status/FileDistributionStatusClient.java +++ b/vespaclient-java/src/main/java/com/yahoo/vespa/filedistribution/status/FileDistributionStatusClient.java @@ -1,9 +1,9 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.filedistribution.status; +import ai.vespa.json.Jackson; import ai.vespa.util.http.hc5.VespaHttpClientBuilder; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import io.airlift.airline.Command; import io.airlift.airline.HelpOption; import io.airlift.airline.Option; @@ -102,10 +102,9 @@ public class FileDistributionStatusClient { } String parseAndGenerateOutput(String json) { - ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode; try { - jsonNode = objectMapper.readTree(json); + jsonNode = Jackson.mapper().readTree(json); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/vespaclient-java/src/test/java/com/yahoo/vespaget/DocumentRetrieverTest.java b/vespaclient-java/src/test/java/com/yahoo/vespaget/DocumentRetrieverTest.java index 2ea38a75ea0..223d62ea323 100644 --- a/vespaclient-java/src/test/java/com/yahoo/vespaget/DocumentRetrieverTest.java +++ b/vespaclient-java/src/test/java/com/yahoo/vespaget/DocumentRetrieverTest.java @@ -1,7 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespaget; -import com.fasterxml.jackson.databind.ObjectMapper; +import ai.vespa.json.Jackson; import com.yahoo.document.DataType; import com.yahoo.document.Document; import com.yahoo.document.DocumentId; @@ -182,9 +182,8 @@ public class DocumentRetrieverTest { documentRetriever.retrieveDocuments(); verify(mockedSession, times(3)).syncSend(any()); - ObjectMapper m = new ObjectMapper(); @SuppressWarnings("unchecked") - List<Map<String, Object>> feed = m.readValue(outContent.toByteArray(), List.class); + List<Map<String, Object>> feed = Jackson.mapper().readValue(outContent.toByteArray(), List.class); assertEquals(DOC_ID_1, feed.get(0).get("id")); assertEquals(DOC_ID_2, feed.get(1).get("id")); assertEquals(DOC_ID_3, feed.get(2).get("id")); diff --git a/vespajlib/abi-spec.json b/vespajlib/abi-spec.json index a97950415e4..f496ac62a72 100644 --- a/vespajlib/abi-spec.json +++ b/vespajlib/abi-spec.json @@ -4041,6 +4041,20 @@ ], "fields" : [ ] }, + "ai.vespa.json.Jackson" : { + "superClass" : "java.lang.Object", + "interfaces" : [ ], + "attributes" : [ + "public" + ], + "methods" : [ + "public void <init>()", + "public static com.fasterxml.jackson.databind.ObjectMapper createMapper()", + "public static com.fasterxml.jackson.databind.ObjectMapper createMapper(com.fasterxml.jackson.core.JsonFactoryBuilder)", + "public static com.fasterxml.jackson.databind.ObjectMapper mapper()" + ], + "fields" : [ ] + }, "ai.vespa.llm.LanguageModel" : { "superClass" : "java.lang.Object", "interfaces" : [ ], diff --git a/vespajlib/pom.xml b/vespajlib/pom.xml index 16ae251aa8b..2313a55a857 100644 --- a/vespajlib/pom.xml +++ b/vespajlib/pom.xml @@ -58,6 +58,11 @@ <scope>provided</scope> </dependency> <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <scope>provided</scope> + </dependency> + <dependency> <groupId>com.yahoo.vespa</groupId> <artifactId>annotations</artifactId> <version>${project.version}</version> @@ -82,11 +87,6 @@ <scope>test</scope> </dependency> <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <scope>test</scope> diff --git a/vespajlib/src/main/java/ai/vespa/json/Jackson.java b/vespajlib/src/main/java/ai/vespa/json/Jackson.java new file mode 100644 index 00000000000..58c775486ad --- /dev/null +++ b/vespajlib/src/main/java/ai/vespa/json/Jackson.java @@ -0,0 +1,27 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ai.vespa.json; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonFactoryBuilder; +import com.fasterxml.jackson.core.StreamReadFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class Jackson { + private static final ObjectMapper mapperInstance = createMapper(); + /// Create an ObjectMapper based on given factory, adds additional recommended settings + public static ObjectMapper createMapper() { + return createMapper(new JsonFactoryBuilder()); + } + + /// Create an ObjectMapper based on given factory, adds additional recommended settings + public static ObjectMapper createMapper(JsonFactoryBuilder jsonFactoryBuilder) { + JsonFactory jsonFactory = jsonFactoryBuilder + // This changes in 2.16, needs to consider what to do + .configure(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION, true) + .build(); + return new ObjectMapper(jsonFactory); + } + + /// Return a default ObjectMapper with recommended settings + public static ObjectMapper mapper() { return mapperInstance; } +} diff --git a/vespajlib/src/main/java/ai/vespa/json/package-info.java b/vespajlib/src/main/java/ai/vespa/json/package-info.java new file mode 100644 index 00000000000..95aa7b427c8 --- /dev/null +++ b/vespajlib/src/main/java/ai/vespa/json/package-info.java @@ -0,0 +1,7 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +@PublicApi +package ai.vespa.json; + +import com.yahoo.api.annotations.PublicApi; +import com.yahoo.osgi.annotation.ExportPackage;
\ No newline at end of file diff --git a/vespajlib/src/test/java/com/yahoo/slime/JsonBenchmark.java b/vespajlib/src/test/java/com/yahoo/slime/JsonBenchmark.java index 19862e874d6..e1aafca8d22 100644 --- a/vespajlib/src/test/java/com/yahoo/slime/JsonBenchmark.java +++ b/vespajlib/src/test/java/com/yahoo/slime/JsonBenchmark.java @@ -1,11 +1,11 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.slime; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -38,12 +38,13 @@ public class JsonBenchmark { try { for (int i=0; i < numIterations; i++) { - JsonParser jsonParser = jsonFactory.createParser(json); - JsonToken array = jsonParser.nextToken(); - for (JsonToken token = jsonParser.nextToken(); ! JsonToken.END_ARRAY.equals(token); token = jsonParser.nextToken()) { - if (JsonToken.FIELD_NAME.equals(token) && "weight".equals(jsonParser.getCurrentName())) { - token = jsonParser.nextToken(); - count += jsonParser.getLongValue(); + try (JsonParser jsonParser = jsonFactory.createParser(json)) { + JsonToken array = jsonParser.nextToken(); + for (JsonToken token = jsonParser.nextToken(); !JsonToken.END_ARRAY.equals(token); token = jsonParser.nextToken()) { + if (JsonToken.FIELD_NAME.equals(token) && "weight".equals(jsonParser.getCurrentName())) { + token = jsonParser.nextToken(); + count += jsonParser.getLongValue(); + } } } } @@ -54,11 +55,10 @@ public class JsonBenchmark { } private static long benchmarkJacksonTree(byte [] json, int numIterations) { long count = 0; - ObjectMapper mapper = new ObjectMapper(); // use the ObjectMapper to read the json string and create a tree try { for (int i=0; i < numIterations; i++) { - JsonNode node = mapper.readTree(json); + JsonNode node = Jackson.mapper().readTree(json); for(JsonNode item : node) { count += item.get("weight").asLong(); } diff --git a/vespajlib/src/test/java/com/yahoo/tensor/serialization/SerializationTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/serialization/SerializationTestCase.java index 2be61de0bfa..147cb402cb3 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/serialization/SerializationTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/serialization/SerializationTestCase.java @@ -2,8 +2,8 @@ package com.yahoo.tensor.serialization; +import ai.vespa.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.io.GrowableByteBuffer; import com.yahoo.tensor.Tensor; import com.yahoo.tensor.TensorType; @@ -25,8 +25,8 @@ import static org.junit.Assert.assertTrue; public class SerializationTestCase { - private static String testPath = "eval/src/apps/make_tensor_binary_format_test_spec/test_spec.json"; - private static List<String> tests = new ArrayList<>(); + private static final String testPath = "eval/src/apps/make_tensor_binary_format_test_spec/test_spec.json"; + private static final List<String> tests = new ArrayList<>(); @Before public void loadTests() throws IOException { @@ -46,8 +46,7 @@ public class SerializationTestCase { @Test public void testSerialization() throws IOException { for (String test : tests) { - ObjectMapper mapper = new ObjectMapper(); - JsonNode node = mapper.readTree(test); + JsonNode node = Jackson.mapper().readTree(test); if (node.has("tensor") && node.has("binary")) { System.out.println("Running test: " + test); |