@Override public RequestMessage deserializeRequest(final ByteBuf msg) throws SerializationException { try { final Kryo kryo = kryoThreadLocal.get(); final byte[] payload = new byte[msg.readableBytes()]; msg.readBytes(payload); try (final Input input = new Input(payload)) { // by the time the message gets here, the mime length/type have been already read, so this // part just // needs to process the payload. final UUID id = kryo.readObject(input, UUID.class); final String processor = input.readString(); final String op = input.readString(); final RequestMessage.Builder builder = RequestMessage.build(op).overrideRequestId(id).processor(processor); final Map<String, Object> args = kryo.readObject(input, HashMap.class); args.forEach(builder::addArg); return builder.create(); } } catch (Exception ex) { logger.warn( "Request [{}] could not be deserialized by {}.", msg, GryoMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
@Override public ResponseMessage deserializeResponse(final ByteBuf msg) throws SerializationException { try { final Kryo kryo = kryoThreadLocal.get(); final byte[] payload = new byte[msg.readableBytes()]; msg.readBytes(payload); try (final Input input = new Input(payload)) { final UUID requestId = kryo.readObjectOrNull(input, UUID.class); final int status = input.readShort(); final String statusMsg = input.readString(); final Map<String, Object> statusAttributes = (Map<String, Object>) kryo.readClassAndObject(input); final Object result = kryo.readClassAndObject(input); final Map<String, Object> metaAttributes = (Map<String, Object>) kryo.readClassAndObject(input); return ResponseMessage.build(requestId) .code(ResponseStatusCode.getFromValue(status)) .statusMessage(statusMsg.intern()) .statusAttributes(statusAttributes) .result(result) .responseMetaData(metaAttributes) .create(); } } catch (Exception ex) { logger.warn( "Response [{}] could not be deserialized by {}.", msg, GryoMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
@Override public ByteBuf serializeResponseAsBinary( final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException { ByteBuf encodedMessage = null; try { final Kryo kryo = kryoThreadLocal.get(); try (final OutputStream baos = new ByteArrayOutputStream()) { final Output output = new Output(baos); // request id - if present kryo.writeObjectOrNull( output, responseMessage.getRequestId() != null ? responseMessage.getRequestId() : null, UUID.class); // status output.writeShort(responseMessage.getStatus().getCode().getValue()); output.writeString(responseMessage.getStatus().getMessage()); kryo.writeClassAndObject(output, responseMessage.getStatus().getAttributes()); // result kryo.writeClassAndObject( output, serializeToString ? serializeResultToString(responseMessage) : responseMessage.getResult().getData()); kryo.writeClassAndObject(output, responseMessage.getResult().getMeta()); final long size = output.total(); if (size > Integer.MAX_VALUE) throw new SerializationException( String.format("Message size of %s exceeds allocatable space", size)); encodedMessage = allocator.buffer((int) output.total()); encodedMessage.writeBytes(output.toBytes()); } return encodedMessage; } catch (Exception ex) { if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage); logger.warn( "Response [{}] could not be serialized by {}.", responseMessage.toString(), GryoMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
@Override public ByteBuf serializeRequestAsBinary( final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException { ByteBuf encodedMessage = null; try { final Kryo kryo = kryoThreadLocal.get(); try (final OutputStream baos = new ByteArrayOutputStream()) { final Output output = new Output(baos); final String mimeType = serializeToString ? MIME_TYPE_STRINGD : MIME_TYPE; output.writeByte(mimeType.length()); output.write(mimeType.getBytes(UTF8)); kryo.writeObject(output, requestMessage.getRequestId()); output.writeString(requestMessage.getProcessor()); output.writeString(requestMessage.getOp()); kryo.writeObject(output, requestMessage.getArgs()); final long size = output.total(); if (size > Integer.MAX_VALUE) throw new SerializationException( String.format("Message size of %s exceeds allocatable space", size)); encodedMessage = allocator.buffer((int) size); encodedMessage.writeBytes(output.toBytes()); } return encodedMessage; } catch (Exception ex) { if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage); logger.warn( "Request [{}] could not be serialized by {}.", requestMessage.toString(), GryoMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
@Override public Kryo createMapper() { final Kryo kryo = new Kryo(new GryoClassResolver(), new MapReferenceResolver(), new DefaultStreamFactory()); kryo.addDefaultSerializer(Map.Entry.class, new EntrySerializer()); kryo.setRegistrationRequired(registrationRequired); kryo.setReferences(referenceTracking); serializationList.forEach( p -> { final Function<Kryo, Serializer> serializer = p.getValue1(); if (null == serializer) kryo.register(p.getValue0(), kryo.getDefaultSerializer(p.getValue0()), p.getValue2()); else kryo.register(p.getValue0(), serializer.apply(kryo), p.getValue2()); }); return kryo; }