@Override public CompletableFuture<List<ResponseMessage>> submitAsync(final RequestMessage requestMessage) throws Exception { final List<ResponseMessage> results = new ArrayList<>(); final CompletableFuture<List<ResponseMessage>> f = new CompletableFuture<>(); callbackResponseHandler.callback = response -> { if (f.isDone()) throw new RuntimeException("A terminating message was already encountered - no more messages should have been received"); results.add(response); // check if the current message is terminating - if it is then we can mark complete if (!response.getStatus().getCode().equals(ResponseStatusCode.PARTIAL_CONTENT)) { f.complete(results); } }; writeAndFlush(requestMessage); return f; }
@Override public ResponseMessage createObject(final Map<String, Object> data) { final Map<String, Object> status = (Map<String, Object>) data.get(SerTokens.TOKEN_STATUS); final Map<String, Object> result = (Map<String, Object>) data.get(SerTokens.TOKEN_RESULT); return ResponseMessage.build(UUID.fromString(data.get(SerTokens.TOKEN_REQUEST).toString())) .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE))) .statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString()) .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES)) .result(result.get(SerTokens.TOKEN_DATA)) .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META)) .create(); } }
@Override public ByteBuf serializeResponseAsBinary(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException { ByteBuf encodedMessage = null; try { final Kryo kryo = kryoThreadLocal.get(); try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) { final Output output = new Output(baos, bufferSize); // 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)); output.flush(); encodedMessage = allocator.buffer((int) size); encodedMessage.writeBytes(baos.toByteArray()); } return encodedMessage; } catch (Exception ex) { if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage); logger.warn(String.format("Response [%s] could not be serialized by %s.", responseMessage, AbstractGryoMessageSerializerV1d0.class.getName()), ex); throw new SerializationException(ex); } }
/** * Writes a response message to the underlying channel while ensuring that at most one * {@link ResponseStatusCode#isFinalResponse() final} response is written. * <p>The caller must make sure that the provided response status code matches the content of the message.</p> * <p>Note: this method should be used instead of writing to the channel directly when multiple threads * are expected to produce response messages concurrently.</p> * <p>Attempts to write more than one final response message will be ignored.</p> * @see #writeAndFlush(ResponseMessage) */ public void writeAndFlush(final ResponseStatusCode code, final Object responseMessage) { final boolean messageIsFinal = code.isFinalResponse(); if(finalResponseWritten.compareAndSet(false, messageIsFinal)) { context.getChannelHandlerContext().writeAndFlush(responseMessage); } else { final String logMessage = String.format("Another final response message was already written for request %s, ignoring response code: %s", context.getRequestMessage().getRequestId(), code); logger.warn(logMessage); } } }
if (!o.getStatus().getCode().isSuccess()) errorMeter.mark(); if (null == session || !o.getStatus().getCode().isSuccess()) serialized = new Frame(serializer.serializeResponseAsBinary(o, ctx.alloc())); else if (null == session || !o.getStatus().getCode().isSuccess()) serialized = new Frame(textSerializer.serializeResponseAsString(o)); else
/** * Writes a response message to the underlying channel while ensuring that at most one * {@link ResponseStatusCode#isFinalResponse() final} response is written. * <p>The caller must make sure that the provided response status code matches the content of the message.</p> * <p>Note: this method should be used instead of writing to the channel directly when multiple threads * are expected to produce response messages concurrently.</p> * <p>Attempts to write more than one final response message will be ignored.</p> * @see #writeAndFlush(ResponseMessage) */ public void writeAndFlush(final ResponseStatusCode code, final Object responseMessage) { final boolean messageIsFinal = code.isFinalResponse(); if(finalResponseWritten.compareAndSet(false, messageIsFinal)) { context.getChannelHandlerContext().writeAndFlush(responseMessage); } else { final String logMessage = String.format("Another final response message was already written for request %s, ignoring response code: %s", context.getRequestMessage().getRequestId(), code); logger.warn(logMessage); } } }
if (!o.getStatus().getCode().isSuccess()) errorMeter.mark(); if (null == session || !o.getStatus().getCode().isSuccess()) serialized = new Frame(serializer.serializeResponseAsBinary(o, ctx.alloc())); else if (null == session || !o.getStatus().getCode().isSuccess()) serialized = new Frame(textSerializer.serializeResponseAsString(o)); else
@Override public ResponseMessage deserializeResponse(final ByteBuf msg) throws SerializationException { try { final byte[] payload = new byte[msg.readableBytes()]; msg.readBytes(payload); final Map<String, Object> responseData = mapper.readValue(payload, mapTypeReference); final Map<String, Object> status = (Map<String, Object>) responseData.get(SerTokens.TOKEN_STATUS); final Map<String, Object> result = (Map<String, Object>) responseData.get(SerTokens.TOKEN_RESULT); return ResponseMessage.build(UUID.fromString(responseData.get(SerTokens.TOKEN_REQUEST).toString())) .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE))) .statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString()) .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES)) .result(result.get(SerTokens.TOKEN_DATA)) .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META)) .create(); } catch (Exception ex) { logger.warn("Response [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
public ByteBuf writeValue(final ResponseMessage value, final ByteBufAllocator allocator, final GraphBinaryWriter context, final boolean nullable) throws SerializationException { final ResponseResult result = value.getResult(); final ResponseStatus status = value.getStatus(); return allocator.compositeBuffer(8).addComponents(true, // Version allocator.buffer(1).writeByte(0x81), // Nullable request id context.writeValue(value.getRequestId(), allocator, true), // Status code context.writeValue(status.getCode().getValue(), allocator, false), // Nullable status message context.writeValue(status.getMessage(), allocator, true), // Status attributes context.writeValue(status.getAttributes(), allocator, false), // Result meta context.writeValue(result.getMeta(), allocator, false), // Fully-qualified value context.write(result.getData(), allocator)); } }
@Override public CompletableFuture<List<ResponseMessage>> submitAsync(final RequestMessage requestMessage) throws Exception { final List<ResponseMessage> results = new ArrayList<>(); final CompletableFuture<List<ResponseMessage>> f = new CompletableFuture<>(); callbackResponseHandler.callback = response -> { if (f.isDone()) throw new RuntimeException("A terminating message was already encountered - no more messages should have been received"); results.add(response); // check if the current message is terminating - if it is then we can mark complete if (!response.getStatus().getCode().equals(ResponseStatusCode.PARTIAL_CONTENT)) { f.complete(results); } }; writeAndFlush(requestMessage); return f; }
@Override public ResponseMessage deserializeResponse(final String msg) throws SerializationException { try { final Map<String, Object> responseData = mapper.readValue(msg, mapTypeReference); final Map<String, Object> status = (Map<String, Object>) responseData.get(SerTokens.TOKEN_STATUS); final Map<String, Object> result = (Map<String, Object>) responseData.get(SerTokens.TOKEN_RESULT); return ResponseMessage.build(UUID.fromString(responseData.get(SerTokens.TOKEN_REQUEST).toString())) .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE))) .statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString()) .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES)) .result(result.get(SerTokens.TOKEN_DATA)) .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META)) .create(); } catch (Exception ex) { logger.warn("Response [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
public void ser(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException, JsonProcessingException { jsonGenerator.writeStartObject(); if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); jsonGenerator.writeStringField(SerTokens.TOKEN_REQUEST, responseMessage.getRequestId() != null ? responseMessage.getRequestId().toString() : null); jsonGenerator.writeObjectFieldStart(SerTokens.TOKEN_STATUS); if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); jsonGenerator.writeStringField(SerTokens.TOKEN_MESSAGE, responseMessage.getStatus().getMessage()); jsonGenerator.writeNumberField(SerTokens.TOKEN_CODE, responseMessage.getStatus().getCode().getValue()); jsonGenerator.writeObjectField(SerTokens.TOKEN_ATTRIBUTES, responseMessage.getStatus().getAttributes()); jsonGenerator.writeEndObject(); jsonGenerator.writeObjectFieldStart(SerTokens.TOKEN_RESULT); if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); if (null == responseMessage.getResult().getData()) jsonGenerator.writeNullField(SerTokens.TOKEN_DATA); else GraphSONUtil.writeWithType(SerTokens.TOKEN_DATA, responseMessage.getResult().getData(), jsonGenerator, serializerProvider, typeSerializer); jsonGenerator.writeObjectField(SerTokens.TOKEN_META, responseMessage.getResult().getMeta()); jsonGenerator.writeEndObject(); jsonGenerator.writeEndObject(); } }
@Override public ResponseMessage deserializeResponse(final ByteBuf msg) throws SerializationException { try { final Kryo kryo = kryoThreadLocal.get(); final byte[] payload = new byte[msg.capacity()]; 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) .statusAttributes(statusAttributes) .result(result) .responseMetaData(metaAttributes) .create(); } } catch (Exception ex) { logger.warn(String.format("Response [%s] could not be deserialized by %s.", msg, AbstractGryoMessageSerializerV1d0.class.getName()), ex); throw new SerializationException(ex); } }
@Override public <O extends OutputShim> void write(final KryoShim<?, O> kryo, final O output, final ResponseMessage responseMessage) { kryo.writeObjectOrNull(output, responseMessage.getRequestId() != null ? responseMessage.getRequestId() : null, UUID.class); // status output.writeShort((short) responseMessage.getStatus().getCode().getValue()); output.writeString(responseMessage.getStatus().getMessage()); kryo.writeClassAndObject(output, responseMessage.getStatus().getAttributes()); // result kryo.writeClassAndObject(output, responseMessage.getResult().getData()); kryo.writeClassAndObject(output, responseMessage.getResult().getMeta()); }
public ResponseMessage readValue(final ByteBuf buffer, final GraphBinaryReader context, final boolean nullable) throws SerializationException { final int version = buffer.readByte(); assert version >>> 31 == 1; return ResponseMessage.build(context.readValue(buffer, UUID.class, true)) .code(ResponseStatusCode.getFromValue(context.readValue(buffer, Integer.class, false))) .statusMessage(context.readValue(buffer, String.class, true)) .statusAttributes(context.readValue(buffer, Map.class, false)) .responseMetaData(context.readValue(buffer, Map.class, false)) .result(context.read(buffer)) .create(); }
public void ser(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException { GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer); jsonGenerator.writeStringField(SerTokens.TOKEN_REQUEST, responseMessage.getRequestId() != null ? responseMessage.getRequestId().toString() : null); jsonGenerator.writeFieldName(SerTokens.TOKEN_STATUS); GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer); jsonGenerator.writeStringField(SerTokens.TOKEN_MESSAGE, responseMessage.getStatus().getMessage()); jsonGenerator.writeNumberField(SerTokens.TOKEN_CODE, responseMessage.getStatus().getCode().getValue()); jsonGenerator.writeObjectField(SerTokens.TOKEN_ATTRIBUTES, responseMessage.getStatus().getAttributes()); GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer); jsonGenerator.writeFieldName(SerTokens.TOKEN_RESULT); GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer); if (null == responseMessage.getResult().getData()){ jsonGenerator.writeNullField(SerTokens.TOKEN_DATA); } else { jsonGenerator.writeFieldName(SerTokens.TOKEN_DATA); final Object result = responseMessage.getResult().getData(); serializerProvider.findTypedValueSerializer(result.getClass(), true, null).serialize(result, jsonGenerator, serializerProvider); } jsonGenerator.writeObjectField(SerTokens.TOKEN_META, responseMessage.getResult().getMeta()); GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer); GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer); } }
@Override public <I extends InputShim> ResponseMessage read(final KryoShim<I, ?> kryo, final I input, final Class<ResponseMessage> clazz) { 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) .statusAttributes(statusAttributes) .result(result) .responseMetaData(metaAttributes) .create(); } }
@Override public ByteBuf serializeResponseAsBinary(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException { ByteBuf encodedMessage = null; try { final Kryo kryo = kryoThreadLocal.get(); try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) { final Output output = new Output(baos, bufferSize); // 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)); output.flush(); encodedMessage = allocator.buffer((int) size); encodedMessage.writeBytes(baos.toByteArray()); } return encodedMessage; } catch (Exception ex) { if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage); logger.warn(String.format("Response [%s] could not be serialized by %s.", responseMessage, AbstractGryoMessageSerializerV1d0.class.getName()), ex); throw new SerializationException(ex); } }
@Override public ResponseMessage createObject(final Map<String, Object> data) { final Map<String, Object> status = (Map<String, Object>) data.get(SerTokens.TOKEN_STATUS); final Map<String, Object> result = (Map<String, Object>) data.get(SerTokens.TOKEN_RESULT); return ResponseMessage.build(UUID.fromString(data.get(SerTokens.TOKEN_REQUEST).toString())) .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE))) .statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString()) .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES)) .result(result.get(SerTokens.TOKEN_DATA)) .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META)) .create(); } }
public ByteBuf writeValue(final ResponseMessage value, final ByteBufAllocator allocator, final GraphBinaryWriter context, final boolean nullable) throws SerializationException { final ResponseResult result = value.getResult(); final ResponseStatus status = value.getStatus(); return allocator.compositeBuffer(8).addComponents(true, // Version allocator.buffer(1).writeByte(0x81), // Nullable request id context.writeValue(value.getRequestId(), allocator, true), // Status code context.writeValue(status.getCode().getValue(), allocator, false), // Nullable status message context.writeValue(status.getMessage(), allocator, true), // Status attributes context.writeValue(status.getAttributes(), allocator, false), // Result meta context.writeValue(result.getMeta(), allocator, false), // Fully-qualified value context.write(result.getData(), allocator)); } }