/** * Used to decrease the size of a Gremlin script that triggered a "method too large" exception so that it * doesn't log a massive text string nor return a large error message. */ private RequestMessage trimMessage(final RequestMessage msg) { final RequestMessage trimmedMsg = RequestMessage.from(msg).create(); if (trimmedMsg.getArgs().containsKey(Tokens.ARGS_GREMLIN)) trimmedMsg.getArgs().put(Tokens.ARGS_GREMLIN, trimmedMsg.getArgs().get(Tokens.ARGS_GREMLIN).toString().substring(0, 1021) + "..."); return trimmedMsg; }
protected static void attemptCommit(final RequestMessage msg, final GraphManager graphManager, final boolean strict) { if (strict) { if (msg.getArgs().containsKey(Tokens.ARGS_ALIASES)) { final Map<String, String> aliases = (Map<String, String>) msg.getArgs().get(Tokens.ARGS_ALIASES); graphManager.commit(new HashSet<>(aliases.values())); } else { graphManager.commitAll(); } } else { graphManager.commitAll(); } }
protected static void attemptRollback(final RequestMessage msg, final GraphManager graphManager, final boolean strict) { if (strict) { if (msg.getArgs().containsKey(Tokens.ARGS_ALIASES)) { final Map<String, String> aliases = (Map<String, String>) msg.getArgs().get(Tokens.ARGS_ALIASES); graphManager.rollback(new HashSet<>(aliases.values())); } else { graphManager.rollbackAll(); } } else { graphManager.rollbackAll(); } } }
/** * Examines the {@link RequestMessage} and extracts the session token. The session is then either found or a new * one is created. */ protected static Session getSession(final Context context, final RequestMessage msg) { final String sessionId = (String) msg.getArgs().get(Tokens.ARGS_SESSION); logger.debug("In-session request {} for eval for session {} in thread {}", msg.getRequestId(), sessionId, Thread.currentThread().getName()); final Session session = sessions.computeIfAbsent(sessionId, k -> new Session(k, context, sessions)); session.touch(); return session; }
@Override public CompletableFuture<ResultSet> submitAsync(final RequestMessage msg) { final RequestMessage.Builder builder = RequestMessage.from(msg); // only add aliases which aren't already present. if they are present then they represent request level // overrides which should be mucked with if (!aliases.isEmpty()) { final Map original = (Map) msg.getArgs().getOrDefault(Tokens.ARGS_ALIASES, Collections.emptyMap()); aliases.forEach((k,v) -> { if (!original.containsKey(k)) builder.addArg(Tokens.ARGS_ALIASES, aliases); }); } return super.submitAsync(builder.create()); }
/** * Uses a {@link LoadBalancingStrategy} to choose the best {@link Host} and then selects the best connection * from that host's connection pool. */ @Override protected Connection chooseConnection(final RequestMessage msg) throws TimeoutException, ConnectionException { final Iterator<Host> possibleHosts; if (msg.optionalArgs(Tokens.ARGS_HOST).isPresent()) { // TODO: not sure what should be done if unavailable - select new host and re-submit traversal? final Host host = (Host) msg.getArgs().get(Tokens.ARGS_HOST); msg.getArgs().remove(Tokens.ARGS_HOST); possibleHosts = IteratorUtils.of(host); } else { possibleHosts = this.cluster.loadBalancingStrategy().select(msg); } // you can get no possible hosts in more than a few situations. perhaps the servers are just all down. // or perhaps the client is not configured properly (disables ssl when ssl is enabled on the server). if (!possibleHosts.hasNext()) throw new TimeoutException("Timed out while waiting for an available host - check the client configuration and connectivity to the server if this message persists"); final Host bestHost = possibleHosts.next(); final ConnectionPool pool = hostConnectionPools.get(bestHost); return pool.borrowConnection(cluster.connectionPoolSettings().maxWaitForConnection, TimeUnit.MILLISECONDS); }
if (msg.getArgs().containsKey(Tokens.ARGS_ALIASES)) { final Map<String, String> aliases = (Map<String, String>) msg.getArgs().get(Tokens.ARGS_ALIASES); for (Map.Entry<String,String> aliasKv : aliases.entrySet()) { boolean found = false; Optional.ofNullable((Map<String, Object>) msg.getArgs().get(Tokens.ARGS_BINDINGS)).ifPresent(bindings::putAll); return bindings; };
if (msg.getArgs().containsKey(Tokens.ARGS_ALIASES)) { final Map<String, String> aliases = (Map<String, String>) msg.getArgs().get(Tokens.ARGS_ALIASES); for (Map.Entry<String,String> aliasKv : aliases.entrySet()) { boolean found = false; Optional.ofNullable((Map<String, Object>) msg.getArgs().get(Tokens.ARGS_BINDINGS)).ifPresent(bindings::putAll); return bindings; };
@Override public ByteBuf serializeRequestAsBinary(final RequestMessage requestMessage, 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 String mimeType = mimeTypesSupported()[0]; 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)); 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("Request [%s] could not be serialized by %s.", requestMessage, AbstractGryoMessageSerializerV1d0.class.getName()), ex); throw new SerializationException(ex); } }
/** * Session based requests accept a "close" operator in addition to "eval". A close will trigger the session to be * killed and any uncommitted transaction to be rolled-back. */ @Override public Optional<ThrowingConsumer<Context>> selectOther(final RequestMessage requestMessage) throws OpProcessorException { if (requestMessage.getOp().equals(Tokens.OPS_CLOSE)) { // this must be an in-session request if (!requestMessage.optionalArgs(Tokens.ARGS_SESSION).isPresent()) { final String msg = String.format("A message with an [%s] op code requires a [%s] argument", Tokens.OPS_CLOSE, Tokens.ARGS_SESSION); throw new OpProcessorException(msg, ResponseMessage.build(requestMessage).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } final boolean force = requestMessage.<Boolean>optionalArgs(Tokens.ARGS_FORCE).orElse(false); return Optional.of(ctx -> { // validate the session is present and then remove it if it is. final Session sessionToClose = sessions.get(requestMessage.getArgs().get(Tokens.ARGS_SESSION).toString()); if (null == sessionToClose) { final String msg = String.format("There was no session named %s to close", requestMessage.getArgs().get(Tokens.ARGS_SESSION).toString()); throw new OpProcessorException(msg, ResponseMessage.build(requestMessage).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } sessionToClose.manualKill(force); // send back a confirmation of the close ctx.getChannelHandlerContext().writeAndFlush(ResponseMessage.build(requestMessage) .code(ResponseStatusCode.NO_CONTENT) .create()); }); } else { return Optional.empty(); } }
protected Optional<ThrowingConsumer<Context>> validateEvalMessage(final RequestMessage message) throws OpProcessorException { if (!message.optionalArgs(Tokens.ARGS_GREMLIN).isPresent()) { final String msg = String.format("A message with an [%s] op code requires a [%s] argument.", Tokens.OPS_EVAL, Tokens.ARGS_GREMLIN); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } if (message.optionalArgs(Tokens.ARGS_BINDINGS).isPresent()) { final Map bindings = (Map) message.getArgs().get(Tokens.ARGS_BINDINGS); if (IteratorUtils.anyMatch(bindings.keySet().iterator(), k -> null == k || !(k instanceof String))) { final String msg = String.format("The [%s] message is using one or more invalid binding keys - they must be of type String and cannot be null", Tokens.OPS_EVAL); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } final Set<String> badBindings = IteratorUtils.set(IteratorUtils.<String>filter(bindings.keySet().iterator(), INVALID_BINDINGS_KEYS::contains)); if (!badBindings.isEmpty()) { final String msg = String.format("The [%s] message supplies one or more invalid parameters key of [%s] - these are reserved names.", Tokens.OPS_EVAL, badBindings); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } // ignore control bindings that get passed in with the "#jsr223" prefix - those aren't used in compilation if (IteratorUtils.count(IteratorUtils.filter(bindings.keySet().iterator(), k -> !k.toString().startsWith("#jsr223"))) > maxParameters) { final String msg = String.format("The [%s] message contains %s bindings which is more than is allowed by the server %s configuration", Tokens.OPS_EVAL, bindings.size(), maxParameters); throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create()); } } return Optional.empty(); }
public ByteBuf writeValue(final RequestMessage value, final ByteBufAllocator allocator, final GraphBinaryWriter context) throws SerializationException { return allocator.compositeBuffer(5).addComponents(true, // Version allocator.buffer(1).writeByte(0x81), // RequestId context.writeValue(value.getRequestId(), allocator, false), // Op context.writeValue(value.getOp(), allocator, false), // Processor context.writeValue(value.getProcessor(), allocator, false), // Args context.writeValue(value.getArgs(), allocator, false)); } }
public void ser(final RequestMessage requestMessage, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException { GraphSONUtil.writeStartObject(requestMessage, jsonGenerator, typeSerializer); jsonGenerator.writeStringField(SerTokens.TOKEN_REQUEST, requestMessage.getRequestId().toString()); jsonGenerator.writeStringField(SerTokens.TOKEN_OP, requestMessage.getOp()); jsonGenerator.writeStringField(SerTokens.TOKEN_PROCESSOR, requestMessage.getProcessor()); jsonGenerator.writeObjectField(SerTokens.TOKEN_ARGS, requestMessage.getArgs()); GraphSONUtil.writeEndObject(requestMessage, jsonGenerator, typeSerializer); } }
@Override public <O extends OutputShim> void write(final KryoShim<?, O> kryo, final O output, final RequestMessage requestMessage) { kryo.writeObject(output, requestMessage.getRequestId()); output.writeString(requestMessage.getProcessor()); output.writeString(requestMessage.getOp()); kryo.writeObject(output, requestMessage.getArgs()); }
true : (Boolean) msg.getArgs().getOrDefault(Tokens.ARGS_MANAGE_TRANSACTION, false);
final Object bytecodeObj = msg.getArgs().get(Tokens.ARGS_GREMLIN); final Bytecode bytecode = bytecodeObj instanceof Bytecode ? (Bytecode) bytecodeObj : mapper.readValue(bytecodeObj.toString(), Bytecode.class); final long seto = msg.getArgs().containsKey(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT) ? ((Number) msg.getArgs().get(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT)).longValue() : context.getSettings().scriptEvaluationTimeout;
final Settings settings = context.getSettings(); final Map<String, Object> args = msg.getArgs();
/** * Used to decrease the size of a Gremlin script that triggered a "method too large" exception so that it * doesn't log a massive text string nor return a large error message. */ private RequestMessage trimMessage(final RequestMessage msg) { final RequestMessage trimmedMsg = RequestMessage.from(msg).create(); if (trimmedMsg.getArgs().containsKey(Tokens.ARGS_GREMLIN)) trimmedMsg.getArgs().put(Tokens.ARGS_GREMLIN, trimmedMsg.getArgs().get(Tokens.ARGS_GREMLIN).toString().substring(0, 1021) + "..."); return trimmedMsg; }
public void ser(final RequestMessage requestMessage, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException { GraphSONUtil.writeStartObject(requestMessage, jsonGenerator, typeSerializer); jsonGenerator.writeStringField(SerTokens.TOKEN_REQUEST, requestMessage.getRequestId().toString()); jsonGenerator.writeStringField(SerTokens.TOKEN_OP, requestMessage.getOp()); jsonGenerator.writeStringField(SerTokens.TOKEN_PROCESSOR, requestMessage.getProcessor()); jsonGenerator.writeObjectField(SerTokens.TOKEN_ARGS, requestMessage.getArgs()); GraphSONUtil.writeEndObject(requestMessage, jsonGenerator, typeSerializer); } }