////
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.
////

= TinkerPop 3.0.0

image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/gremlin-hindu.png[width=225]

*A Gremlin Rāga in 7/16 Time*

== TinkerPop 3.0.2

*Release Date: October 19, 2015*

Please see the link:https://github.com/apache/tinkerpop/blob/3.0.2-incubating/CHANGELOG.asciidoc#tinkerpop-302-release-date-october-19-2015[changelog] for a complete list of all the modifications that are part of this release.

=== Upgrading for Users

==== BulkLoaderVertexProgram (BLVP)

`BulkLoaderVertexProgram` now supports arbitrary inputs (i addition to `HadoopGraph`, which was already supported in
version 3.0.1-incubating). It can now also read from any TP3 enabled graph, like `TinkerGraph`
or `Neo4jGraph`.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-814[TINKERPOP-319],
link:https://tinkerpop.apache.org/docs/3.0.2-incubating/#bulkloadervertexprogram[Reference Documentation - BLVP]

==== TinkerGraph

TinkerGraph can now be configured to support persistence, where TinkerGraph will try to load a graph from a specified
location and calls to `close()` will save the graph data to that location.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-828[TINKERPOP-828],
link:https://tinkerpop.apache.org/docs/3.0.2-incubating/#_configuration[Reference Documentation - TinkerGraph]

==== Gremlin Driver and Server

There were a number of fixes to `gremlin-driver` that prevent protocol desynchronization when talking to Gremlin
Server.

On the Gremlin Server side, Websocket sub-protocol introduces a new "close" operation to explicitly close sessions.
Prior to this change, sessions were closed in a more passive fashion (i.e. session timeout).  There were also so
bug fixes around the protocol as it pertained to third-party drivers (e.g. python) using JSON for authentication.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-814[TINKERPOP-814],
link:https://issues.apache.org/jira/browse/TINKERPOP-816[TINKERPOP-816],
link:https://issues.apache.org/jira/browse/TINKERPOP-817[TINKERPOP-817],
link:https://issues.apache.org/jira/browse/TINKERPOP-855[TINKERPOP-855],
link:https://issues.apache.org/jira/browse/TINKERPOP-870[TINKERPOP-870],
link:https://issues.apache.org/jira/browse/TINKERPOP-877[TINKERPOP-877]

=== Upgrading for Providers

==== Graph Driver Providers

===== Gremlin Server close Operation

It is important to note that this feature of the sub-protocol applies to the `SessionOpProcessor` (i.e. for
session-based requests).  Prior to this change, there was no way to explicitly close a session.  Sessions would get
closed by the server after timeout of activity.  This new "op" gives drivers the ability to close the session
explicitly and as needed.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-849[TINKERPOP-849],
link:https://tinkerpop.apache.org/docs/3.0.2-incubating/#_opprocessors_arguments[Reference Documentation - OpProcessor]

== TinkerPop 3.0.1

*Release Date: September 2, 2015*

Please see the link:https://github.com/apache/tinkerpop/blob/3.0.1-incubating/CHANGELOG.asciidoc#tinkerpop-301-release-date-september-2-2015[changelog] for a complete list of all the modifications that are part of this release.

=== Upgrading for Users

==== Gremlin Server

Gremlin Server now supports a link:https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer[SASL-based] 
(Simple Authentication and Security Layer) authentication model and a default `SimpleAuthenticator` which implements 
the `PLAIN` SASL mechanism (i.e. plain text) to authenticate requests.  This gives Gremlin Server some basic security 
capabilities, especially when combined with its built-in SSL feature.

There have also been changes in how global variable bindings in Gremlin Server are established via initialization
scripts.  The initialization scripts now allow for a `Map` of values that can be returned from those scripts.  
That `Map` will be used to set global bindings for the server. See this 
link:https://github.com/apache/tinkerpop/blob/3.0.1-incubating/gremlin-server/scripts/generate-modern.groovy[sample script]
for an example.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-576[TINKERPOP-576]

==== Neo4j

Problems related to using `:install` to get the Neo4j plugin operating in Gremlin Console on Windows have been 
resolved.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-804[TINKERPOP-804]

=== Upgrading for Providers

==== Graph System Providers

===== GraphFactoryClass Annotation

Providers can consider the use of the new `GraphFactoryClass` annotation to specify the factory class that `GraphFactory` will use to open a new `Graph` instance. This is an optional feature and will generally help implementations that have an interface extending `Graph`.  If that is the case, then this annotation can be used in the following fashion:

[source,java]
----
@GraphFactory(MyGraphFactory.class)
public interface MyGraph extends Graph{
}
----

`MyGraphFactory` must contain the static `open` method that is normally expected by `GraphFactory`.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-778[TINKERPOP-778]

===== GraphProvider.Descriptor Annotation

There was a change that affected providers who implemented `GraphComputer` related tests such as the `ProcessComputerSuite`.  If the provider runs those tests, then edit the `GraphProvider` implementation for those suites to include the `GraphProvider.Descriptor` annotation as follows:

[source,java]
----
@GraphProvider.Descriptor(computer = GiraphGraphComputer.class)
public final class HadoopGiraphGraphProvider extends HadoopGraphProvider {

    public GraphTraversalSource traversal(final Graph graph) {
        return GraphTraversalSource.build().engine(ComputerTraversalEngine.build().computer(GiraphGraphComputer.class)).create(graph);
    }
}
----

See: link:https://issues.apache.org/jira/browse/TINKERPOP-690[TINKERPOP-690] for more information.

===== Semantics of Transaction.close()

There were some adjustments to the test suite with respect to how `Transaction.close()` was being validated.  For most providers, this will generally mean checking `OptOut` annotations for test renaming problems.  The error that occurs when running the test suite should make it apparent that a test name is incorrect in an `OptOut` if there are issues there.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-764[TINKERPOP-764] for more information.

==== Graph Driver Providers

===== Authentication

Gremlin Server now supports SASL-based authentication.  By default, Gremlin Server is not configured with
authentication turned on and authentication is not required, so existing drivers should still work without any
additional change.  Drivers should however consider implementing this feature as it is likely that many users will
want the security capabilities that it provides.

See: link:https://tinkerpop.apache.org/docs/3.0.1-incubating/#_authentication[Reference Documentation - Gremlin Server Authentication]
