@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); final ResponseMessage msgToWrite = !serializeToString ? responseMessage : ResponseMessage.build(responseMessage.getRequestId()) .code(responseMessage.getStatus().getCode()) .statusAttributes(responseMessage.getStatus().getAttributes()) .responseMetaData(responseMessage.getResult().getMeta()) .result(serializeResultToString(responseMessage)) .statusMessage(responseMessage.getStatus().getMessage()).create(); kryo.writeObject(output, msgToWrite); 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, AbstractGryoMessageSerializerV3d0.class.getName()), ex); throw new SerializationException(ex); } }
public ResponseMessage create() { final ResponseResult responseResult = new ResponseResult(result, metaData); final ResponseStatus responseStatus = new ResponseStatus(code, statusMessage, attributes); return new ResponseMessage(requestId, responseStatus, responseResult); } }
@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()); }
@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; }
private Object serializeResultToString(final ResponseMessage msg) { if (msg.getResult() == null) return "null"; if (msg.getResult().getData() == null) return "null"; // the IteratorHandler should return a collection so keep it as such final Object o = msg.getResult().getData(); if (o instanceof Collection) { return ((Collection) o).stream().map(d -> null == d ? "null" : d.toString()).collect(Collectors.toList()); } else { return o.toString(); } } }
@Override public String serializeResponseAsString(final ResponseMessage responseMessage) throws SerializationException { try { return mapper.writeValueAsString(responseMessage); } catch (Exception ex) { logger.warn(String.format("Response [%s] could not be serialized by %s.", responseMessage.toString(), GraphSONMessageSerializerV3d0.class.getName()), ex); 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 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>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(ResponseStatusCode, Object) */ public void writeAndFlush(final ResponseMessage message) { writeAndFlush(message.getStatus().getCode(), message); }
private Object serializeResultToString(final ResponseMessage msg) { if (msg.getResult() == null) return "null"; if (msg.getResult().getData() == null) return "null"; // the IteratorHandler should return a collection so keep it as such final Object o = msg.getResult().getData(); if (o instanceof Collection) { return ((Collection) o).stream().map(d -> null == d ? "null" : d.toString()).collect(Collectors.toList()); } else { return o.toString(); } } }
@Override public ByteBuf serializeResponseAsBinary(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException { ByteBuf encodedMessage = null; try { final byte[] payload = mapper.writeValueAsBytes(responseMessage); encodedMessage = allocator.buffer(payload.length); encodedMessage.writeBytes(payload); return encodedMessage; } catch (Exception ex) { if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage); logger.warn("Response [{}] could not be serialized by {}.", responseMessage.toString(), AbstractGraphSONMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
private static Optional<Map<String, String>> validatedAliases(final RequestMessage message) throws OpProcessorException { final Optional<Map<String, String>> aliases = message.optionalArgs(Tokens.ARGS_ALIASES); if (!aliases.isPresent()) { final String msg = String.format("A message with [%s] op code requires a [%s] argument.", Tokens.OPS_BYTECODE, Tokens.ARGS_ALIASES); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } if (aliases.get().size() != 1 || !aliases.get().containsKey(Tokens.VAL_TRAVERSAL_SOURCE_ALIAS)) { final String msg = String.format("A message with [%s] op code requires the [%s] argument to be a Map containing one alias assignment named '%s'.", Tokens.OPS_BYTECODE, Tokens.ARGS_ALIASES, Tokens.VAL_TRAVERSAL_SOURCE_ALIAS); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } return aliases; }
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 logger.warn("The result [{}] in the request {} could not be serialized and returned.", o.getResult(), o.getRequestId(), ex); final String errorMessage = String.format("Error during serialization: %s", ExceptionHelper.getMessageFromExceptionOrCause(ex)); final ResponseMessage error = ResponseMessage.build(o.getRequestId()) .statusMessage(errorMessage) .statusAttributeException(ex)
@Override protected void channelRead0(final ChannelHandlerContext channelHandlerContext, final ResponseMessage response) throws Exception { try { final ResponseStatusCode statusCode = response.getStatus().getCode(); final ResultQueue queue = pending.get(response.getRequestId()); if (statusCode == ResponseStatusCode.SUCCESS || statusCode == ResponseStatusCode.PARTIAL_CONTENT) { final Object data = response.getResult().getData(); final Map<String,Object> meta = response.getResult().getMeta(); } else { queue.add(new Result(response.getResult().getData())); final Map<String,Object> attributes = response.getStatus().getAttributes(); final String stackTrace = attributes.containsKey(Tokens.STATUS_ATTRIBUTE_STACK_TRACE) ? (String) attributes.get(Tokens.STATUS_ATTRIBUTE_STACK_TRACE) : null; final List<String> exceptions = attributes.containsKey(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS) ? (List<String>) attributes.get(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS) : null; queue.markError(new ResponseException(response.getStatus().getCode(), response.getStatus().getMessage(), exceptions, stackTrace, cleanStatusAttributes(attributes))); pending.remove(response.getRequestId()).markComplete(response.getStatus().getAttributes());
@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; }
private Object serializeResultToString(final ResponseMessage msg) { if (msg.getResult() == null) return "null"; if (msg.getResult().getData() == null) return "null"; // the IteratorHandler should return a collection so keep it as such final Object o = msg.getResult().getData(); if (o instanceof Collection) { return ((Collection) o).stream().map(d -> null == d ? "null" : d.toString()).collect(Collectors.toList()); } else { return o.toString(); } } }
@Override public String serializeResponseAsString(final ResponseMessage responseMessage) throws SerializationException { try { return mapper.writeValueAsString(responseMessage); } catch (Exception ex) { logger.warn("Response [{}] could not be serialized by {}.", responseMessage.toString(), AbstractGraphSONMessageSerializerV1d0.class.getName()); throw new SerializationException(ex); } }
public ResponseMessage create() { final ResponseResult responseResult = new ResponseResult(result, metaData); final ResponseStatus responseStatus = new ResponseStatus(code, statusMessage, attributes); return new ResponseMessage(requestId, responseStatus, responseResult); } }
private static void validateTraversalSourceAlias(final Context ctx, final RequestMessage message, final Map<String, String> aliases) throws OpProcessorException { final String traversalSourceBindingForAlias = aliases.values().iterator().next(); if (!ctx.getGraphManager().getTraversalSourceNames().contains(traversalSourceBindingForAlias)) { final String msg = String.format("The traversal source [%s] for alias [%s] is not configured on the server.", traversalSourceBindingForAlias, Tokens.VAL_TRAVERSAL_SOURCE_ALIAS); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } }
if (response.getStatus().getCode() == ResponseStatusCode.AUTHENTICATE) { final Attribute<SaslClient> saslClient = ((AttributeMap) channelHandlerContext).attr(saslClientKey); final Attribute<Subject> subject = ((AttributeMap) channelHandlerContext).attr(subjectKey); final ResponseMessage clientSideError = ResponseMessage.build(response.getRequestId()) .code(ResponseStatusCode.FORBIDDEN).statusMessage(saslException.getMessage()).create(); channelHandlerContext.fireChannelRead(clientSideError); final String base64sasl = response.getStatus().getAttributes().containsKey(Tokens.ARGS_SASL) ? response.getStatus().getAttributes().get(Tokens.ARGS_SASL).toString() : BASE64_ENCODER.encodeToString((byte[]) response.getResult().getData());