diff --git a/serde-support/src/main/java/io/micronaut/serde/support/serdes/ByteBufferSerde.java b/serde-support/src/main/java/io/micronaut/serde/support/serdes/ByteBufferSerde.java new file mode 100644 index 000000000..2c3b74579 --- /dev/null +++ b/serde-support/src/main/java/io/micronaut/serde/support/serdes/ByteBufferSerde.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.serde.support.serdes; + +import io.micronaut.core.annotation.NonNull; +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.type.Argument; +import io.micronaut.serde.Decoder; +import io.micronaut.serde.Encoder; +import io.micronaut.serde.Serde; +import jakarta.inject.Singleton; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * {@link Serde} implementation of {@link java.nio.ByteBuffer}. + * This is a based on `com.fasterxml.jackson.databind.ser.std.ByteBufferSerializer` which is licenced under the Apache 2.0 licence. + */ +@Singleton +public class ByteBufferSerde implements Serde { + @Override + public @Nullable ByteBuffer deserialize(@NonNull Decoder decoder, + @NonNull DecoderContext context, + @NonNull Argument type) throws IOException { + byte[] b = decoder.decodeBinary(); + return ByteBuffer.wrap(b); + } + + @Override + public void serialize(@NonNull Encoder encoder, + @NonNull EncoderContext context, + @NonNull Argument type, + @NonNull ByteBuffer value) throws IOException { + ByteBuffer slice = value.asReadOnlyBuffer(); + ByteBuffer copy = ByteBuffer.allocate(slice.remaining()); + copy.put(slice); + encoder.encodeBinary(copy.array()); + } +} diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/ByteArrayWriteValueAsStringTest.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/ByteArrayWriteValueAsStringTest.java new file mode 100644 index 000000000..ffe37407a --- /dev/null +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/ByteArrayWriteValueAsStringTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.serde.tck.tests; + +import io.micronaut.context.annotation.Property; +import io.micronaut.core.util.StringUtils; +import io.micronaut.json.JsonMapper; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import org.junit.jupiter.api.Test; +import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Property(name = "micronaut.serde.write-binary-as-array", value = StringUtils.FALSE) +@MicronautTest(startApplication = false) +public class ByteArrayWriteValueAsStringTest { + + /** + * byte[] is written as base64 string + * @param jsonMapper JSONMapper either Jackson or Serde implementation + * @throws IOException If an unrecoverable error occurs + */ + @Test + public void testByteArrayAsString(JsonMapper jsonMapper) throws IOException { + final byte[] INPUT_BYTES = new byte[] { 1, 2, 3, 4, 5 }; + assertEquals("\"AQIDBAU=\"", jsonMapper.writeValueAsString(INPUT_BYTES)); + } +} diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/InetAddressTest.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/InetAddressTest.java index d2fbb9d83..83660540c 100644 --- a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/InetAddressTest.java +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/InetAddressTest.java @@ -23,7 +23,7 @@ import java.net.InetAddress; import static org.junit.jupiter.api.Assertions.assertEquals; -@MicronautTest +@MicronautTest(startApplication = false) public class InetAddressTest { @Test diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferDuplicatedTest.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferDuplicatedTest.java new file mode 100644 index 000000000..f21c9b944 --- /dev/null +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferDuplicatedTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.serde.tck.tests.bytebuffer; + +import io.micronaut.context.annotation.Property; +import io.micronaut.core.util.StringUtils; +import io.micronaut.json.JsonMapper; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Property(name = "micronaut.serde.write-binary-as-array", value = StringUtils.FALSE) +@MicronautTest(startApplication = false) +public class ByteBufferDuplicatedTest { + /** + * Test ported from com.fasterxml.jackson.databind.ser.jdk.JDKTypeSerializationTest + * @param jsonMapper JSONMapper either Jackson or Serde implementation + * @throws IOException If an unrecoverable error occurs + */ + @Test + public void testDuplicatedByteBufferWithCustomPosition(JsonMapper jsonMapper) throws IOException { + final byte[] INPUT_BYTES = new byte[] { 1, 2, 3, 4, 5 }; + + String exp = jsonMapper.writeValueAsString(new byte[] { 3, 4, 5 }); + ByteBuffer bbuf = ByteBuffer.wrap(INPUT_BYTES); + bbuf.position(2); + ByteBuffer duplicated = bbuf.duplicate(); + assertEquals(exp, jsonMapper.writeValueAsString(duplicated)); + + // also check differently constructed bytebuffer (noting that + // offset given is the _position_ to use, NOT array offset + exp = jsonMapper.writeValueAsString(new byte[] { 2, 3, 4 }); + bbuf = ByteBuffer.wrap(INPUT_BYTES, 1, 3); + assertEquals(exp, jsonMapper.writeValueAsString(bbuf.duplicate())); + } +} diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferNativeTest.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferNativeTest.java new file mode 100644 index 000000000..25138d70e --- /dev/null +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferNativeTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.serde.tck.tests.bytebuffer; + +import io.micronaut.context.annotation.Property; +import io.micronaut.core.util.StringUtils; +import io.micronaut.json.JsonMapper; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Property(name = "micronaut.serde.write-binary-as-array", value = StringUtils.FALSE) +@MicronautTest(startApplication = false) +public class ByteBufferNativeTest { + /** + * Test ported from com.fasterxml.jackson.databind.ser.jdk.JDKTypeSerializationTest + * @param jsonMapper JSONMapper either Jackson or Serde implementation + * @throws IOException If an unrecoverable error occurs + */ + @Test + public void testByteBufferNative(JsonMapper jsonMapper) throws IOException { + final byte[] INPUT_BYTES = new byte[]{1, 2, 3, 4, 5}; + String exp = jsonMapper.writeValueAsString(INPUT_BYTES); + // so far so good, but must ensure Native buffers also work: + ByteBuffer bbuf2 = ByteBuffer.allocateDirect(5); + bbuf2.put(INPUT_BYTES); + bbuf2.flip(); + assertEquals(exp, jsonMapper.writeValueAsString(bbuf2)); + } +} diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferSlicedTest.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferSlicedTest.java new file mode 100644 index 000000000..e09b388d0 --- /dev/null +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferSlicedTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.serde.tck.tests.bytebuffer; + +import io.micronaut.context.annotation.Property; +import io.micronaut.core.util.StringUtils; +import io.micronaut.json.JsonMapper; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Property(name = "micronaut.serde.write-binary-as-array", value = StringUtils.FALSE) +@MicronautTest(startApplication = false) +public class ByteBufferSlicedTest { + + /** + * Test ported from com.fasterxml.jackson.databind.ser.jdk.JDKTypeSerializationTest + * @param jsonMapper JSONMapper either Jackson or Serde implementation + * @throws IOException If an unrecoverable error occurs + */ + @Test + public void testSlicedByteBuffer(JsonMapper jsonMapper) throws IOException { + final byte[] INPUT_BYTES = new byte[] { 1, 2, 3, 4, 5 }; + ByteBuffer bbuf = ByteBuffer.wrap(INPUT_BYTES); + + bbuf.position(2); + ByteBuffer slicedBuf = bbuf.slice(); + + assertEquals(jsonMapper.writeValueAsString(new byte[] { 3, 4, 5 }), + jsonMapper.writeValueAsString(slicedBuf)); + + // but how about offset within? + slicedBuf.position(1); + assertEquals(jsonMapper.writeValueAsString(new byte[] { 4, 5 }), + jsonMapper.writeValueAsString(slicedBuf)); + } +} diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferTest.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferTest.java new file mode 100644 index 000000000..ead2b3899 --- /dev/null +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/ByteBufferTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.serde.tck.tests.bytebuffer; + +import io.micronaut.context.annotation.Property; +import io.micronaut.core.util.StringUtils; +import io.micronaut.json.JsonMapper; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +@Property(name = "micronaut.serde.write-binary-as-array", value = StringUtils.FALSE) +@MicronautTest(startApplication = false) +public class ByteBufferTest { + + /** + * Test ported from com.fasterxml.jackson.databind.ser.jdk.JDKTypeSerializationTest + * @param jsonMapper JSONMapper either Jackson or Serde implementation + * @throws IOException If an unrecoverable error occurs + */ + @Test + public void testByteBuffer(JsonMapper jsonMapper) throws IOException { + final byte[] INPUT_BYTES = new byte[]{1, 2, 3, 4, 5}; + String exp = jsonMapper.writeValueAsString(INPUT_BYTES); + ByteBuffer bbuf = ByteBuffer.wrap(INPUT_BYTES); + assertEquals(exp, jsonMapper.writeValueAsString(bbuf)); + } +} diff --git a/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/package-info.java b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/package-info.java new file mode 100644 index 000000000..374a76382 --- /dev/null +++ b/serde-tck-tests/src/main/java/io/micronaut/serde/tck/tests/bytebuffer/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Tests ported from Jackson Databind project. + * Jackson-databind is licensed under Apache 2.0. License + */ +package io.micronaut.serde.tck.tests.bytebuffer; diff --git a/test-suite-tck-jackson-databind/src/test/resources/logback.xml b/test-suite-tck-jackson-databind/src/test/resources/logback.xml new file mode 100644 index 000000000..8eb8c3a81 --- /dev/null +++ b/test-suite-tck-jackson-databind/src/test/resources/logback.xml @@ -0,0 +1,10 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + diff --git a/test-suite-tck-serde/src/test/resources/logback.xml b/test-suite-tck-serde/src/test/resources/logback.xml new file mode 100644 index 000000000..8eb8c3a81 --- /dev/null +++ b/test-suite-tck-serde/src/test/resources/logback.xml @@ -0,0 +1,10 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + +