
com.tinkerpop.gremlin.server.op.session.SessionOps Maven / Gradle / Ivy
The newest version!
package com.tinkerpop.gremlin.server.op.session;
import com.codahale.metrics.Timer;
import com.tinkerpop.gremlin.driver.Tokens;
import com.tinkerpop.gremlin.driver.message.RequestMessage;
import com.tinkerpop.gremlin.driver.message.ResponseMessage;
import com.tinkerpop.gremlin.driver.message.ResponseStatusCode;
import com.tinkerpop.gremlin.server.Context;
import com.tinkerpop.gremlin.server.GremlinServer;
import com.tinkerpop.gremlin.server.handler.StateKey;
import com.tinkerpop.gremlin.server.op.OpProcessorException;
import com.tinkerpop.gremlin.server.util.MetricManager;
import com.tinkerpop.gremlin.util.function.TriConsumer;
import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
import io.netty.channel.ChannelHandlerContext;
import org.javatuples.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.script.Bindings;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import static com.codahale.metrics.MetricRegistry.name;
/**
* Operations to be used by the {@link SessionOpProcessor}.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public final class SessionOps {
private static final Logger logger = LoggerFactory.getLogger(SessionOps.class);
/**
* Script engines are evaluated in a per session context where imports/scripts are isolated per session.
*/
private static ConcurrentHashMap sessions = new ConcurrentHashMap<>();
private static final Timer evalOpTimer = MetricManager.INSTANCE.getTimer(name(GremlinServer.class, "op", "eval"));
static {
MetricManager.INSTANCE.getGuage(sessions::size, name(GremlinServer.class, "sessions"));
}
public static void evalOp(final Context context) throws OpProcessorException {
evalOp(context, (Context ctx, RequestMessage msg, Object o) -> {
ctx.getChannelHandlerContext().write(Pair.with(msg, IteratorUtils.convertToIterator(o)));
});
}
public static void evalOp(final Context context, TriConsumer handler) {
final Timer.Context timerContext = evalOpTimer.time();
final ChannelHandlerContext ctx = context.getChannelHandlerContext();
final RequestMessage msg = context.getRequestMessage();
final Session session = getSession(context, msg);
// place the session on the channel context so that it can be used during serialization. in this way
// the serialization can occur on the same thread used to execute the gremlin within the session. this
// is important given the threadlocal nature of Graph implementation transactions.
context.getChannelHandlerContext().channel().attr(StateKey.SESSION).set(session);
final String script = (String) msg.getArgs().get(Tokens.ARGS_GREMLIN);
final Optional language = Optional.ofNullable((String) msg.getArgs().get(Tokens.ARGS_LANGUAGE));
final Bindings bindings = session.getBindings();
final Map requestBindings = Optional.ofNullable((Map) msg.getArgs().get(Tokens.ARGS_BINDINGS)).orElse(new HashMap<>());
// parameter bindings override session bindings
bindings.putAll(requestBindings);
final CompletableFuture
© 2015 - 2025 Weber Informatics LLC | Privacy Policy