////
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
////

anchor:gremlin-variants[]
[[gremlin-drivers-variants]]
= Gremlin Drivers and Variants

image::gremlin-house-of-mirrors.png[width=1024]

At this point, readers should be well familiar with the <<intro,Introduction>> to this Reference Documentation and
will likely be thinking about implementation details specific to the graph provider they have selected as well as
the programming language they intend to use. The choice of programming language could have implications to the
architecture and design of the application and the choice itself may have limits imposed upon it by the chosen graph
provider. For example, a <<connecting-rgp,Remote Gremlin Provider>> will require the selection of a driver to interact
with it. On the other hand, a graph system that is designed for embedded use, like TinkerGraph, needs the Java
Virtual Machine (JVM) environment so will require <<connecting-gremlin-server,Gremlin Server>>, if using a programming
language that is not on the JVM and will further require driver selection.

TinkerPop provides an array of drivers in different programming languages as a way to connect to a remote Gremlin
Server or Remote Gremlin Provider. Drivers allow the developer to make requests to that remote system and get back
results from the TinkerPop-enabled graphs hosted within. A driver can submit Gremlin strings and Gremlin bytecode
over this sub-protocol. Gremlin strings are written in the scripting language made available by the remote system that
the driver is connecting to (typically, Groovy-based). This connection approach is quite similar to what developers
are likely familiar with when using JDBC and SQL. While it is familiar, it is not recommended and for TinkerPop it is
considered an out-dated concept and is largely still present for the purpose of supporting applications that might
still be using that method of interaction.

The preferred approach is to use bytecode-based requests, which essentially allows the ability to craft Gremlin
directly in the programming language of choice. As Gremlin makes use of two fundamental programming constructs:
link:https://en.wikipedia.org/wiki/Function_composition[function composition] and
link:https://en.wikipedia.org/wiki/Nested_function[function nesting]. it is possible to embed the Gremlin language
in any modern programming language. It is a far more natural way to program, because it enables IDE interaction,
compile time checks, and language level checks that can help prevent errors prior to execution. The differences
between these two approaches were outlined in the <<connecting-via-drivers,Connecting Via Drivers>> Section, which
applies to Gremlin Server, but also to Remote Gremlin Providers.

In addition to the languages and drivers that TinkerPop supports, there are also third-party implementations, as well
as extensions to the Gremlin language that might be specific to a particular graph provider. That listing can be
found on the TinkerPop link:https://tinkerpop.apache.org/#graph-systems[home page]. Their description is beyond the
scope of this documentation.

TIP: When possible, it is typically best to align the version of TinkerPop used on the client with the version
supported on the server. While it is not impossible to have a different version between client and server, it may
require additional configuration and/or a deeper knowledge of that changes introduced between versions. It's simply
safer to avoid the conflict, when allowed to do so.

IMPORTANT: Gremlin-Java is the canonical representation of Gremlin and any (proper) Gremlin language variant will
emulate its structure as best as possible given the constructs of the host language. A strong correspondence between
variants ensures that the general Gremlin reference documentation is applicable to all variants and that users moving
between development languages can easily adopt the Gremlin variant for that language.

image::gremlin-variant-architecture.png[width=650,float=left]

NOTE: The information herein describes how to use the Gremlin language variants distributed
with Apache TinkerPop. For information on how to build a Gremlin language variant, please review the
link:https://tinkerpop.apache.org/docs/x.y.z/tutorials/gremlin-language-variants/[Gremlin Language Variants] tutorial.

The following sections describe each language variant and driver that is officially TinkerPop a part of the project,
provided more detailed information about usage, configuration and known limitations.

anchor:connecting-via-remotegraph[]
anchor:connecting-via-java[]
[[gremlin-java]]
== Gremlin-Java

image:gremlin-java-drawing.png[width=130,float=right] Apache TinkerPop's Gremlin-Java implements Gremlin within the
Java language and can be used by any Java Virtual Machine. Gremlin-Java is considered the canonical, reference
implementation of Gremlin and serves as the foundation by which all other Gremlin language variants should emulate.
As the Gremlin Traversal Machine that processes Gremlin queries is also written in Java, it can be used in all three
connection methods described in the <<connecting-gremlin,Connecting Gremlin>> Section.

[source,xml]
----
<dependency>
   <groupId>org.apache.tinkerpop</groupId>
   <artifactId>gremlin-core</artifactId>
   <version>x.y.z</version>
</dependency>

<!-- when using Gremlin Server or Remote Gremlin Provider a driver is required -->
<dependency>
   <groupId>org.apache.tinkerpop</groupId>
   <artifactId>gremlin-driver</artifactId>
   <version>x.y.z</version>
</dependency>
----

=== Connecting

The pattern for connecting is described in <<connecting-gremlin,Connecting Gremlin>> and it basically distills down
to creating a `GraphTraversalSource`. For <<connecting-embedded,embedded>> mode, this involves first creating a
`Graph` and then spawning the `GraphTraversalSource`:

[source,java]
----
Graph graph = ...;
GraphTraversalSource g = graph.traversal();
----

Using "g" it is then possible to start writing Gremlin. The "g" allows for the setting of many configuration options
which affect traversal execution. The <<traversal, Traversal>> Section describes some of these options and some are
only suitable with <<connecting-embedded,embedded>> style usage. For remote options however there are some added
configurations to consider and this section looks to address those.

When connecting to <<connecting-gremlin-server,Gremlin Server>> or <<connecting-rgp,Remote Gremlin Providers>>  it
is possible to configure the `DriverRemoteConnection` manually as shown in earlier examples where the host and port
are provided as follows:

[source,java]
----
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using("localhost",8182,"g"));
----

It is also possible to create it from a configuration. The most basic way to do so involves the following line of code:

[source,java]
----
GraphTraversalSource g = traversal().withRemote('conf/remote-graph.properties');
----

The `remote-graph.properties` file simply provides connection information to the `GraphTraversalSource` which is used
to configure a `RemoteConnection`. That file looks like this:

[source,text]
----
gremlin.remote.remoteConnectionClass=org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection
gremlin.remote.driver.clusterFile=conf/remote-objects.yaml
gremlin.remote.driver.sourceName=g
----

The `RemoteConnection` is an interface that provides the transport mechanism for "g" and makes it possible to for
that mechanism to be altered (typically by graph providers who have their own protocols). TinkerPop provides one such
implementation called the `DriverRemoteConnection` which enables transport over Gremlin Server protocols using the
TinkerPop driver. The driver is configured by the specified `gremlin.remote.driver.clusterFile` and the local "g" is
bound to the `GraphTraversalSource` on the remote end with `gremlin.remote.driver.sourceName` which in this case is
also "g".

There are other ways to configure the traversal using `withRemote()` as it has other overloads. It can take an
Apache Commons `Configuration` object which would have keys similar to those shown in the properties file and it
can also take a `RemoteConnection` instance directly. The latter is interesting in that it means it is possible to
programmatically construct all aspects of the `RemoteConnection`. For TinkerPop usage, that might mean directly
constructing the `DriverRemoteConnection` and the driver instance that supplies the transport mechanism. For example,
the command shown above could be re-written using programmatic construction as follows:

[source,java]
----
Cluster cluster = Cluster.open();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
----

Please consider the following example:

[gremlin-groovy]
----
g = traversal().withRemote('conf/remote-graph.properties')
g.V().elementMap()
g.close()
----

[source,java]
----
GraphTraversalSource g = traversal().withRemote("conf/remote-graph.properties");
List<Map> list = g.V().elementMap();
g.close();
----

Note the call to `close()` above. The call to `withRemote()` internally instantiates a connection via the driver that
can only be released by "closing" the `GraphTraversalSource`. It is important to take that step to release resources
created in that step.

If working with multiple remote `TraversalSource` instances it is more efficient to construct `Cluster` and `Client
objects and then re-use them.

[gremlin-groovy]
----
cluster = Cluster.open('conf/remote-objects.yaml')
client = cluster.connect()
g = traversal().withRemote(DriverRemoteConnection.using(client, "g"))
g.V().elementMap()
g.close()
client.close()
cluster.close()
----

If the `Client` instance is supplied externally, as is shown above, then it is not closed implicitly by the close of
"g".  Closing "g" will have no effect on "client" or "cluster". When supplying them externally, the `Client` and
`Cluster` objects must also be closed explicitly. It's worth noting that the close of a `Cluster` will close all
`Client` instances spawned by the `Cluster`.

IMPORTANT: Bytecode-based traversals use the `TraversalOpProcessor` in Gremlin Server which requires a cache to enable
the retrieval of side-effects (if the `Traversal` produces any). That cache can be configured (e.g. controlling
eviction times and sizing) in the Gremlin Server configuration file as described <<traversalopprocessor, here>>.

Some connection options can also be set on individual requests made through the Java driver using `with()` step
on the `TraversalSource`. For instance to set request timeout to 500 milliseconds:

[source,java]
----
GraphTraversalSource g = traversal().withRemote(conf);
List<Vertex> vertices = g.with(Tokens.ARGS_EVAL_TIMEOUT, 500L).V().out("knows").toList()
----

[[java-imports]]
=== Common Imports

There are a number of classes, functions and tokens that are typically used with Gremlin. The following imports
provide most of the common functionality required to use Gremlin:

[source,java]
----
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.IO;
import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;
import static org.apache.tinkerpop.gremlin.process.traversal.Operator.*;
import static org.apache.tinkerpop.gremlin.process.traversal.Order.*;
import static org.apache.tinkerpop.gremlin.process.traversal.P.*;
import static org.apache.tinkerpop.gremlin.process.traversal.Pop.*;
import static org.apache.tinkerpop.gremlin.process.traversal.SackFunctions.*;
import static org.apache.tinkerpop.gremlin.process.traversal.Scope.*;
import static org.apache.tinkerpop.gremlin.process.traversal.TextP.*;
import static org.apache.tinkerpop.gremlin.structure.Column.*;
import static org.apache.tinkerpop.gremlin.structure.Direction.*;
import static org.apache.tinkerpop.gremlin.structure.T.*;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
----

=== Configuration

The following table describes the various configuration options for the Gremlin Driver:

[width="100%",cols="3,10,^2",options="header"]
|=========================================================
|Key |Description |Default
|connectionPool.channelizer |The fully qualified classname of the client `Channelizer` that defines how to connect to the server. |`Channelizer.WebSocketChannelizer`
|connectionPool.enableSsl |Determines if SSL should be enabled or not. If enabled on the server then it must be enabled on the client. |false
|connectionPool.keepAliveInterval |Length of time in milliseconds to wait on an idle connection before sending a keep-alive request. Set to zero to disable this feature. |180000
|connectionPool.keyStore |The private key in JKS or PKCS#12 format. |_none_
|connectionPool.keyStorePassword |The password of the `keyStore` if it is password-protected. |_none_
|connectionPool.keyStoreType |`JKS` (Java 8 default) or `PKCS12` (Java 9+ default)|_none_
|connectionPool.maxContentLength |The maximum length in bytes that a message can be sent to the server. This number can be no greater than the setting of the same name in the server configuration. |65536
|connectionPool.maxInProcessPerConnection |The maximum number of in-flight requests that can occur on a connection. |4
|connectionPool.maxSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |16
|connectionPool.maxSize |The maximum size of a connection pool for a host. |8
|connectionPool.maxWaitForConnection |The amount of time in milliseconds to wait for a new connection before timing out. |3000
|connectionPool.maxWaitForClose |The amount of time in milliseconds to wait for pending messages to be returned from the server before closing the connection. |3000
|connectionPool.minInProcessPerConnection |The minimum number of in-flight requests that can occur on a connection. |1
|connectionPool.minSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |8
|connectionPool.minSize |The minimum size of a connection pool for a host. |2
|connectionPool.reconnectInterval |The amount of time in milliseconds to wait before trying to reconnect to a dead host. |1000
|connectionPool.resultIterationBatchSize |The override value for the size of the result batches to be returned from the server. |64
|connectionPool.sslCipherSuites |The list of JSSE ciphers to support for SSL connections. If specified, only the ciphers that are listed and supported will be enabled. If not specified, the JVM default is used.  |_none_
|connectionPool.sslEnabledProtocols |The list of SSL protocols to support for SSL connections. If specified, only the protocols that are listed and supported will be enabled. If not specified, the JVM default is used.  |_none_
|connectionPool.sslSkipCertValidation |Configures the `TrustManager` to trust all certs without any validation. Should not be used in production.|false
|connectionPool.trustStore |File location for a SSL Certificate Chain to use when SSL is enabled. If this value is not provided and SSL is enabled, the default `TrustManager` will be used. |_none_
|connectionPool.trustStorePassword |The password of the `trustStore` if it is password-protected |_none_
|connectionPool.validationRequest |A script that is used to test server connectivity. A good script to use is one that evaluates quickly and returns no data. The default simply returns an empty string, but if a graph is required by a particular provider, a good traversal might be `g.inject()`. |_''_
|hosts |The list of hosts that the driver will connect to. |localhost
|jaasEntry |Sets the `AuthProperties.Property.JAAS_ENTRY` properties for authentication to Gremlin Server. |_none_
|nioPoolSize |Size of the pool for handling request/response operations. |available processors
|password |The password to submit on requests that require authentication. |_none_
|path |The URL path to the Gremlin Server. |_/gremlin_
|port |The port of the Gremlin Server to connect to. The same port will be applied for all hosts. |8192
|protocol |Sets the `AuthProperties.Property.PROTOCOL` properties for authentication to Gremlin Server. |_none_
|serializer.className |The fully qualified class name of the `MessageSerializer` that will be used to communicate with the server. Note that the serializer configured on the client should be supported by the server configuration. |_none_
|serializer.config |A `Map` of configuration settings for the serializer. |_none_
|username |The username to submit on requests that require authentication. |_none_
|workerPoolSize |Size of the pool for handling background work. |available processors * 2
|=========================================================

Please see the link:https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/driver/Cluster.Builder.html[Cluster.Builder javadoc] to get more information on these settings.

=== Serialization

Remote systems like Gremlin Server and Remote Gremlin Providers respond to requests made in a particular serialization
format and respond by serializing results to some format to be interpreted by the client. For JVM-based languages,
there are three options for serialization: Gryo, GraphSON and GraphBinary. When using Gryo serialization (the default
serializer for the Java driver), it is important that the client and server have the same serializers configured or
else one or the other will experience serialization exceptions and fail to always communicate. Discrepancy in
serializer registration between client and server can happen fairly easily as graphs will automatically include
serializers on the server-side, thus leaving the client to be configured manually. This can be done manually as
follows:

[source,java]
----
IoRegistry registry = ...; // an IoRegistry instance exposed by a specific graph provider
GryoMapper kryo = GryoMapper.build().addRegistry(registry).create();
MessageSerializer serializer = new GryoMessageSerializerV3d0(kryo);
Cluster cluster = Cluster.build().
                          serializer(serializer).
                          create();
Client client = cluster.connect();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(client, "g"));
----

The `IoRegistry` tells the serializer what classes from the graph provider to auto-register during serialization.
Gremlin Server roughly uses this same approach when it configures its serializers, so using this same model will
ensure compatibility when making requests. Obviously, it is possible to switch to GraphSON or GraphBinary by building
the appropriate `MessageSerializer` (`GraphSONMessageSerializerV3d0` or `GraphBinaryMessageSerializerV1` respectively)
in the same way and building that into the `Cluster` object.

=== The Lambda Solution

Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
most languages do not support lambda introspection and thus, code analysis. In Gremlin-Java and with
<<connecting-embedded,embedded>> usage, lambdas can be leveraged directly:

[source,java]
----
g.V().out("knows").map(t -> t.get().value("name") + " is the friend name") <1>
g.V().out("knows").sideEffect(System.out::println) <2>
g.V().as("a").out("knows").as("b").select("b").by((Function<Vertex, Integer>) v -> v.<String>value("name").length()) <3>
----

<1> A Java `Function` is used to map a `Traverser<S>` to an object `E`.
<2> Gremlin steps that take consumer arguments can be passed Java method references.
<3> Gremlin-Java may sometimes require explicit lambda typing when types can not be automatically inferred.

When sending traversals remotely to <<connecting-gremlin-server,Gremlin Server>> or
<<connecting-rgp,Remote Gremlin Providers>>, the static methods of `Lambda` should be used and should denote a
particular JSR-223 `ScriptEngine` that is available on the remote end (typically, this is Groovy). `Lambda` creates a
string-based lambda that is  then converted into a lambda/closure/anonymous-function/etc. by the respective lambda
language's JSR-223 `ScriptEngine` implementation.

[source,java]
----
g.V().out("knows").map(Lambda.function("it.get().value('name') + ' is the friend name'"))
g.V().out("knows").sideEffect(Lambda.consumer("println it"))
g.V().as("a").out("knows").as("b").select("b").by(Lambda.<Vertex,Integer>function("it.value('name').length()"))
----

Finally, Gremlin `Bytecode` that includes lambdas requires that the traversal be processed by the
`ScriptEngine`. To avoid continued recompilation costs, it supports the encoding of bindings, which allow Gremlin
Server to cache traversals that will be reused over and over again save that some parameterization may change. Thus,
instead of translating, compiling, and then executing each submitted bytecode request, it is possible to simply
execute. To express bindings in Java, use `Bindings`.

[source,java]
----
b = Bindings.instance()
g.V(b.of('id',1)).out('created').values('name').map{t -> "name: " + t.get() }
g.V(b.of('id',4)).out('created').values('name').map{t -> "name: " + t.get() }
g.V(b.of('id',4)).out('created').values('name').getBytecode()
g.V(b.of('id',4)).out('created').values('name').getBytecode().getBindings()
cluster.close()
----

Both traversals are abstractly defined as `g.V(id).out('created').values('name').map{t -> "name: " + t.get() }` and
thus, the first submission can be cached for faster evaluation on the next submission.

WARNING: It is generally advised to avoid lambda usage. Please consider <<a-note-on-lambdas,A Note On Lambdas>> for
more information.

=== Submitting Scripts

WARNING: TinkerPop does not recommend submitting script-based requests and generally continues to support this feature
for legacy reasons and corner use cases which are still not completely addressed by the Gremlin language. Please
consider using bytecode-based requests instead when possible.

image:gremlin-java.png[width=175,float=left] TinkerPop comes equipped with a reference client for Java-based
applications.  It is referred to as `gremlin-driver`, which enables applications to send requests to Gremlin Server
and get back results.

Gremlin scripts are sent to the server from a `Client` instance.  A `Client` is created as follows:

[source,java]
----
Cluster cluster = Cluster.open();  <1>
Client client = cluster.connect(); <2>
----

<1> Opens a reference to `localhost` - note that there are many configuration options available in defining a `Cluster` object.
<2> Creates a `Client` given the configuration options of the `Cluster`.

Once a `Client` instance is ready, it is possible to issue some Gremlin Groovy scripts:

[source,java]
----
ResultSet results = client.submit("[1,2,3,4]");  <1>
results.stream().map(i -> i.get(Integer.class) * 2);       <2>

CompletableFuture<List<Result>> results = client.submit("[1,2,3,4]").all();  <3>

CompletableFuture<ResultSet> future = client.submitAsync("[1,2,3,4]"); <4>

Map<String,Object> params = new HashMap<>();
params.put("x",4);
client.submit("[1,2,3,x]", params); <5>
----

<1> Submits a script that simply returns a `List` of integers.  This method blocks until the request is written to
the server and a `ResultSet` is constructed.
<2> Even though the `ResultSet` is constructed, it does not mean that the server has sent back the results (or even
evaluated the script potentially).  The `ResultSet` is just a holder that is awaiting the results from the server.
In this case, they are streamed from the server as they arrive.
<3> Submit a script, get a `ResultSet`, then return a `CompletableFuture` that will be called when all results have been returned.
<4> Submit a script asynchronously without waiting for the request to be written to the server.
<5> Parameterized request are considered the most efficient way to send Gremlin to the server as they can be cached,
which will boost performance and reduce resources required on the server.

==== Per Request Settings

There are a number of overloads to `Client.submit()` that accept a `RequestOptions` object. The `RequestOptions`
provide a way to include options that are specific to the request made with the call to `submit()`. A good use-case for
this feature is to set a per-request override to the `scriptEvaluationTimeout` so that it only applies to the current
request.

[source,java]
----
Cluster cluster = Cluster.open();
Client client = cluster.connect();
RequestOptions options = RequestOptions.build().timeout(500).create();
List<Result> result = client.submit("g.V()", options).all().get();
----

==== Aliases

Scripts submitted to Gremlin Server automatically have the globally configured `Graph` and `TraversalSource` instances
made available to them.  Therefore, if Gremlin Server configures two `TraversalSource` instances called "g1" and "g2"
a script can simply reference them directly as:

[source,java]
----
client.submit("g1.V()")
client.submit("g2.V()")
----

While this is an acceptable way to submit scripts, it has the downside of forcing the client to encode the server-side
variable name directly into the script being sent.  If the server configuration ever changed such that "g1" became
"g100", the client-side code might have to see a significant amount of change.  Decoupling the script code from the
server configuration can be managed by the `alias` method on `Client` as follows:

[source,java]
----
Client g1Client = client.alias("g1")
Client g2Client = client.alias("g2")
g1Client.submit("g.V()")
g2Client.submit("g.V()")
----

The above code demonstrates how the `alias` method can be used such that the script need only contain a reference
to "g" and "g1" and "g2" are automatically rebound into "g" on the server-side.

[[gremlin-java-dsl]]
=== Domain Specific Languages

Creating a <<dsl,Domain Specific Language>> (DSL) in Java requires the `@GremlinDsl` Java annotation in `gremlin-core`.
This annotation should be applied to a "DSL interface" that extends `GraphTraversal.Admin`:

[source,java]
----
@GremlinDsl
public interface SocialTraversalDsl<S, E> extends GraphTraversal.Admin<S, E> {
}
----

IMPORTANT: The name of the DSL interface should be suffixed with "TraversalDSL". All characters in the interface name
before that become the "name" of the DSL.

In this interface, define the methods that the DSL will be composed of:

[source,java]
----
@GremlinDsl
public interface SocialTraversalDsl<S, E> extends GraphTraversal.Admin<S, E> {
    public default GraphTraversal<S, Vertex> knows(String personName) {
        return out("knows").hasLabel("person").has("name", personName);
    }

    public default <E2 extends Number> GraphTraversal<S, E2> youngestFriendsAge() {
        return out("knows").hasLabel("person").values("age").min();
    }

    public default GraphTraversal<S, Long> createdAtLeast(int number) {
        return outE("created").count().is(P.gte(number));
    }
}
----

IMPORTANT: Follow the TinkerPop convention of using `<S,E>` in naming generics as those conventions are taken into
account when generating the anonymous traversal class. The processor attempts to infer the appropriate type parameters
when generating the anonymous traversal class. If it cannot do it correctly, it is possible to avoid the inference by
using the `GremlinDsl.AnonymousMethod` annotation on the DSL method. It allows explicit specification of the types to
use.

The `@GremlinDsl` annotation is used by the link:https://docs.oracle.com/javase/8/docs/api/index.html?javax/annotation/processing/Processor.html[Java Annotation Processor]
to generate the boilerplate class structure required to properly use the DSL within the TinkerPop framework. These
classes can be generated and maintained by hand, but it would be time consuming, monotonous and error-prone to do so.
Typically, the Java compilation process is automatically configured to detect annotation processors on the classpath
and will automatically use them when found. If that does not happen, it may be necessary to make configuration changes
to the build to allow for the compilation process to be aware of the following `javax.annotation.processing.Processor`
implementation:

[source,java]
----
org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDslProcessor
----

The annotation processor will generate several classes for the DSL:

* `SocialTraversal` - A `Traversal` interface that extends the `SocialTraversalDsl` proxying methods to its underlying
interfaces (such as `GraphTraversal`) to instead return a `SocialTraversal`
* `DefaultSocialTraversal` - A default implementation of `SocialTraversal` (typically not used directly by the user)
* `SocialTraversalSource` - Spawns `DefaultSocialTraversal` instances.
* `__` - Spawns anonymous `DefaultSocialTraversal` instances.

Using the DSL then just involves telling the `Graph` to use it:

[source,java]
----
SocialTraversalSource social = graph.traversal(SocialTraversalSource.class);
social.V().has("name","marko").knows("josh");
----

The `SocialTraversalSource` can also be customized with DSL functions. As an additional step, include a class that
extends from `GraphTraversalSource` and with a name that is suffixed with "TraversalSourceDsl". Include in this class,
any custom methods required by the DSL:

[source,java]
----
public class SocialTraversalSourceDsl extends GraphTraversalSource {

    public SocialTraversalSourceDsl(Graph graph, TraversalStrategies traversalStrategies) {
        super(graph, traversalStrategies);
    }

    public SocialTraversalSourceDsl(Graph graph) {
        super(graph);
    }

    public GraphTraversal<Vertex, Vertex> persons(String... names) {
        GraphTraversalSource clone = this.clone();

        // Manually add a "start" step for the traversal in this case the equivalent of V(). GraphStep is marked
        // as a "start" step by passing "true" in the constructor.
        clone.getBytecode().addStep(GraphTraversal.Symbols.V);
        GraphTraversal<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(clone);
        traversal.asAdmin().addStep(new GraphStep<>(traversal.asAdmin(), Vertex.class, true));

        traversal = traversal.hasLabel("person");
        if (names.length > 0) traversal = traversal.has("name", P.within(names));

        return traversal;
    }
}
----

Then, back in the `SocialTraversal` interface, update the `GremlinDsl` annotation with the `traversalSource` argument
to point to the fully qualified class name of the `SocialTraversalSourceDsl`:

[source,java]
----
@GremlinDsl(traversalSource = "com.company.SocialTraversalSourceDsl")
public interface SocialTraversalDsl<S, E> extends GraphTraversal.Admin<S, E> {
    ...
}
----

It is then possible to use the `persons()` method to start traversals:

[source,java]
----
SocialTraversalSource social = graph.traversal(SocialTraversalSource.class);
social.persons("marko").knows("josh");
----

NOTE: Using Maven, as shown in the `gremlin-archetype-dsl` module, makes developing DSLs with the annotation processor
straightforward in that it sets up appropriate paths to the generated code automatically.

anchor:java-application-examples[]
[[gremlin-archetypes]]
=== Application Examples

The available link:https://maven.apache.org/guides/introduction/introduction-to-archetypes.html[Maven archetypes] are
as follows:

* `gremlin-archetype-dsl` - An example project that demonstrates how to build Domain Specific Languages with Gremlin
in Java.
* `gremlin-archetype-server` - An example project that demonstrates the basic structure of a
<<gremlin-server,Gremlin Server>> project, how to connect with the Gremlin Driver, and how to embed Gremlin Server in
a testing framework.
* `gremlin-archetype-tinkergraph` - A basic example of how to structure a TinkerPop project with Maven.

Use Maven to generate these example projects with a command like:

[source,shell]
$ mvn archetype:generate -DarchetypeGroupId=org.apache.tinkerpop -DarchetypeArtifactId=gremlin-archetype-server \
      -DarchetypeVersion=x.y.z -DgroupId=com.my -DartifactId=app -Dversion=0.1 -DinteractiveMode=false

This command will generate a new Maven project in a directory called "app" with a `pom.xml` specifying a `groupId` of
`com.my`. Please see the `README.asciidoc` in the root of each generated project for information on how to build and
execute it.

[[gremlin-groovy]]
== Gremlin-Groovy

image:gremlin-groovy-drawing.png[width=130,float=right] Apache TinkerPop's Gremlin-Groovy implements Gremlin within the
link:http://groovy.apache.org[Apache Groovy] language. As a JVM-based language variant, Gremlin-Groovy is backed by
Gremlin-Java constructs. Moreover, given its scripting nature, Gremlin-Groovy serves as the language of
<<gremlin-console,Gremlin Console>> and <<gremlin-server,Gremlin Server>>.

[source,groovy]
----
compile group: 'org.apache.tinkerpop', name: 'gremlin-core', version: '3.3.4'
compile group: 'org.apache.tinkerpop', name: 'gremlin-driver', version: '3.3.4'
----

[[gremlin-groovy-differences]]
=== Differences

In Groovy, `as`, `in`, and `not` are reserved words. Gremlin-Groovy does not allow these steps to be called
statically from the anonymous traversal `+__+` and therefore, must always be prefixed with `+__.+` For instance:
`+g.V().as('a').in().as('b').where(__.not(__.as('a').out().as('b')))+`

[[gremlin-python]]
== Gremlin-Python

image:gremlin-python-drawing.png[width=130,float=right] Apache TinkerPop's Gremlin-Python implements Gremlin within
the link:https://www.python.org/[Python] language and can be used on any Python virtual machine including the popular
link:https://en.wikipedia.org/wiki/CPython[CPython] machine. Python's syntax has the same constructs as Java including
"dot notation" for function chaining (`a.b.c`), round bracket function arguments (`a(b,c)`), and support for global
namespaces (`a(b())` vs `a(__.b())`). As such, anyone familiar with Gremlin-Java will immediately be able to work
with Gremlin-Python. Moreover, there are a few added constructs to Gremlin-Python that make traversals a bit more
succinct.

To install Gremlin-Python, use Python's link:https://en.wikipedia.org/wiki/Pip_(package_manager)[pip] package manager.

[source,bash]
----
pip install gremlinpython
----

=== Connecting

The pattern for connecting is described in <<connecting-gremlin,Connecting Gremlin>> and it basically distills down to
creating a `GraphTraversalSource`. A `GraphTraversalSource` is created from the anonymous `traversal()` method where
the "g" provided to the `DriverRemoteConnection` corresponds to the name of a `GraphTraversalSource` on the remote end.

[source,python]
----
g = traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
----

If you need to send additional headers in the websockets connection, you can pass an optional `headers` parameter
to the `DriverRemoteConnection` constructor.

[source,python]
----
g = traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g',headers={'Header':'Value'}))
----

[[python-imports]]
=== Common Imports

There are a number of classes, functions and tokens that are typically used with Gremlin. The following imports
provide most of the typical functionality required to use Gremlin:

[source,python]
----
from gremlin_python import statics
from gremlin_python.process.anonymous_traversal import traversal
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.traversal import T
from gremlin_python.process.traversal import Order
from gremlin_python.process.traversal import Cardinality
from gremlin_python.process.traversal import Column
from gremlin_python.process.traversal import Direction
from gremlin_python.process.traversal import Operator
from gremlin_python.process.traversal import P
from gremlin_python.process.traversal import Pop
from gremlin_python.process.traversal import Scope
from gremlin_python.process.traversal import Barrier
from gremlin_python.process.traversal import Bindings
from gremlin_python.process.traversal import WithOptions
----

These can be used analogously to how they are used in Gremlin-Java.

[gremlin-python,modern]
----
g.V().hasLabel('person').has('age',P.gt(30)).order().by('age',Order.desc).toList()
----

Moreover, by importing the `statics` of Gremlin-Python, the class prefixes can be omitted.

[source,python]
----
>>> statics.load_statics(globals())
----

With statics loaded its possible to represent the above traversal as below.

[gremlin-python,modern]
----
g.V().hasLabel('person').has('age',gt(30)).order().by('age',desc).toList()
----

Finally, statics includes all the `+__+`-methods and thus, anonymous traversals like `+__.out()+` can be expressed as below.
That is, without the `+__+`-prefix.

[gremlin-python,modern]
----
g.V().repeat(out()).times(2).name.fold().toList()
----

=== Configuration

The following table describes the various configuration options for the Gremlin-Python Driver. They
can be passed to the `Client` or `DriverRemoteConnection` instance as keyword arguments:

[width="100%",cols="3,10,^2",options="header"]
|=========================================================
|Key |Description |Default
|protocol_factory |A callable that returns an instance of `AbstractBaseProtocol`. |`gremlin_python.driver.protocol.GremlinServerWSProtocol`
|transport_factory |A callable that returns an instance of `AbstractBaseTransport`. |`gremlin_python.driver.tornado.transport.TornadoTransport`
|pool_size |The number of connections used by the pool. |4
|max_workers |Maximum number of worker threads. |Number of CPUs * 5
|message_serializer |The message serializer implementation.|`gremlin_python.driver.serializer.GraphSONMessageSerializer`
|password |The password to submit on requests that require authentication. |""
|username |The username to submit on requests that require authentication. |""
|session | A unique string-based identifier (typically a UUID) to enable a <<sessions,session-based connection>>. This is not a valid configuration for `DriverRemoteConnection`. |None
|=========================================================

=== Traversal Strategies

In order to add and remove <<traversalstrategy,traversal strategies>> from a traversal source, Gremlin-Python has a
`TraversalStrategy` class along with a collection of subclasses that mirror the standard Gremlin-Java strategies.

[gremlin-python,modern]
----
g = g.withStrategies(SubgraphStrategy(vertices=hasLabel('person'),edges=has('weight',gt(0.5))))
g.V().name.toList()
g.V().outE().elementMap().toList()
g = g.withoutStrategies(SubgraphStrategy)
g.V().name.toList()
g.V().outE().elementMap().toList()
g = g.withComputer(workers=2,vertices=has('name','marko'))
g.V().name.toList()
g.V().outE().valueMap().with_(WithOptions.tokens).toList()
----

NOTE: Many of the `TraversalStrategy` classes in Gremlin-Python are proxies to the respective strategy on
Apache TinkerPop's JVM-based Gremlin traversal machine. As such, their `apply(Traversal)` method does nothing. However,
the strategy is encoded in the Gremlin-Python bytecode and transmitted to the Gremlin traversal machine for
re-construction machine-side.

=== The Lambda Solution

Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
most languages do not support lambda introspection and thus, code analysis. In Gremlin-Python,
a link:https://docs.python.org/2/reference/expressions.html#lambda[Python lambda] should be represented as a zero-arg
callable that returns a string representation of a lambda. The default lambda language is `gremlin-python` and can be
changed via `gremlin_python.statics.default_lambda_language`. When the lambda is represented in `Bytecode` its language
is encoded such that the remote connection host can infer which translator and ultimate execution engine to use.

[gremlin-python,modern]
----
g.V().out().map(lambda: "lambda x: len(x.get().value('name'))").sum().toList()                     <1>
statics.default_lambda_language                                                                    <2>
g.V().out().map(lambda: ("it.get().value('name').length()", "gremlin-groovy")).sum().toList()      <3>
statics.default_lambda_language = 'gremlin-groovy'                                                 <4>
g.V().out().map(lambda: "it.get().value('name').length()").sum().toList()                          <5>
g.V().out().map(lambda: ("lambda x: len(x.get().value('name'))", "gremlin-python")).sum().toList() <6>
statics.default_lambda_language = 'gremlin-python'                                                 <7>
g.V().out().map(lambda: "x: len(x.get().value('name'))").sum().toList()                            <8>
----

<1> A zero-arg lambda yields a string representation of a lambda in Gremlin-Python.
<2> The default lambda language is currently Gremlin-Python.
<3> A zero-arg lambda yields a 2-tuple where the second element is the language of the lambda (Gremlin-Groovy).
<4> The default lambda language can be statically changed.
<5> A zero-arg lambda yields a string representation of a closure in Gremlin-Groovy.
<6> A zero-arg lambda yields a 2-tuple where the second element is the language of the lambda (Gremlin-Python).
<7> The default lambda language is changed back to Gremlin-Python.
<8> If the `lambda`-prefix is not provided, then it is appended automatically in order to give a more natural look to the expression.

TIP: When running into situations where Groovy cannot properly discern a method signature based on the `Lambda`
instance created, it will help to fully define the closure in the lambda expression - so rather than
`lambda: ("it.get().value("name')","gremlin-groovy")`, prefer `lambda: ("x -> x.get().value("name"),"gremlin-groovy")`.

WARNING: Jython support has been deprecated as for 3.3.10 and will be removed in 3.5.0. Gremlin-Python will at that
point default to Groovy for lambda processing and Python lambdas will not be supported.

Finally, Gremlin `Bytecode` that includes lambdas requires that the traversal be processed by the
`ScriptEngine`. To avoid continued recompilation costs, it supports the encoding of bindings, which allow a remote
engine to to cache traversals that will be reused over and over again save that some parameterization may change. Thus,
instead of translating, compiling, and then executing each submitted bytecode, it is possible to simply execute.

[gremlin-python,modern]
----
g.V(Bindings.of('id',1)).out('created').map(lambda: ("it.get().value('name').length()", "gremlin-groovy")).sum().toList()
g.V(Bindings.of('id',4)).out('created').map(lambda: ("it.get().value('name').length()", "gremlin-groovy")).sum().toList()
----

==== Native Python Lambdas

To process lambdas in Python, the `GremlinJythonScriptEngine` must be enabled on the remote end. If that remote is
Gremlin Server, then these instructions can help configuration it. As an example, the
`conf/gremlin-server-modern-py.yaml` configuration maintains a `GremlinJythonScriptEngine`.

[source,bash]
----
$ bin/gremlin-server.sh install org.apache.tinkerpop gremlin-python x.y.z
$ bin/gremlin-server.sh conf/gremlin-server-modern-py.yaml
[INFO] GremlinServer -
       \,,,/
       (o o)
---oOOo-(3)-oOOo---

[INFO] GremlinServer - Configuring Gremlin Server from conf/gremlin-server-modern-py.yaml
[INFO] MetricManager - Configured Metrics Slf4jReporter configured with interval=180000ms and loggerName=org.apache.tinkerpop.gremlin.server.Settings$Slf4jReporterMetrics
[INFO] GraphManager - Graph [graph] was successfully configured via [conf/tinkergraph-empty.properties].
[INFO] ServerGremlinExecutor - Initialized Gremlin thread pool.  Threads in pool named with pattern gremlin-*
[INFO] ScriptEngines - Loaded gremlin-jython ScriptEngine
[INFO] ScriptEngines - Loaded gremlin-python ScriptEngine
[INFO] ScriptEngines - Loaded gremlin-groovy ScriptEngine
[INFO] GremlinExecutor - Initialized gremlin-groovy ScriptEngine with scripts/generate-modern.groovy
[INFO] ServerGremlinExecutor - Initialized GremlinExecutor and configured ScriptEngines.
[INFO] ServerGremlinExecutor - A GraphTraversalSource is now bound to [g] with graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
[INFO] OpLoader - Adding the standard OpProcessor.
[INFO] OpLoader - Adding the session OpProcessor.
[INFO] OpLoader - Adding the traversal OpProcessor.
[INFO] TraversalOpProcessor - Initialized cache for TraversalOpProcessor with size 1000 and expiration time of 600000 ms
[INFO] GremlinServer - Executing start up LifeCycleHook
[INFO] Logger$info - Loading 'modern' graph data.
[WARN] AbstractChannelizer - The org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0 serialization class is deprecated.
[INFO] AbstractChannelizer - Configured application/vnd.gremlin-v3.0+gryo with org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0
[WARN] AbstractChannelizer - The org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0 serialization class is deprecated.
[INFO] AbstractChannelizer - Configured application/vnd.gremlin-v3.0+gryo-stringd with org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0
[INFO] AbstractChannelizer - Configured application/vnd.gremlin-v3.0+json with org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0
[INFO] AbstractChannelizer - Configured application/json with org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0
[INFO] AbstractChannelizer - Configured application/vnd.graphbinary-v1.0 with org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1
[INFO] AbstractChannelizer - Configured application/vnd.graphbinary-v1.0-stringd with org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1
[INFO] GremlinServer$1 - Gremlin Server configured with worker thread pool of 1, gremlin pool of 8 and boss thread pool of 1.
[INFO] GremlinServer$1 - Channel started at port 8182.
----

NOTE: The command to use `install` need only be executed once to gather `gremlin-python` dependencies into Gremlin Servers'
path. Future starts of Gremlin Server will not require that command.

WARNING: As explained throughout the documentation, when possible <<a-note-on-lambdas,avoid>> lambdas. If lambdas
must be used, then consider submitting Groovy lambdas as opposed to Python-based ones. The `GremlinGroovyScriptEngine`
is far more featured and performant than its Jython sibling and will likely yield better results.

=== Submitting Scripts

WARNING: TinkerPop does not recommend submitting script-based requests and generally continues to support this feature
for legacy reasons and corner use cases which are still not completely addressed by the Gremlin language. Please
consider using bytecode-based requests instead when possible.

The `Client` class implementation/interface is based on the Java Driver, with some restrictions. Most notably,
Gremlin-Python does not yet implement the `Cluster` class. Instead, `Client` is instantiated directly.
Usage is as follows:

[source,python]
----
from gremlin_python.driver import client <1>
client = client.Client('ws://localhost:8182/gremlin', 'g') <2>
----

<1> Import the Gremlin-Python `client` module.
<2> Opens a reference to `localhost` - note that there are various configuration options that can be passed
to the `Client` object upon instantiation as keyword arguments.

Once a `Client` instance is ready, it is possible to issue some Gremlin:

[source,python]
----
result_set = client.submit("[1,2,3,4]")  <1>
future_results = result_set.all()  <2>
results = future_results.result() <3>
assert results == [1, 2, 3, 4] <4>

future_result_set = client.submitAsync("[1,2,3,4]") <5>
result_set = future_result_set.result() <6>
result = result_set.one() <7>
assert results == [1, 2, 3, 4] <8>
assert result_set.done.done() <9>

client.close() <10>
----

<1> Submit a script that simply returns a `List` of integers.  This method blocks until the request is written to
the server and a `ResultSet` is constructed.
<2> Even though the `ResultSet` is constructed, it does not mean that the server has sent back the results (or even
evaluated the script potentially).  The `ResultSet` is just a holder that is awaiting the results from the server. The `all` method
returns a `concurrent.futures.Future` that resolves to a list when it is complete.
<3> Block until the the script is evaluated and results are sent back by the server.
<4> Verify the result.
<5> Submit the same script to the server but don't block.
<6> Wait until request is written to the server and `ResultSet` is constructed.
<7> Read a single result off the result stream.
<8> Again, verify the result.
<9> Verify that the all results have been read and stream is closed.
<10> Close client and underlying pool connections.

[[gremlin-python-dsl]]
=== Domain Specific Languages

Writing a Gremlin <<dsl,Domain Specific Language>> (DSL) in Python simply requires direct extension of several classes:

* `GraphTraversal` - which exposes the various steps used in traversal writing
* `__` - which spawns anonymous traversals from steps
* `GraphTraversalSource` - which spawns `GraphTraversal` instances

The Social DSL based on the link:https://tinkerpop.apache.org/docs/current/images/tinkerpop-modern.png["modern" toy graph]
might look like this:

[source,python]
----
class SocialTraversal(GraphTraversal):

    def knows(self, person_name):
        return self.out("knows").hasLabel("person").has("name", person_name)

    def youngestFriendsAge(self):
        return self.out("knows").hasLabel("person").values("age").min()

    def createdAtLeast(self, number):
        return self.outE("created").count().is_(P.gte(number))

class __(AnonymousTraversal):

    graph_traversal = SocialTraversal

    @classmethod
    def knows(cls, *args):
        return cls.graph_traversal(None, None, Bytecode()).knows(*args)

    @classmethod
    def youngestFriendsAge(cls, *args):
        return cls.graph_traversal(None, None, Bytecode()).youngestFriendsAge(*args)

    @classmethod
    def createdAtLeast(cls, *args):
        return cls.graph_traversal(None, None, Bytecode()).createdAtLeast(*args)


class SocialTraversalSource(GraphTraversalSource):

    def __init__(self, *args, **kwargs):
        super(SocialTraversalSource, self).__init__(*args, **kwargs)
        self.graph_traversal = SocialTraversal

    def persons(self, *args):
        traversal = self.get_graph_traversal()
        traversal.bytecode.add_step("V")
        traversal.bytecode.add_step("hasLabel", "person")

        if len(args) > 0:
            traversal.bytecode.add_step("has", "name", P.within(args))

        return traversal
----

NOTE: The `AnonymousTraversal` class above is just an alias for `+__+` as in
`+from gremlin_python.process.graph_traversal import __ as AnonymousTraversal+`

Using the DSL is straightforward and just requires that the graph instance know the `SocialTraversalSource` should
be used:

[source,python]
----
social = Graph().traversal(SocialTraversalSource).withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
social.persons("marko").knows("josh")
social.persons("marko").youngestFriendsAge()
social.persons().filter(__.createdAtLeast(2)).count()
----

=== Syntactic Sugar

Python supports meta-programming and operator overloading. There are three uses of these techniques in Gremlin-Python
that makes traversals a bit more concise.

[gremlin-python,modern]
----
g.V().both()[1:3].toList()
g.V().both()[1].toList()
g.V().both().name.toList()
----

[[gremlin-python-differences]]
=== Differences

In situations where Python reserved words and global functions overlap with standard Gremlin steps and tokens, those
bits of conflicting Gremlin get an underscore appended as a suffix:

*Steps* - <<and-step,and_()>>, <<as-step,as_()>>, <<from-step,from_()>>, <<is-step,is_()>>, <<in-step,in_()>>,
<<not-step,not_()>>, <<or-step,or_()>>, <<with-step,with_()>>

*Tokens* - <<a-note-on-scopes,Scope.global_>>

=== Limitations

* Traversals that return a `Set` *might* be coerced to a `List` in Python. In the case of Python, number equality
is different from JVM languages which produces different `Set` results when those types are in use. When this case
is detected during deserialization, the `Set` is coerced to a `List` so that traversals return consistent
results within a collection across different languages. If a `Set` is needed then convert `List` results
to `Set` manually.
* Gremlin is capable of returning `Dictionary` results that use non-hashable keys (e.g. Dictionary as a key) and Python
does not support that at a language level. Gremlin that returns such results will need to be re-written to avoid that.

=== Application Examples

The TinkerPop source code contains a simple Python script that shows a basic example of how gremlinpython works. It
can be found in GitHub link:https://github.com/apache/tinkerpop/tree/xx.yy.zz/gremlin-python/src/main/jython/example.py[here]
and is designed to work best with a running <<gremlin-server,Gremlin Server>> configured with the default
`conf/gremlin-server.yaml` file as included with the standard release packaging.

[source,shell]
----
pip install gremlinpython
pip install tornado
python example.py
----

anchor:gremlin-DotNet[]
[[gremlin-dotnet]]
== Gremlin.Net

image:gremlin-dotnet-logo.png[width=371,float=right] Apache TinkerPop's Gremlin.Net implements Gremlin within the C#
language. It targets .NET Standard and can therefore be used on different operating systems and with different .NET
frameworks, such as .NET Framework and link:https://www.microsoft.com/net/core[.NET Core]. Since the C# syntax is very
similar to that of Java, it should be very easy to switch between Gremlin-Java and Gremlin.Net. The only major
syntactical difference is that all method names in Gremlin.Net use PascalCase as opposed to camelCase in Gremlin-Java
in order to comply with .NET conventions.

[source,powershell]
nuget install Gremlin.Net

=== Connecting

The pattern for connecting is described in <<connecting-gremlin,Connecting Gremlin>> and it basically distills down to
creating a `GraphTraversalSource`. A `GraphTraversalSource` is created from the `AnonymousTraversalSource.traversal()`
method where the "g" provided to the `DriverRemoteConnection` corresponds to the name of a `GraphTraversalSource` on
the remote end.

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=connecting]
----

=== Common Imports

There are a number of classes, functions and tokens that are typically used with Gremlin. The following imports
provide most of the typical functionality required to use Gremlin:

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=commonImports]
----

=== Configuration

The connection properties for the Gremlin.Net driver can be passed to the `GremlinServer` instance as keyword arguments:

[width="100%",cols="3,10,^2",options="header"]
|=========================================================
|Key |Description |Default
|hostname |The hostname that the driver will connect to. |localhost
|port |The port on which Gremlin Server can be reached. |8182
|enableSsl |Determines if SSL should be enabled or not. If enabled on the server then it must be enabled on the client. |false
|username |The username to submit on requests that require authentication. |_none_
|password |The password to submit on requests that require authentication. |_none_
|=========================================================

==== Connection Pool

It is also possible to configure the `ConnectionPool` of the Gremlin.Net driver.
These configuration options can be set as properties
on the `ConnectionPoolSettings` instance that can be passed to the `GremlinClient`:

[width="100%",cols="3,10,^2",options="header"]
|=========================================================
|Key |Description |Default
|PoolSize |The size of the connection pool. |4
|MaxInProcessPerConnection |The maximum number of in-flight requests that can occur on a connection. |32
|=========================================================

A `NoConnectionAvailableException` is thrown if all connections have reached the `MaxInProcessPerConnection` limit
when a new request comes in.

==== Serialization

The Gremlin.Net driver uses by default GraphSON 3.0 but it is also possible to use GraphSON 2.0 which can be necessary
when the server does not support GraphSON 3.0 yet:

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=serialization]
----

=== Traversal Strategies

In order to add and remove traversal strategies from a traversal source, Gremlin.Net has an `AbstractTraversalStrategy`
class along with a collection of subclasses that mirror the standard Gremlin-Java strategies.

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=traversalStrategies]
----

NOTE: Many of the TraversalStrategy classes in Gremlin.Net are proxies to the respective strategy on Apache TinkerPop’s
JVM-based Gremlin traversal machine. As such, their `Apply(ITraversal)` method does nothing. However, the strategy is
encoded in the Gremlin.Net bytecode and transmitted to the Gremlin traversal machine for re-construction machine-side.

=== The Lambda Solution

Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
most languages do not support lambda introspection and thus, code analysis. While Gremlin.Net doesn't support C# lambdas, it
is still able to represent lambdas in other languages. When the lambda is represented in `Bytecode` its language is encoded
such that the remote connection host can infer which translator and ultimate execution engine to use.

[source,csharp]
----
g.V().Out().Map<int>(Lambda.Groovy("it.get().value('name').length()")).Sum<int>().ToList();      <1>
g.V().Out().Map<int>(Lambda.Python("lambda x: len(x.get().value('name'))")).Sum<int>().ToList(); <2>
----

<1> `Lambda.Groovy()` can be used to create a Groovy lambda. 
<2> `Lambda.Python()` can be used to create a Python lambda.

The `ILambda` interface returned by these two methods inherits interfaces like `IFunction` and `IPredicate` that mirror
their Java counterparts which makes it possible to use lambdas with Gremlin.Net for the same steps as in Gremlin-Java.

TIP: When running into situations where Groovy cannot properly discern a method signature based on the `Lambda`
instance created, it will help to fully define the closure in the lambda expression - so rather than
`Lambda.Groovy("it.get().value('name'))`, prefer `Lambda.Groovy("x -> x.get().value('name'))`.

=== Submitting Scripts

WARNING: TinkerPop does not recommend submitting script-based requests and generally continues to support this feature
for legacy reasons and corner use cases which are still not completely addressed by the Gremlin language. Please
consider using bytecode-based requests instead when possible.

Gremlin scripts are sent to the server from a `IGremlinClient` instance.  A `IGremlinClient` is created as follows:

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=submittingScripts]
----

If the remote system has authentication and SSL enabled, then the `GremlinServer` object can be configured as follows:

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=submittingScriptsWithAuthentication]
----

It is also possible to initialize the `Client` to use <<sessions,sessions>>:

[source,csharp]
----
var gremlinServer = new GremlinServer("localhost", 8182);
var client = new GremlinClient(gremlinServer, sessionId: Guid.NewGuid().ToString()))
----

[[gremlin-net-dsl]]
=== Domain Specific Languages

Developing a <<dsl,Domain Specific Language>> (DSL) for .Net is most easily implemented using
link:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods[Extension Methods]
as they don't require direct extension of classes in the TinkerPop hierarchy. Extension Method classes simply need to
be constructed for the `GraphTraversal` and the `GraphTraversalSource`. Unfortunately, anonymous traversals (spawned
from `+__+`) can't use the Extension Method approach as they do not work for static classes and static classes can't be
extended. The only option is to re-implement the methods of `+__+` as a wrapper in the anonymous traversal for the DSL
or to simply create a static class for the DSL and use the two anonymous traversals creators independently. The
following example uses the latter approach as it saves a lot of boilerplate code with the minor annoyance of having a
second static class to deal with when writing traversals rather than just calling `+__+` for everything.

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsDsl.cs[tags=dsl]
----

Note the creation of `__Social` as the Social DSL's "extension" to the available ways in which to spawn anonymous
traversals. The use of the double underscore prefix in the name is just a convention to consider using and is not a
requirement. To use the DSL, bring it into scope with the `using` directive:

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsDslTests.cs[tags=dslUsing]
----

and then it can be called from the application as follows:

[source,csharp]
----
include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsDslTests.cs[tags=dslExamples]
----

anchor:gremlin-dotnet-template[]
[[dotnet-application-examples]]
=== Application Examples

This link:https://docs.microsoft.com/dotnet/core/tools/custom-templates[dotnet template] helps getting started with
<<gremlin-dotnet,Gremlin.Net>>. It creates a new C# console project that shows how to connect to a
<<gremlin-server,Gremlin Server>> with Gremlin.Net.

You can install the template with the dotnet CLI tool:
[source,shell]
dotnet new -i Gremlin.Net.Template

After the template is installed, a new project based on this template can be installed:

[source,shell]
dotnet new gremlin

Specify the output directory for the new project which will then also be used as the name of the created project:

[source,shell]
dotnet new gremlin -o MyFirstGremlinProject

[[gremlin-javascript]]
== Gremlin-JavaScript

image:gremlin-js.png[width=130,float=right] Apache TinkerPop's Gremlin-JavaScript implements Gremlin within the
JavaScript language. It targets Node.js runtime and can be used on different operating systems on any Node.js 6 or
above. Since the JavaScript naming conventions are very similar to that of Java, it should be very easy to switch
between Gremlin-Java and Gremlin-JavaScript.

[source,bash]
npm install gremlin

=== Connecting

The pattern for connecting is described in <<connecting-gremlin,Connecting Gremlin>> and it basically distills down to
creating a `GraphTraversalSource`. A `GraphTraversalSource` is created from the `AnonymousTraversalSource.traversal()`
method where the "g" provided to the `DriverRemoteConnection` corresponds to the name of a `GraphTraversalSource` on
the remote end.

[source,javascript]
----
const g = traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
----

Gremlin-JavaScript supports plain text SASL authentication, you can set it on the connection options.

[source,javascript]
----
const authenticator = new gremlin.driver.auth.PlainTextSaslAuthenticator('myuser', 'mypassword');
const g = traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin', { authenticator });
----

Given that I/O operations in Node.js are asynchronous by default, <<terminal-steps,Terminal Steps>> return a `Promise`:

* `Traversal.toList()`: Returns a `Promise` with an `Array` as result value.
* `Traversal.next()`: Returns a `Promise` with a `{ value, done }` tuple as result value, according to the
link:https://github.com/tc39/proposal-async-iteration[async iterator proposal].
* `Traversal.iterate()`: Returns a `Promise` without a value.

For example:

[source,javascript]
----
g.V().hasLabel('person').values('name').toList()
  .then(names => console.log(names));
----

When using `async` functions it is possible to `await` the promises:

[source,javascript]
----
const names = await g.V().hasLabel('person').values('name').toList();
console.log(names);
----

=== Common Imports

There are a number of classes, functions and tokens that are typically used with Gremlin. The following imports
provide most of the typical functionality required to use Gremlin:

[source,javascript]
----
const gremlin = require('gremlin');
const traversal = gremlin.process.AnonymousTraversalSource.traversal;
const __ = gremlin.process.statics;
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const column = gremlin.process.traversal.column
const direction = gremlin.process.traversal.direction
const p = gremlin.process.traversal.P
const pick = gremlin.process.traversal.pick
const pop = gremlin.process.traversal.pop
const order = gremlin.process.traversal.order
const scope = gremlin.process.traversal.scope
const t = gremlin.process.traversal.t
----

=== Submitting Scripts

WARNING: TinkerPop does not recommend submitting script-based requests and generally continues to support this feature
for legacy reasons and corner use cases which are still not completely addressed by the Gremlin language. Please
consider using bytecode-based requests instead when possible.

It is possible to submit parametrized Gremlin scripts to the server as strings, using the `Client` class:

[source,javascript]
----
const gremlin = require('gremlin');
const client = new gremlin.driver.Client('ws://localhost:8182/gremlin', { traversalSource: 'g' });

const result1 = await client.submit('g.V(vid)', { vid: 1 });
const vertex = result1.first();

const result2 = await client.submit('g.V().hasLabel(label).tail(n)', { label: 'person', n: 3 });

// ResultSet is an iterable
for (const vertex of result2) {
  console.log(vertex.id);
}
----

It is also possible to initialize the `Client` to use <<sessions,sessions>>:

[source,javascript]
----
const client = new gremlin.driver.Client('ws://localhost:8182/gremlin', { traversalSource: 'g', 'session': 'unique-string-id' });
----

With this configuration, the state of variables within scripts are preserved between requests.

[[gremlin-javascript-dsl]]
=== Domain Specific Languages

Developing Gremlin DSLs in JavaScript largely requires extension of existing core classes with use of standalone
functions for anonymous traversal spawning. The pattern is demonstrated in the following example:

[source,javascript]
----
class SocialTraversal extends GraphTraversal {
  constructor(graph, traversalStrategies, bytecode) {
    super(graph, traversalStrategies, bytecode);
  }

  aged(age) {
    return this.has('person', 'age', age);
  }
}

class SocialTraversalSource extends GraphTraversalSource {
  constructor(graph, traversalStrategies, bytecode) {
    super(graph, traversalStrategies, bytecode, SocialTraversalSource, SocialTraversal);
  }

  person(name) {
    return this.V().has('person', 'name', name);
  }
}

function anonymous() {
  return new SocialTraversal(null, null, new Bytecode());
}

function aged(age) {
  return anonymous().aged(age);
}
----

`SocialTraversal` extends the core `GraphTraversal` class and has a three argument constructor which is immediately
proxied to the `GraphTraversal` constructor. New DSL steps are then added to this class using available steps to
construct the underlying traversal to execute as demonstrated in the `aged()` step.

The `SocialTraversal` is spawned from a `SocialTraversalSource` which is extended from `GraphTraversalSource`. Steps
added here are meant to be start steps. In the above case, the `person()` start step find a "person" vertex to begin
the traversal from.

Typically, steps that are made available on a `GraphTraversal` (i.e. SocialTraversal in this example) should also be
made available as spawns for anonymous traversals. The recommendation is that these steps be exposed in the module
as standalone functions. In the example above, the standalone `aged()` step creates an anonymous traversal through
an `anonymous()` utility function. The method for creating these standalone functions can be handled in other ways if
desired.

To use the DSL, simply initialize the `g` as follows:

[source,javascript]
----
const g = traversal(SocialTraversalSource).withRemote(connection);
g.person('marko').aged(29).values('name').toList().
  then(names => console.log(names));
----

[[gremlin-javascript-differences]]
=== Differences

In situations where Javascript reserved words and global functions overlap with standard Gremlin steps and tokens, those
bits of conflicting Gremlin get an underscore appended as a suffix:

*Steps* - <<from-step,from_()>>, <<in-step,in_()>>, <<with-step,with_()>>
