APPNG-2068 fix constructor's name

APPNG-2068 fix constructor's name

== Testing
=== General
AppNG also offers support for unit- and integration testing your appNG applications. Therefore, it uses the testing capabilities of the Spring framework. See the {spring}/spring-framework-reference/htmlsingle/#testing[Reference Documentation^] for details on testing with Spring.

To enable test support, just add the following dependency to your `pom.xml`:

[source,xml]
----
<dependency>
    <groupId>org.appng</groupId>
    <artifactId>appng-testsupport</artifactId>
    <version>${appNG.version}</version>
</dependency>
----

Next, use {appng}/org/appng/testsupport/TestBase.html[org.appng.testsupport.TestBase^] as a base class for your unit tests. You can test with or without JPA support enabled.

Without JPA support:
[source,java]
----
@org.springframework.test.context.ContextConfiguration(initializers = MyTest.class)
public class EmployeesTest extends TestBase {

    public EmployeesTest() {
        super("myapp", "application-home");
    }

}
----

With JPA support:
[source,java]
----
@org.springframework.test.context.ContextConfiguration(
    locations = { TestBase.TESTCONTEXT_JPA }, initializers = MyTest.class)
public class EmployeesTest extends TestBase {

    public EmployeesTest() {
        super("myapp", "application-home");
        setEntityPackage("com.myapp.domain");
        setRepositoryBase("com.myapp.repository");
    }

}
----

=== Testing a datasource:
[source,java]
----
@org.junit.Test
public void testShowEmployees() throws ProcessingException, IOException {
	addParameter("selectedId", "1"); // <!--1-->
	initParameters(); // <!--2-->
	DataSourceCall dataSourceCall = getDataSource("employees");// <!--3-->
	CallableDataSource callableDataSource = dataSourceCall.getCallableDataSource(); // <!--4-->
	callableDataSource.perform("aPage"); // <!--5-->
	validate(callableDataSource.getDatasource());// <!--6-->
}
----
<1> adds a parameter
<2> initialize the parameters, must be called after parameters have been added
<3> retrieve a `DataSourceCall` representing the datasource by its id
<4> get a `CallableDataSource`
<5> perform the `CallableDataSource`
<6> validate the response

In step 6, a {appng}/org/appng/testsupport/validation/WritingXmlValidator.html[org.appng.testsupport.validation.WritingXmlValidator^] is used to compare the contents of a *control file* with the XML that results from marshalling the given object (in this case a `org.appng.xml.platform.Datasource`). The control file must be located at `src/test/resources/xml`. It's name is derived from the name of the test class and the name of the test method. So in this example, it would be `EmployeesTest-testShowEmployees.xml`.

NOTE: For initially creating and later updating your control files, just set `WritingXmlValidator.writeXml = true` and the control files will be written to `src/test/resources/xml`.

=== Testing an action:
[source,java]
----
@org.junit.Test
public void testCreateEmployee() throws ProcessingException, IOException {
	ActionCall action = getAction("employeeEvent", "create");// <!--1-->
	action.withParam(FORM_ACTION, "create");// <!--2-->
	Employee formBean = new Employee("John", "Doe");// <!--3-->
	CallableAction callableAction = action.getCallableAction(formBean);// <!--4-->
	FieldProcessor fieldProcessor = callableAction.perform();// <!--5-->
	validate(fieldProcessor.getMessages(), "-messages");// <!--6-->
	validate(callableAction.getAction(), "-action");// <!--7-->
}
----
<1> retrieve an `ActionCall` representing the action by its event-id and id
<2> add required parameters to the action
<3> create a form bean
<4> retrieve a `CallableAction`
<5> perform the `CallableAction` receive a `FieldProcessor`
<6> use a `validate(...)`-method that takes a suffix as a parameter, validating the messages of the `fieldProcessor`
<7> use the same validate method to validte the contents of the action

NOTE: Although you pass the `formBean` as a whole to `ActionCall.getCallableAction(formBean)`, this `formBean` is being copied internally. This copy, which is passed to the `ActionProvider<T>`, will contain only those properties that are mapped and writable in the datasource used by the action.

=== Adding custom bean definitions for testing
You can add custom bean definitons for your tests. For example, if you want to run a SQL script to initialize your test database, you could provide a file `beans-test-xml` located at `src/test/resources`.

.beans-test.xml
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="http://www.springframework.org/schema/jdbc
		http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">

	<jdbc:initialize-database enabled="true" data-source="datasource"><!--1-->
		<jdbc:script location="classpath:/sql/init-db.sql" /><!--2-->
	</jdbc:initialize-database>
</beans>
----
<1> use `<jdbc:initialize-database>` and make a reference to the built in <<app-datasource, datasource>>
<2> set the classpath location for the DDL script

In your testcase, you just need to add `beans-test.xml` to the `@ContextConfiguration`-annotation

[source,java]
----
@ContextConfiguration(locations = { TestBase.TESTCONTEXT_JPA, "classpath:/beans-test.xml" }
----

== Testing
=== General
AppNG also offers support for unit- and integration testing your appNG applications. Therefore, it uses the testing capabilities of the Spring framework. See the {spring}/spring-framework-reference/htmlsingle/#testing[Reference Documentation^] for details on testing with Spring.

To enable test support, just add the following dependency to your `pom.xml`:

[source,xml]
----
<dependency>
    <groupId>org.appng</groupId>
    <artifactId>appng-testsupport</artifactId>
    <version>${appNG.version}</version>
</dependency>
----

Next, use {appng}/org/appng/testsupport/TestBase.html[org.appng.testsupport.TestBase^] as a base class for your unit tests. You can test with or without JPA support enabled.

Without JPA support:
[source,java]
----
@org.springframework.test.context.ContextConfiguration(initializers = MyTest.class)
public class EmployeesTest extends TestBase {

    public MyTest() {
        super("myapp", "application-home");
    }

}
----

With JPA support:
[source,java]
----
@org.springframework.test.context.ContextConfiguration(
    locations = { TestBase.TESTCONTEXT_JPA }, initializers = MyTest.class)
public class EmployeesTest extends TestBase {

    public MyTest() {
        super("myapp", "application-home");
        setEntityPackage("com.myapp.domain");
        setRepositoryBase("com.myapp.repository");
    }

}
----

=== Testing a datasource:
[source,java]
----
@org.junit.Test
public void testShowEmployees() throws ProcessingException, IOException {
	addParameter("selectedId", "1"); // <!--1-->
	initParameters(); // <!--2-->
	DataSourceCall dataSourceCall = getDataSource("employees");// <!--3-->
	CallableDataSource callableDataSource = dataSourceCall.getCallableDataSource(); // <!--4-->
	callableDataSource.perform("aPage"); // <!--5-->
	validate(callableDataSource.getDatasource());// <!--6-->
}
----
<1> adds a parameter
<2> initialize the parameters, must be called after parameters have been added
<3> retrieve a `DataSourceCall` representing the datasource by its id
<4> get a `CallableDataSource`
<5> perform the `CallableDataSource`
<6> validate the response

In step 6, a {appng}/org/appng/testsupport/validation/WritingXmlValidator.html[org.appng.testsupport.validation.WritingXmlValidator^] is used to compare the contents of a *control file* with the XML that results from marshalling the given object (in this case a `org.appng.xml.platform.Datasource`). The control file must be located at `src/test/resources/xml`. It's name is derived from the name of the test class and the name of the test method. So in this example, it would be `EmployeesTest-testShowEmployees.xml`.

NOTE: For initially creating and later updating your control files, just set `WritingXmlValidator.writeXml = true` and the control files will be written to `src/test/resources/xml`.

=== Testing an action:
[source,java]
----
@org.junit.Test
public void testCreateEmployee() throws ProcessingException, IOException {
	ActionCall action = getAction("employeeEvent", "create");// <!--1-->
	action.withParam(FORM_ACTION, "create");// <!--2-->
	Employee formBean = new Employee("John", "Doe");// <!--3-->
	CallableAction callableAction = action.getCallableAction(formBean);// <!--4-->
	FieldProcessor fieldProcessor = callableAction.perform();// <!--5-->
	validate(fieldProcessor.getMessages(), "-messages");// <!--6-->
	validate(callableAction.getAction(), "-action");// <!--7-->
}
----
<1> retrieve an `ActionCall` representing the action by its event-id and id
<2> add required parameters to the action
<3> create a form bean
<4> retrieve a `CallableAction`
<5> perform the `CallableAction` receive a `FieldProcessor`
<6> use a `validate(...)`-method that takes a suffix as a parameter, validating the messages of the `fieldProcessor`
<7> use the same validate method to validte the contents of the action

NOTE: Although you pass the `formBean` as a whole to `ActionCall.getCallableAction(formBean)`, this `formBean` is being copied internally. This copy, which is passed to the `ActionProvider<T>`, will contain only those properties that are mapped and writable in the datasource used by the action.

=== Adding custom bean definitions for testing
You can add custom bean definitons for your tests. For example, if you want to run a SQL script to initialize your test database, you could provide a file `beans-test-xml` located at `src/test/resources`.

.beans-test.xml
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="http://www.springframework.org/schema/jdbc
		http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">

	<jdbc:initialize-database enabled="true" data-source="datasource"><!--1-->
		<jdbc:script location="classpath:/sql/init-db.sql" /><!--2-->
	</jdbc:initialize-database>
</beans>
----
<1> use `<jdbc:initialize-database>` and make a reference to the built in <<app-datasource, datasource>>
<2> set the classpath location for the DDL script

In your testcase, you just need to add `beans-test.xml` to the `@ContextConfiguration`-annotation

[source,java]
----
@ContextConfiguration(locations = { TestBase.TESTCONTEXT_JPA, "classpath:/beans-test.xml" }
----


Updated javadocs

Updated javadocs

= Cheatsheets

[[ActionKnotOptions]]
== ActionKnotOptions

++++
 Describes an Action Knot configuration options
++++
'''

[cols=">25%,^25%,50%"]
[frame="topbot"]
|===
^|Name | Type ^| Description
|[[adapters]]`adapters`|`Array of link:dataobjects.html#ActionSettings[ActionSettings]`|
+++
Sets the adapters that will be responsible for communicating with external services in order to
 process the request.
+++
|[[address]]`address`|`String`|
+++
Sets the EB address of the verticle
+++
|[[deliveryOptions]]`deliveryOptions`|`link:dataobjects.html#DeliveryOptions[DeliveryOptions]`|
+++
Sets the Vert.x Event Bus Delivery Options
+++
|[[formIdentifierName]]`formIdentifierName`|`String`|
+++
Sets the name of the hidden input tag which is added by Action Knot.
+++
|===

[[ActionSettings]]
== ActionSettings

++++
 Describes a physical details of HTTP service endpoint that consumes form submitions
 from AdapterServiceKnot.
++++
'''

[cols=">25%,^25%,50%"]
[frame="topbot"]
|===
^|Name | Type ^| Description
|[[address]]`address`|`String`|
+++
Sets the EB address of the service adapter
+++
|[[allowedRequestHeaders]]`allowedRequestHeaders`|`Array of String`|
+++
Sets list of HTTP client request headers that are allowed to be passed to Adapter. No request headers are allowed if not set.
+++
|[[allowedResponseHeaders]]`allowedResponseHeaders`|`Array of String`|
+++
Sets list of HTTP response headers that are allowed to be sent in a client response. No response headers are allowed if not set.
+++
|[[name]]`name`|`String`|
+++
Set the name of the service the will be used on html snippet level.
+++
|[[params]]`params`|`Json object`|
+++
Set the service parameters to be consumed by the adapter.
+++
|===

= Cheatsheets

[[ActionKnotOptions]]
== ActionKnotOptions

++++
 Describes an Action Knot configuration options
++++
'''

[cols=">25%,^25%,50%"]
[frame="topbot"]
|===
^|Name | Type ^| Description
|[[adapters]]`adapters`|`Array of link:dataobjects.html#ActionSettings[ActionSettings]`|
+++

Configures the available ActionAdapters to be used by the knot
Sets the adapters that will be responsible for communicating with external services in order to
 process the request.
+++
|[[address]]`address`|`String`|
+++
Sets the EB address of the verticle
+++
|[[deliveryOptions]]`deliveryOptions`|`link:dataobjects.html#DeliveryOptions[DeliveryOptions]`|
+++
Sets the Vert.x Event Bus Delivery Options
Sets the value of the 'name' attribute of the <form> tag.
 If not set, a default value is _frmId
Sets the name of the hidden input tag which is added by Action Knot.
+++
|===

[[ActionSettings]]
== ActionSettings

++++
 Describes a physical details of HTTP service endpoint that consumes form submitions
 from AdapterServiceKnot.
++++
'''

[cols=">25%,^25%,50%"]
[frame="topbot"]
|===
^|Name | Type ^| Description
|[[address]]`address`|`String`|
+++
Sets the EB address of the service adapter
+++
|[[allowedRequestHeaders]]`allowedRequestHeaders`|`Array of String`|
+++
Sets list of HTTP client request headers that are allowed to be passed to Adapter. No request headers are allowed if not set.
+++
|[[allowedResponseHeaders]]`allowedResponseHeaders`|`Array of String`|
+++
Sets list of HTTP response headers that are allowed to be sent in a client response. No response headers are allowed if not set.
+++
|[[name]]`name`|`String`|
+++
Set the name of the service the will be used on html snippet level.
+++
|[[params]]`params`|`Json object`|
+++
Set the service parameters to be consumed by the adapter.
+++
|===


Added TINKERPOP-1417 to the future dev doc CTR

////
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.
////
image::apache-tinkerpop-logo.png[width=500,link="http://tinkerpop.apache.org"]

*4.0.0*

:toc-position: left

= TinkerPop 4.x Design Ideas

TinkerPop 4.x is not a version considered on the immediate horizon, but there are often points in the day to day
development of TinkerPop 3.x where there are changes of importance, novelty and usefulness that are so big that they
could only be implemented under a major new version. This document is meant to track these concepts as they develop,
so that at some point in the future they can be referenced in a single place.

There is no particular layout or style to this document. Simple bullet points, open questions posed as single
sentences, or fully structured document headers and content are all acceptable. The main point is to capture ideas
for future consideration when 4.x becomes the agenda of the day for The TinkerPop.

image:tp4-think.png[]

== The Main Features

TinkerPop4 should focus on the most successful aspects of TinkerPop3 and it should avoid the traps realized in TinkerPop3.
These items include:

* The concept of Gremlin as both a virtual machine and language.
** A standard bytecode specification should be provided.
** A standard machine architecture should be provided.
* The concept of Gremlin language variants.
** It should be easy to create Gremlin variants in every major programming language.
** A standard template should be followed for all languages.
** Apache TinkerPop should provide variants in all major programming languges.
* The concept of `Traversal` as the sole means of interacting with the graph.
** The role of Blueprints should be significantly reduced.
** The role of Gremlin should be significantly increased.

== Hiding Blueprints

Originally from the link:https://lists.apache.org/thread.html/b4d80072ad36849b4e9cd3308f87115660574e3e7a4abb7ee68e959b@%3Cdev.tinkerpop.apache.org%3E[mailing list]:

Throughout our documentation we show uses of the “Blueprints API” (i.e. Graph/Vertex/Edge/etc. classes & methods) as
well as the use of the Traversal API (i.e. Gremlin).

Enabling users to have two ways of interacting with the graph system has its problems:

1. The DetachedXXX problem — how much data should a returned vertex/edge/etc. have associated with it?
2. `graph.addVertex()` and `g.addV()` — which should I use? The first is faster but is not recommended.
3. `SubgraphStrategy` leaking — I get subgraphs with Gremlin, but can then directly interact with the vertex objects to see more than I should.
4. `VertexProgram` model — I write traversals with Traversal API, but then develop VertexPrograms with the Blueprints API. That’s weird.
5. GremlinServer returning fat objects — Serializers are created property-rich vertices and edges. The awkward HaltedTraversalStrategy solution.
6. … various permutations of these source problems.

In TinkerPop4 the solution might be as follows:

There should be two “Graph APIs.”

1. Provider Graph API: This is the current Blueprints API with `Graph.addVertex()`, `Vertex.edges()`, `Edge.inVertex()`, etc.
2. User Graph API: This is a ReferenceXXX API.

The first API is well known, but the second bears further discussion. `ReferenceGraph` is simply a reference/dummy/proxy
to the provider Graph API. `ReferenceGraph` has the following API:

* `ReferenceGraph.open()`
* `ReferenceGraph.close()`
* `ReferenceGraph.tx()` // assuming we like the current transaction model (??)
* `ReferenceGraph.traversal()`

That is it. What does this entail? Assume the following traversal:

[source,java]
----
g = ReferenceGraph.open(config).traversal()
g.V(1).out(‘knows’)
----

`ReferenceGraph` is almost like a `RemoteGraph` (`RemoteStrategy`) in that it makes a connection (remote or inter-JVM)
to the provider Graph API. When `g.V(1).out(‘knows’)` executes, it is really sending the bytecode to the provider Graph
for execution (as specified by the config of `ReferenceGraph.open()`). Thus, once it hits the provider's graph,
`ProviderVertex`, `ProviderEdge`, etc. are the objects being processed. However, what the traversal’s `Iterator<Vertex>`
returns is `ReferenceVertex`! That is, it never returns `ProviderVertex`. In this way, regardless if the user is
going “over the wire” or within the same JVM or against a different provider’s graph database or from
Gremlin-Python/C#/etc., all the vertices are simply ‘reference vertices’ (id + label). This makes it so that users
never interact with the graph element objects themselves directly. They can ONLY interact with the graph via
traversals! At most they can `ReferenceVertex.id()` and `ReferenceVertex.label()`. Thats it, — no mutations, not
walking edges, nada! And moreover, since ReferenceXXX has enough information to re-attach to the source graph, they
can always do the following to get more information:

[source,java]
----
v = g.V(1).out(‘knows’).next()
g.V(v).values(‘name’)
----

This split into two Graph APIs will enables us to make a hard boundary between what the provider (vendor) needs to
implement and what the user (developer) gets to access.

=== Comments

There is a question mark next to `ReferenceGraph.tx()` - Transactions are a bit of an open question for future versions
of TinkerPop and likely deserve their own section in this document. The model used for last three version of TinkerPop
now is rooted in the Neo4j approach to transactions and is often more trouble than it should be for us and providers.
Distributed transactions are a challenge and don't apply to every provider. Transactions are further complicated by
GLVs. The idea of local subgraphs for mutations and transaction management might be good but that goes against having
just `ReferenceGraph`.

== Gremlin Language Subset

On link:https://issues.apache.org/jira/browse/TINKERPOP-1417[TINKERPOP-1417], it was suggested that we "Create a
Gremlin language subset that is easy to implement on any VM". Implementing the Gremlin VM in another language is
pretty straightforward. However, its a lot of code.. all these steps implementations. One thing we could do to make
it easy for database providers not on the JVM (e.g. ArangoDB and C) is to create "Gremlito" (Gremlin--). This language
subset wouldn't support side-effects, sacks, match, etc. Basically, just simple traversal steps and reducing barrier
terminals.

Thus:

* out, in, both, values, outE, inV, id, label, etc.
* repeat
* select, project
* where, has, limit, range, is, dedup
* path, simplePath, cyclicPath
* groupCount, sum, group, count, max, min, etc. (reducing barriers)

=== Comments

This has an interesting potential impact on GLVs because "Little Gremlin" could be implemented within them for
client-side traversals over remote subgraphs, where the subgraph is like a remote transaction. All graph mutations
essentially build a subgraph which is merged into the primary graph. That subgraph is effectively the "transaction".
Build it locally then submit it remotely and have the server sort out the merging. It's perhaps the most natural way
to load data. With "Gremlinito" you then get the added power of being able to traverse a local subgraph.


Added some more notes to release documents.

////
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.
////
Release Process
===============

This document describes the steps required to release a version of TinkerPop.  The release is handled by a "release
manager" (a committer fulfills this role), who ensures that the steps in this document are executed. The process is
multi-phased and can therefore take several weeks to complete given the time needed for Apache voting and community
feedback.  Once a release point has been identified, the following phases represent the flow of "release":

* Pre-flight check.
* Optionally, produce a release candidate for community feedback.
* Submit the official release for PMC vote.
* Release and promote.

NOTE: It might be helpful to use this document as generated from the currently release as opposed to one generate
from a previous version or from recent `SNAPSHOT`. When using one generated for release, all the "versions" in the
commands end up being set to the version that is being released, making cut and paste of those commands less labor
intensive and error prone.

Pre-flight Check
----------------

The "pre-flight check" is a list of things performed by the release manager during the weeks leading up to a scheduled
day to release.  These checks will help to ensure that that release day goes smoothly by identifying problems up early
and communicating with other members of the community.

. Fourteen days before release, issue an email to the dev mailing list to remind the community of the pending release.
.. Note any important issues open in JIRA in that post.
.. Request review and update of the "upgrade documentation" and CHANGELOG.
. Seven days before release, announce the code freeze on the dev mailing list to remind the community that the branch
under release is protected. Tweaks to documentation and other odds and ends related to release are still allowed
during this period.
. At some point during the week:
.. Run the full integration test suite: `mvn clean install -DskipIntegrationTests=false -DincludeNeo4j`
.. Deploy a final SNAPSHOT to the snapshot repository.
.. Review LICENSE and NOTICE files to make sure that no <<dependencies,changes are needed>>.
.. Review javadoc filters on the "Core API" docs to be sure nothing needs to change.
.. Review JIRA tickets in the release and ensure that:
... All tickets categorized by having a "Component" assigned.
... All tickets are either of type "Bug" or "Enhancement".
... All tickets where work was completed are "Closed"
.... Search for "closed the pull request" in comments for hints on possible tickets that were left open by mistake).
.... Look for tickets marked as "Resolved" (some users might not have rights to mark as "Closed" - convert these to "Closed".
... All tickets not marked "Fixed", "Done", or "Implemented" for their Resolution should not have a Fix Version
assigned (use common sense when reviewing these tickets before removing the Fix Version as it is possible the incorrect
Resolution may have been assigned).
. When all documentation changes are in place, use `bin/publish-docs.sh` to deploy a final `SNAPSHOT` representation
of the docs and thus validate that there are no issues with the documentation generation process. Request review
of the published documentation on the dev mailing list.

Release Candidate
-----------------

A release candidate is an unofficial release that is represented by a tagged version in the Git repository.  It is
offered in cases where there is significant change in a particular version and the potential for upgrades and problems
might be high.

. `mvn clean install -DincludeNeo4j`
.. `mvn verify -DskipIntegrationTests=false -DincludeNeo4j`
.. `mvn verify -DskipPerformanceTests=false`
. `bin/publish-docs.sh <username>` - note that under a release candidate the documentation is published as SNAPSHOT
. `mvn versions:set -DnewVersion=xx.yy.zz -DgenerateBackupPoms=false` to update the project files to reference a non-SNAPSHOT version
. `git diff` and review the updated files (expect all `pom.xml` files and this README)
. `git commit -a -m "TinkerPop xx.yy.zz release"` and `git push`
. `git tag -a -m "TinkerPop xx.yy.zz release" xx.yy.zz` and `git push --tags`
. `mvn clean install`
. `mvn versions:set -DnewVersion=xx.yy.zz-SNAPSHOT -DgenerateBackupPoms=false` to go back to SNAPSHOT
. `git commit -a -m "Returned to xx.yy.zz-SNAPSHOT"` and `git push`
. Announce the release candidate to `dev` mailing list and await feedback
. Repeat as required or proceed to the next phase

PMC Vote
--------

A positive vote for a particular release from the TinkerPop PMC is required to move to the following phase.

. By this point, the testing performed during the code freeze should have validated the release.  If however there
are additional tests to perform that the release manager feels are relevant, they should be performed now. In other
words, there is no need to rebuild the `SNAPSHOT` yet another time unless there are circumstances that would call its
validity into question.
. Update `CHANGELOG.asciidoc`:
.. Update the release date
.. Generate the JIRA release notes report for the current version and append them to the `CHANGELOG.asciidoc`.
... Use an "advanced" search to filter out JIRA issues already released on other versions. For example: `fixVersion
= 3.2.0 AND fixVersion not in (3.1.3, 3.1.2, 3.1.1, 3.1.0)`.
... Consider use of an "Excel" export to organize, sort (by type and then id) and prepare the JIRA tickets to be pasted to `CHANGELOG.asciidoc`
... Be sure to include a link to other versions in the `CHANGELOG.asciidoc` that were previously released while the
current release was under development as this new release will have those changes included within it. Please see
3.2.1 for an example.
.. Organize "breaking" changes to be clearly marked (use JIRA and the "breaking" label to identify those)
. Update "upgrade documentation":
.. Update the release date.
.. Update the link to CHANGELOG.asciidoc
. `mvn versions:set -DnewVersion=xx.yy.zz -DgenerateBackupPoms=false` to update project files to reference the non-SNAPSHOT version
. `git diff` and review the updated files (expect all `pom.xml` files and this README)
. `git commit -a -m "TinkerPop xx.yy.zz release"` and push
. `mvn clean install` - need to build first so that the right version of the console is used with `bin/publish-docs.sh`
. `bin/process-docs.sh` and validate the generated documentation locally (don't rely on "SUCCESS" - scroll up through logs to ensure there were no errors and view the HTML directly)
. `bin/publish-docs.sh <username>` - Note that this step requires no additional processing as the previous step.
handled document generation and this step now merely needs to upload what was generated.
. `mvn deploy -Papache-release -DcreateChecksum=true -DskipTests` - deploy signed artifacts with checksums to link:https://repository.apache.org/[Apache Nexus]. Review (artifacts versions, file sizes, anything that might be out of place - request another committer to review as well).
. Review generated artifacts to be sure they have both javadocs and asciidocs present then "close" the repo - if the repo is left open it will be automatically dropped after five days and closing the repo will allow it to stay available for a full ninety days which is more than enough time to complete a vote. Do NOT "release" the repository at this time.
. Upload artifacts to `https://dist.apache.org/repos/dist/dev//tinkerpop` for `[VOTE]` review.
.. `svn co --depth empty https://dist.apache.org/repos/dist/dev//tinkerpop/ dev` and `mkdir dev/xx.yy.zz`
.. `cp ~/.m2/repository/org/apache/tinkerpop/gremlin-console/xx.yy.zz/gremlin-console-xx.yy.zz-distribution.zip* dev/xx.yy.zz`
.. `cp ~/.m2/repository/org/apache/tinkerpop/gremlin-server/xx.yy.zz/gremlin-server-xx.yy.zz-distribution.zip* dev/xx.yy.zz`
.. `cp ~/.m2/repository/org/apache/tinkerpop/tinkerpop/xx.yy.zz/tinkerpop-xx.yy.zz-source-release.zip* dev/xx.yy.zz`
.. `cd dev/xx.yy.zz`
.. pass:[ls * | xargs -n1 -I {} echo "mv apache-{} {}" | sed -e 's/distribution/bin/' -e 's/source-release/src/' -e s'/^\(.*\) \(.*\) \(.*\)$/\1 \3 \2/' | /bin/bash]
.. `cd ..; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"`
. Execute `bin/validate-distribution.sh` and any other relevant testing.
. `git tag -a -m "TinkerPop xx.yy.zz release" xx.yy.zz` and `git push --tags`
. Perform JIRA administration tasks:
.. "Release" the current version and set the "release date"
.. If there is to be a follow on release in the current line of code, create that new version specifying the "start date"
. Prepare Git administration tasks. Note that this work can be performed at the release manager's discretion. It may be wise to wait until a successful VOTE is eminent before reopening development. Apply the following steps as needed per release branch:
.. Make the appropriate branching changes as required by the release and bump the version to `SNAPSHOT` with
`mvn versions:set -DnewVersion=xx.yy.zz-SNAPSHOT -DgenerateBackupPoms=false`.
.. `mvn clean install -DskipTests` - need to build first so that the right version of the console is used with `bin/publish-docs.sh`
.. `mvn deploy` - deploy the new `SNAPSHOT`
.. `bin/process-docs.sh` and validate the generated `SNAPSHOT` documentation locally
.. `bin/publish-docs.sh <username>` to publish the `SNAPSHOT` docs which enables the README to work properly.
.. Update the links in the `README.asciidoc` to point at the `SNAPSHOT` version.
.. Commit and push the `SNAPSHOT` changes to git
.. Send email to advise that code freeze is lifted.
.. Generate a list of dead branches that will be automatically deleted and post them as a DISCUSS thread for review, then once consensus is reached removed those branches.
. Submit for `[VOTE]` at `dev@tinkerpop.apache.org` (see email template below)
. *Wait for vote acceptance* (72 hours)

Release & Promote
-----------------

. Login to link:https://repository.apache.org/[Apache Nexus] and release the previously closed repository.
. `svn co --depth empty https://dist.apache.org/repos/dist/dev/tinkerpop dev; svn up dev/xx.yy.zz`
. `svn co --depth empty https://dist.apache.org/repos/dist/release/tinkerpop release; mkdir release/xx.yy.zz`
. Copy release files from `dev/xx.yy.zz` to `release/xx.yy.zz`.
. `cd release; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"`
. Update homepage with references to latest distribution and to other internal links elsewhere on the page.
. Wait for Apache Central to sync the jars and src (link:http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/[http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/]).
. If there are releases present in SVN that represents lines of code that are no longer under development, then remove those releases. In other words, if `3.2.0` is present and `3.2.1` is released then remove `3.2.0`.  However, if `3.1.3` is present and that line of code is still under potential development, it may stay.
. Announce release on `dev@`/`gremlin-users@` mailing lists and tweet from `@apachetinkerpop`

Email Templates
---------------

Release VOTE
~~~~~~~~~~~~

```
Subject: [VOTE] TinkerPop xx.yy.zz Release

Hello,

We are happy to announce that TinkerPop xx.yy.zz is ready for release.

The release artifacts can be found at this location:
	https://dist.apache.org/repos/dist/dev/tinkerpop/xx.yy.zz/

The source distribution is provided by:
	apache-tinkerpop-xx.yy.zz-src.zip

Two binary distributions are provided for user convenience:
	apache-gremlin-console-xx.yy.zz-bin.zip
	apache-gremlin-server-xx.yy.zz-bin.zip

The GPG key used to sign the release artifacts is available at:
    https://dist.apache.org/repos/dist/dev/tinkerpop/KEYS

The online docs can be found here:
	http://tinkerpop.apache.org/docs/xx.yy.zz/reference/ (user docs)
	http://tinkerpop.apache.org/docs/xx.yy.zz/upgrade/ (upgrade docs)
	http://tinkerpop.apache.org/javadocs/xx.yy.zz/core/ (core javadoc)
	http://tinkerpop.apache.org/javadocs/xx.yy.zz/full/ (full javadoc)

The tag in Apache Git can be found here:
	https://git-wip-us.apache.org/repos/asf?p=tinkerpop.git;XXXXXXXXXXXXXXXXXX

The release notes are available here:
	https://github.com/apache/tinkerpop/blob/master/CHANGELOG.asciidoc#XXXXXXXXXXXXXXXXXX

The [VOTE] will be open for the next 72 hours --- closing <DayOfTheWeek> (<Month> <Day> <Year>) at <Time> <TimeZone>.

My vote is +1.

Thank you very much,
<TinkerPop Committer Name>
```

Dev Release RESULT VOTE
~~~~~~~~~~~~~~~~~~~~~~~

```
Subject: [RESULT][VOTE] TinkerPop xx.yy.zz Release

This vote is now closed with a total of X +1s, no +0s and no -1s. The results are:

BINDING VOTES:

+1  (X -- list of voters)
0   (0)
-1  (0)

NON-BINDING VOTES:

+1 (X -- list of voters)
0  (0)
-1 (0)

Thank you very much,
<TinkerPop Committer Name>
```

General Release Announcement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Subject: TinkerPop xx.yy.zz Released: [name of release line]

Hello,

TinkerPop xx.yy.zz has just been released. [some text to introduce the release - e.g. whether or not
there is breaking change, an important game-changing feature or two, etc.]

The release artifacts can be found at this location:

https://www.apache.org/dyn/closer.lua/tinkerpop/xx.yy.zz/apache-gremlin-console-xx.yy.zz-bin.zip
https://www.apache.org/dyn/closer.lua/tinkerpop/xx.yy.zz/apache-gremlin-server-xx.yy.zz-bin.zip

The online docs can be found here:

http://tinkerpop.apache.org/docs/xx.yy.zz/reference/ (user docs)
http://tinkerpop.apache.org/docs/xx.yy.zz/upgrade.html#XXXXXXXXXXXXXXXXXX (upgrade docs)
http://tinkerpop.apache.org/javadocs/xx.yy.zz/core/ (core javadoc)
http://tinkerpop.apache.org/javadocs/xx.yy.zz/full/ (full javadoc)
http://tinkerpop.apache.org/docs/xx.yy.zz/some-new-content/ (some new content) [NEW!]

The release notes are available here:

https://github.com/apache/tinkerpop/blob/xx.yy.zz/CHANGELOG.asciidoc#XXXXXXXXXXXXXXXXXX

The Central Maven repo has sync'd as well:

https://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/xx.yy.zz/

[include the release line logo]

////
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.
////
Release Process
===============

This document describes the steps required to release a version of TinkerPop.  The release is handled by a "release
manager" (a committer fulfills this role), who ensures that the steps in this document are executed. The process is
multi-phased and can therefore take several weeks to complete given the time needed for Apache voting and community
feedback.  Once a release point has been identified, the following phases represent the flow of "release":

* Pre-flight check.
* Optionally, produce a release candidate for community feedback.
* Submit the official release for PMC vote.
* Release and promote.

NOTE: It might be helpful to use this document as generated from the currently release as opposed to one generate
from a previous version or from recent `SNAPSHOT`. When using one generated for release, all the "versions" in the
commands end up being set to the version that is being released, making cut and paste of those commands less labor
intensive and error prone.

Pre-flight Check
----------------

The "pre-flight check" is a list of things performed by the release manager during the weeks leading up to a scheduled
day to release.  These checks will help to ensure that that release day goes smoothly by identifying problems up early
and communicating with other members of the community.

. Fourteen days before release, issue an email to the dev mailing list to remind the community of the pending release.
.. Note any important issues open in JIRA in that post.
.. Request review and update of the "upgrade documentation" and CHANGELOG.
. Seven days before release, announce the code freeze on the dev mailing list to remind the community that the branch
under release is protected. Tweaks to documentation and other odds and ends related to release are still allowed
during this period.
. At some point during the week:
.. Run the full integration test suite: `mvn clean install -DskipIntegrationTests=false -DincludeNeo4j`
.. Deploy a final SNAPSHOT to the snapshot repository.
.. Review LICENSE and NOTICE files to make sure that no <<dependencies,changes are needed>>.
.. Review javadoc filters on the "Core API" docs to be sure nothing needs to change.
.. Review JIRA tickets in the release and ensure that:
... All tickets categorized by having a "Component" assigned.
... All tickets are either of type "Bug" or "Enhancement".
... All tickets where work was completed are "Closed"
.... Search for "closed the pull request" in comments for hints on possible tickets that were left open by mistake).
.... Look for tickets marked as "Resolved" (some users might not have rights to mark as "Closed" - convert these to "Closed".
. When all documentation changes are in place, use `bin/publish-docs.sh` to deploy a final `SNAPSHOT` representation
of the docs and thus validate that there are no issues with the documentation generation process. Request review
of the published documentation on the dev mailing list.

Release Candidate
-----------------

A release candidate is an unofficial release that is represented by a tagged version in the Git repository.  It is
offered in cases where there is significant change in a particular version and the potential for upgrades and problems
might be high.

. `mvn clean install -DincludeNeo4j`
.. `mvn verify -DskipIntegrationTests=false -DincludeNeo4j`
.. `mvn verify -DskipPerformanceTests=false`
. `bin/publish-docs.sh <username>` - note that under a release candidate the documentation is published as SNAPSHOT
. `mvn versions:set -DnewVersion=xx.yy.zz -DgenerateBackupPoms=false` to update the project files to reference a non-SNAPSHOT version
. `git diff` and review the updated files (expect all `pom.xml` files and this README)
. `git commit -a -m "TinkerPop xx.yy.zz release"` and `git push`
. `git tag -a -m "TinkerPop xx.yy.zz release" xx.yy.zz` and `git push --tags`
. `mvn clean install`
. `mvn versions:set -DnewVersion=xx.yy.zz-SNAPSHOT -DgenerateBackupPoms=false` to go back to SNAPSHOT
. `git commit -a -m "Returned to xx.yy.zz-SNAPSHOT"` and `git push`
. Announce the release candidate to `dev` mailing list and await feedback
. Repeat as required or proceed to the next phase

PMC Vote
--------

A positive vote for a particular release from the TinkerPop PMC is required to move to the following phase.

. By this point, the testing performed during the code freeze should have validated the release.  If however there
are additional tests to perform that the release manager feels are relevant, they should be performed now. In other
words, there is no need to rebuild the `SNAPSHOT` yet another time unless there are circumstances that would call its
validity into question.
. Update `CHANGELOG.asciidoc`:
.. Update the release date
.. Generate the JIRA release notes report for the current version and append them to the `CHANGELOG.asciidoc`.
... Use an "advanced" search to filter out JIRA issues already released on other versions. For example: `fixVersion
= 3.1.0-incubating AND fixVersion not in (3.0.2-incubating, 3.0.1-incubating)`.
... Consider use of an "Excel" export to organize, sort (by type and then id) and prepare the JIRA tickets to be pasted to `CHANGELOG.asciidoc`
... Be sure to include a link to other versions in the `CHANGELOG.asciidoc` that were previously released while the
current release was under development as this new release will have those changes included within it. Please see
3.1.0-incubating or 3.2.0-incubating for an example.
.. Organize "breaking" changes to be clearly marked (use JIRA and the "breaking" label to identify those)
. Update "upgrade documentation":
.. Update the release date.
.. Update the link to CHANGELOG.asciidoc
. `mvn versions:set -DnewVersion=xx.yy.zz -DgenerateBackupPoms=false` to update project files to reference the non-SNAPSHOT version
. `git diff` and review the updated files (expect all `pom.xml` files and this README)
. `git commit -a -m "TinkerPop xx.yy.zz release"` and push
. `mvn clean install` - need to build first so that the right version of the console is used with `bin/publish-docs.sh`
. `bin/process-docs.sh` and validate the generated documentation locally (don't rely on "SUCCESS" - scroll up through logs to ensure there were no errors and view the HTML directly)
. `bin/publish-docs.sh <username>` - Note that this step requires no additional processing as the previous step.
handled document generation and this step now merely needs to upload what was generated.
. `mvn deploy -Papache-release -DcreateChecksum=true -DskipTests` - deploy signed artifacts with checksums to link:https://repository.apache.org/[Apache Nexus]. Review (artifacts versions, file sizes, anything that might be out of place - request another committer to review as well).
. Review generated artifacts to be sure they have both javadocs and asciidocs present then "close" the repo - if the repo is left open it will be automatically dropped after five days and closing the repo will allow it to stay available for a full ninety days which is more than enough time to complete a vote. Do NOT "release" the repository at this time.
. Upload artifacts to `https://dist.apache.org/repos/dist/dev//tinkerpop` for `[VOTE]` review.
.. `svn co --depth empty https://dist.apache.org/repos/dist/dev//tinkerpop/ dev` and `mkdir dev/xx.yy.zz`
.. `cp ~/.m2/repository/org/apache/tinkerpop/gremlin-console/xx.yy.zz/gremlin-console-xx.yy.zz-distribution.zip* dev/xx.yy.zz`
.. `cp ~/.m2/repository/org/apache/tinkerpop/gremlin-server/xx.yy.zz/gremlin-server-xx.yy.zz-distribution.zip* dev/xx.yy.zz`
.. `cp ~/.m2/repository/org/apache/tinkerpop/tinkerpop/xx.yy.zz/tinkerpop-xx.yy.zz-source-release.zip* dev/xx.yy.zz`
.. `cd dev/xx.yy.zz`
.. pass:[ls * | xargs -n1 -I {} echo "mv apache-{} {}" | sed -e 's/distribution/bin/' -e 's/source-release/src/' -e s'/^\(.*\) \(.*\) \(.*\)$/\1 \3 \2/' | /bin/bash]
.. `cd ..; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"`
. Execute `bin/validate-distribution.sh` and any other relevant testing.
. `git tag -a -m "TinkerPop xx.yy.zz release" xx.yy.zz` and `git push --tags`
. Perform JIRA administration tasks:
.. "Release" the current version and set the "release date"
.. If there is to be a follow on release in the current line of code, create that new version specifying the "start date"
. Prepare Git administration tasks. Note that this work can be performed at the release manager's discretion. It may be wise to wait until a successful VOTE is eminent before reopening development. Apply the following steps as needed per release branch:
.. Make the appropriate branching changes as required by the release and bump the version to `SNAPSHOT` with
`mvn versions:set -DnewVersion=xx.yy.zz-SNAPSHOT -DgenerateBackupPoms=false`.
.. `mvn clean install -DskipTests` - need to build first so that the right version of the console is used with `bin/publish-docs.sh`
.. `mvn deploy` - deploy the new `SNAPSHOT`
.. `bin/process-docs.sh` and validate the generated `SNAPSHOT` documentation locally
.. `bin/publish-docs.sh <username>` to publish the `SNAPSHOT` docs which enables the README to work properly.
.. Update the links in the `README.asciidoc` to point at the `SNAPSHOT` version.
.. Commit and push the `SNAPSHOT` changes to git
.. Send email to advise that code freeze is lifted.
.. Generate a list of dead branches that will be automatically deleted and post them as a DISCUSS thread for review, then once consensus is reached removed those branches.
. Submit for `[VOTE]` at `dev@tinkerpop.apache.org` (see email template below)
. *Wait for vote acceptance* (72 hours)

Release & Promote
-----------------

. Login to link:https://repository.apache.org/[Apache Nexus] and release the previously closed repository.
. `svn co --depth empty https://dist.apache.org/repos/dist/dev/tinkerpop dev; svn up dev/xx.yy.zz`
. `svn co --depth empty https://dist.apache.org/repos/dist/release/tinkerpop release; mkdir release/xx.yy.zz`
. Copy release files from `dev/xx.yy.zz` to `release/xx.yy.zz`.
. `cd release; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"`
. Update homepage with references to latest distribution and to other internal links elsewhere on the page.
. Wait for Apache Central to sync the jars and src (link:http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/[http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/]).
. If there are releases present in SVN that represents lines of code that are no longer under development, then remove those releases. In other words, if `3.1.0-incubating` is present and `3.1.1-incubating` is released then remove `3.1.0-incubating`.  However, if `3.0.2-incubating` is present and that line of code is still under potential development, it may stay.
. Announce release on `dev@`/`gremlin-users@` mailing lists and tweet from `@apachetinkerpop`

Email Templates
---------------

Release VOTE
~~~~~~~~~~~~

```
Subject: [VOTE] TinkerPop xx.yy.zz Release

Hello,

We are happy to announce that TinkerPop xx.yy.zz is ready for release.

The release artifacts can be found at this location:
	https://dist.apache.org/repos/dist/dev/tinkerpop/xx.yy.zz/

The source distribution is provided by:
	apache-tinkerpop-xx.yy.zz-src.zip

Two binary distributions are provided for user convenience:
	apache-gremlin-console-xx.yy.zz-bin.zip
	apache-gremlin-server-xx.yy.zz-bin.zip

The GPG key used to sign the release artifacts is available at:
    https://dist.apache.org/repos/dist/dev/tinkerpop/KEYS

The online docs can be found here:
	http://tinkerpop.apache.org/docs/xx.yy.zz/reference/ (user docs)
	http://tinkerpop.apache.org/docs/xx.yy.zz/upgrade/ (upgrade docs)
	http://tinkerpop.apache.org/javadocs/xx.yy.zz/core/ (core javadoc)
	http://tinkerpop.apache.org/javadocs/xx.yy.zz/full/ (full javadoc)

The tag in Apache Git can be found here:
	https://git-wip-us.apache.org/repos/asf?p=tinkerpop.git;XXXXXXXXXXXXXXXXXX

The release notes are available here:
	https://github.com/apache/tinkerpop/blob/master/CHANGELOG.asciidoc#XXXXXXXXXXXXXXXXXX

The [VOTE] will be open for the next 72 hours --- closing <DayOfTheWeek> (<Month> <Day> <Year>) at <Time> <TimeZone>.

My vote is +1.

Thank you very much,
<TinkerPop Committer Name>
```

Dev Release RESULT VOTE
~~~~~~~~~~~~~~~~~~~~~~~

```
Subject: [RESULT][VOTE] TinkerPop xx.yy.zz Release

This vote is now closed with a total of X +1s, no +0s and no -1s. The results are:

BINDING VOTES:

+1  (X -- list of voters)
0   (0)
-1  (0)

NON-BINDING VOTES:

+1 (X -- list of voters)
0  (0)
-1 (0)

Thank you very much,
<TinkerPop Committer Name>
```

General Release Announcement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Subject: TinkerPop xx.yy.zz Released: [name of release line]

Hello,

TinkerPop xx.yy.zz has just been released. [some text to introduce the release - e.g. whether or not
there is breaking change, an important game-changing feature or two, etc.]

The release artifacts can be found at this location:

https://www.apache.org/dyn/closer.lua/tinkerpop/xx.yy.zz/apache-gremlin-console-xx.yy.zz-bin.zip
https://www.apache.org/dyn/closer.lua/tinkerpop/xx.yy.zz/apache-gremlin-server-xx.yy.zz-bin.zip

The online docs can be found here:

http://tinkerpop.apache.org/docs/xx.yy.zz/reference/ (user docs)
http://tinkerpop.apache.org/docs/xx.yy.zz/upgrade.html#XXXXXXXXXXXXXXXXXX (upgrade docs)
http://tinkerpop.apache.org/javadocs/xx.yy.zz/core/ (core javadoc)
http://tinkerpop.apache.org/javadocs/xx.yy.zz/full/ (full javadoc)
http://tinkerpop.apache.org/docs/xx.yy.zz/some-new-content/ (some new content) [NEW!]

The release notes are available here:

https://github.com/apache/tinkerpop/blob/xx.yy.zz/CHANGELOG.asciidoc#XXXXXXXXXXXXXXXXXX

The Central Maven repo has sync'd as well:

https://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/xx.yy.zz/

[include the release line logo]


added a note in upgrade docs regarding the change of order of select scopes

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

NEED AN IMAGE

*NOT NAMED YET*

== TinkerPop 3.4.0

*NOT OFFICIALLY RELEASED YET*

Please see the link:https://github.com/apache/tinkerpop/blob/3.4.0/CHANGELOG.asciidoc#release-3-4-0[changelog] for a complete list of all the modifications that are part of this release.

=== Upgrading for Users

==== Modifications to reducing barrier steps

The behavior of `min()`, `max()`, `mean()` and `sum()` has been modified to return no result if there's no input. Previously these steps yielded the internal seed value:

[source,groovy]
----
gremlin> g.V().values('foo').min()
==>NaN
gremlin> g.V().values('foo').max()
==>NaN
gremlin> g.V().values('foo').mean()
==>NaN
gremlin> g.V().values('foo').sum()
==>0
----

These traversals will no longer emit a result. Note, that this also affects more complex scenarios, e.g. if these steps are used in `by()` modulators:

[source,groovy]
----
gremlin> g.V().group().
......1>   by(label).
......2>   by(outE().values("weight").sum())
==>[software:0,person:3.5]
----

Since software vertices have no outgoing edges and thus no weight values to sum, `software` will no longer show up in the result. In order to get the same result as before, one would
have to add a `coalesce()`-step:

[source,groovy]
----
gremlin> g.V().group().
......1>   by(label).
......2>   by(outE().values("weight").sum())
==>[person:3.5]
gremlin> g.V().group().
......1>   by(label).
......2>   by(coalesce(outE().values("weight"), constant(0)).sum())
==>[software:0,person:3.5]
----

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

==== Change in order of select() scopes

The order of select scopes has been changed to: maps, side-effects, paths
Previously the order was: side-effects, maps, paths - which made it almost impossible to select a specific map entry if a side-effect with the same name existed.

The following snippets illustrate the changed behavior:

[source,groovy]
----
gremlin> g.V(1).
......1>   group("a").
......2>     by(__.constant("a")).
......3>     by(__.values("name")).
......4>   select("a")
==>[a:marko]
gremlin> g.V(1).
......1>   group("a").
......2>     by(__.constant("a")).
......3>     by(__.values("name")).
......4>   select("a").select("a")
==>[a:marko]
----

Above is the old behavior; the second `select("a")` has no effect, it selects the side-effect `a` again, although one would expect to get the map entry `a`. What follows is the new behavior:

[source,groovy]
----
gremlin> g.V(1).
......1>   group("a").
......2>     by(__.constant("a")).
......3>     by(__.values("name")).
......4>   select("a")
==>[a:marko]
gremlin> g.V(1).
......1>   group("a").
......2>     by(__.constant("a")).
......3>     by(__.values("name")).
......4>   select("a").select("a")
==>marko
----

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

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

NEED AN IMAGE

*NOT NAMED YET*

== TinkerPop 3.4.0

*NOT OFFICIALLY RELEASED YET*

Please see the link:https://github.com/apache/tinkerpop/blob/3.4.0/CHANGELOG.asciidoc#release-3-4-0[changelog] for a complete list of all the modifications that are part of this release.

=== Upgrading for Users

==== Modifications to reducing barrier steps

The behavior of `min()`, `max()`, `mean()` and `sum()` has been modified to return no result if there's no input. Previously these steps yielded the internal seed value:

[source,groovy]
----
gremlin> g.V().values('foo').min()
==>NaN
gremlin> g.V().values('foo').max()
==>NaN
gremlin> g.V().values('foo').mean()
==>NaN
gremlin> g.V().values('foo').sum()
==>0
----

These traversals will no longer emit a result. Note, that this also affects more complex scenarios, e.g. if these steps are used in `by()` modulators:

[source,groovy]
----
gremlin> g.V().group().
......1>   by(label).
......2>   by(outE().values("weight").sum())
==>[software:0,person:3.5]
----

Since software vertices have no outgoing edges and thus no weight values to sum, `software` will no longer show up in the result. In order to get the same result as before, one would
have to add a `coalesce()`-step:

[source,groovy]
----
gremlin> g.V().group().
......1>   by(label).
......2>   by(outE().values("weight").sum())
==>[person:3.5]
gremlin>
gremlin> g.V().group().
......1>   by(label).
......2>   by(coalesce(outE().values("weight"), constant(0)).sum())
==>[software:0,person:3.5]
----

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