public static ByteBuffer getByteBufferOrNull(String property, JsonNode node) {
    if (!node.has(property) || node.get(property).isNull()) {
      return null;
    }

    JsonNode pNode = node.get(property);
    Preconditions.checkArgument(
        pNode.isTextual(), "Cannot parse byte buffer from non-text value: %s: %s", property, pNode);
    return ByteBuffer.wrap(
        BaseEncoding.base16().decode(pNode.textValue().toUpperCase(Locale.ROOT)));
  }
@Test
  public void getByteBufferOrNull() throws JsonProcessingException {
    assertThat(JsonUtil.getByteBufferOrNull("x", JsonUtil.mapper().readTree("{}"))).isNull();
    assertThat(JsonUtil.getByteBufferOrNull("x", JsonUtil.mapper().readTree("{\"x\": null}")))
        .isNull();

    byte[] bytes = new byte[] {1, 2, 3, 4};
    String base16Str = BaseEncoding.base16().encode(bytes);
    String json = String.format("{\"x\": \"%s\"}", base16Str);
    ByteBuffer byteBuffer = JsonUtil.getByteBufferOrNull("x", JsonUtil.mapper().readTree(json));
    assertThat(byteBuffer.array()).isEqualTo(bytes);

    assertThatThrownBy(
            () -> JsonUtil.getByteBufferOrNull("x", JsonUtil.mapper().readTree("{\"x\": 23}")))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("Cannot parse byte buffer from non-text value: x: 23");
  }