Move entry serialization back to ByteBufWriter
[controller.git] / atomix-storage / src / main / java / io / atomix / storage / journal / JournalSerdes.java
1 /*
2  * Copyright 2014-2021 Open Networking Foundation
3  * Copyright 2023 PANTHEON.tech, s.r.o.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package io.atomix.storage.journal;
18
19 import com.esotericsoftware.kryo.KryoException;
20 import com.google.common.annotations.Beta;
21 import com.google.common.annotations.VisibleForTesting;
22 import io.atomix.utils.serializer.KryoJournalSerdesBuilder;
23 import io.netty.buffer.ByteBuf;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.nio.ByteBuffer;
28
29 /**
30  * Support for serialization of {@link Journal} entries.
31  *
32  * @deprecated due to dependency on outdated Kryo library, {@link ByteBufMapper} to be used instead.
33  */
34 @Deprecated(forRemoval = true, since = "9.0.3")
35 public interface JournalSerdes {
36     /**
37      * Serializes given object to byte array.
38      *
39      * @param obj Object to serialize
40      * @return serialized bytes
41      */
42     byte[] serialize(Object obj);
43
44     /**
45      * Serializes given object to byte array.
46      *
47      * @param obj        Object to serialize
48      * @param bufferSize maximum size of serialized bytes
49      * @return serialized bytes
50      */
51     byte[] serialize(Object obj, int bufferSize);
52
53     /**
54      * Serializes given object to byte buffer.
55      *
56      * @param obj    Object to serialize
57      * @param buffer to write to
58      */
59     void serialize(Object obj, ByteBuffer buffer);
60
61     /**
62      * Serializes given object to OutputStream.
63      *
64      * @param obj    Object to serialize
65      * @param stream to write to
66      */
67     void serialize(Object obj, OutputStream stream);
68
69     /**
70      * Serializes given object to OutputStream.
71      *
72      * @param obj        Object to serialize
73      * @param stream     to write to
74      * @param bufferSize size of the buffer in front of the stream
75      */
76     void serialize(Object obj, OutputStream stream, int bufferSize);
77
78     /**
79      * Deserializes given byte array to Object.
80      *
81      * @param bytes serialized bytes
82      * @param <T>   deserialized Object type
83      * @return deserialized Object
84      */
85     <T> T deserialize(byte[] bytes);
86
87     /**
88      * Deserializes given byte buffer to Object.
89      *
90      * @param buffer input with serialized bytes
91      * @param <T>    deserialized Object type
92      * @return deserialized Object
93      */
94     <T> T deserialize(ByteBuffer buffer);
95
96     /**
97      * Deserializes given InputStream to an Object.
98      *
99      * @param stream input stream
100      * @param <T>    deserialized Object type
101      * @return deserialized Object
102      */
103     <T> T deserialize(InputStream stream);
104
105     /**
106      * Deserializes given InputStream to an Object.
107      *
108      * @param stream     input stream
109      * @param <T>        deserialized Object type
110      * @param bufferSize size of the buffer in front of the stream
111      * @return deserialized Object
112      */
113     <T> T deserialize(InputStream stream, int bufferSize);
114
115     /**
116      * Returns a {@link ByteBufMapper} backed by this object.
117      *
118      * @return a {@link ByteBufMapper} backed by this object
119      */
120     default <T> ByteBufMapper<T> toMapper() {
121         return new ByteBufMapper<>() {
122             @Override
123             public void objectToBytes(final T obj, final ByteBuf bytes) throws IOException {
124                 final var buffer = bytes.nioBuffer();
125                 try {
126                     serialize(obj, buffer);
127                 } catch (KryoException e) {
128                     throw new IOException(e);
129                 } finally {
130                     // adjust writerIndex so that readableBytes() the bytes written
131                     bytes.writerIndex(bytes.readerIndex() + buffer.position());
132                 }
133             }
134
135             @Override
136             public T bytesToObject(final long index, final ByteBuf bytes) {
137                 return deserialize(bytes.nioBuffer());
138             }
139         };
140     }
141
142     /**
143      * Creates a new {@link JournalSerdes} builder.
144      *
145      * @return builder
146      */
147     static Builder builder() {
148         return new KryoJournalSerdesBuilder();
149     }
150
151     /**
152      * Builder for {@link JournalSerdes}.
153      */
154     interface Builder {
155         /**
156          * Builds a {@link JournalSerdes} instance.
157          *
158          * @return A {@link JournalSerdes} implementation.
159          */
160         JournalSerdes build();
161
162         /**
163          * Builds a {@link JournalSerdes} instance.
164          *
165          * @param friendlyName friendly name for the namespace
166          * @return A {@link JournalSerdes} implementation.
167          */
168         JournalSerdes build(String friendlyName);
169
170         /**
171          * Registers serializer for the given set of classes.
172          *
173          * <p>
174          * When multiple classes are registered with an explicitly provided serializer, the namespace guarantees
175          * all instances will be serialized with the same type ID.
176          *
177          * @param classes list of classes to register
178          * @param serdes  serializer to use for the class
179          * @return this builder
180          */
181         Builder register(EntrySerdes<?> serdes, Class<?>... classes);
182
183         /**
184          * Sets the namespace class loader.
185          *
186          * @param classLoader the namespace class loader
187          * @return this builder
188          */
189         Builder setClassLoader(ClassLoader classLoader);
190     }
191
192     /**
193      * Input data stream exposed to {@link EntrySerdes#read(EntryInput)}.
194      */
195     @Beta
196     interface EntryInput {
197
198         byte[] readBytes(int length) throws IOException;
199
200         long readLong() throws IOException;
201
202         String readString() throws IOException;
203
204         Object readObject() throws IOException;
205
206         @VisibleForTesting
207         int readVarInt() throws IOException;
208     }
209
210     /**
211      * Output data stream exposed to {@link EntrySerdes#write(EntryOutput, Object)}.
212      */
213     @Beta
214     interface EntryOutput {
215
216         void writeBytes(byte[] bytes) throws IOException;
217
218         void writeLong(long value) throws IOException;
219
220         void writeObject(Object value) throws IOException;
221
222         void writeString(String value) throws IOException;
223
224         @VisibleForTesting
225         void writeVarInt(int value) throws IOException;
226     }
227
228     /**
229      * A serializer/deserializer for an entry.
230      *
231      * @param <T> Entry type
232      */
233     interface EntrySerdes<T> {
234
235         T read(EntryInput input) throws IOException;
236
237         void write(EntryOutput output, T entry) throws IOException;
238     }
239 }