You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2019/09/26 17:03:18 UTC
[tinkerpop] 02/04: Merge branch 'tp33' into tp34
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit a8751c3fe416acca2248a9c957d1beec07df855c
Merge: 5803c26 13b60a6
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Thu Sep 26 11:48:09 2019 -0400
Merge branch 'tp33' into tp34
CHANGELOG.asciidoc | 5 +-
docs/src/upgrade/release-3.3.x.asciidoc | 16 +++
.../AbstractWarningVerificationStrategy.java | 111 +++++++++++++++++++++
.../EdgeLabelVerificationStrategy.java | 69 ++-----------
.../ReservedKeysVerificationStrategy.java | 106 ++++++++++++++++++++
.../EdgeLabelVerificationStrategyTest.java | 6 +-
...a => ReservedKeysVerificationStrategyTest.java} | 38 ++++---
.../Verification/EdgeLabelVerificationStrategy.cs | 49 +++++++++
.../ReservedKeysVerificationStrategy.cs | 55 ++++++++++
.../GraphTraversalSourceTests.cs | 2 +
.../main/jython/gremlin_python/driver/protocol.py | 3 +-
.../jython/gremlin_python/process/strategies.py | 18 +++-
.../tests/driver/test_driver_remote_connection.py | 15 ++-
.../tinkergraph/structure/TinkerGraphTest.java | 31 +++++-
14 files changed, 437 insertions(+), 87 deletions(-)
diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ReservedKeysVerificationStrategy.java
index 0000000,1a5404a..8fe6424
mode 000000,100644..100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ReservedKeysVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ReservedKeysVerificationStrategy.java
@@@ -1,0 -1,106 +1,106 @@@
+ /*
+ * 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.
+ */
+ package org.apache.tinkerpop.gremlin.process.traversal.strategy.verification;
+
+ import org.apache.commons.configuration.Configuration;
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+ import org.apache.tinkerpop.gremlin.process.traversal.Step;
+ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
++import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStartStep;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStep;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep;
+ import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.HashSet;
+ import java.util.Set;
+ import java.util.stream.Collectors;
+
+ /**
+ * This verification strategy detects property keys that should not be used by the traversal. A term may be reserved
+ * by a particular graph implementation or as a convention given best practices.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * * @example <pre>
+ * * __.addV("person").property("id", 123) // throws an IllegalStateException
+ * * __.addE("knows").property("label", "green") // throws an IllegalStateException
+ * * </pre>
+ */
+ public class ReservedKeysVerificationStrategy extends AbstractWarningVerificationStrategy {
+
+ private static final String KEYS = "keys";
+ private static final Set<String> DEFAULT_RESERVED_KEYS = new HashSet<>(Arrays.asList("id", "label"));
+ private final Set<String> reservedKeys;
+
+ private ReservedKeysVerificationStrategy(final Builder builder) {
+ super(builder);
+ this.reservedKeys = builder.reservedKeys;
+ }
+
+ @Override
+ void verify(final Traversal.Admin<?, ?> traversal) throws VerificationException {
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ if (step instanceof AddVertexStep || step instanceof AddVertexStartStep ||
+ step instanceof AddEdgeStartStep || step instanceof AddEdgeStep ||
+ step instanceof AddPropertyStep) {
+ final Parameterizing propertySettingStep = (Parameterizing) step;
+ final Parameters params = propertySettingStep.getParameters();
+ for (String key : reservedKeys) {
+ if (params.contains(key)) {
+ final String msg = String.format(
+ "The provided traversal contains a %s that is setting a property key to a reserved" +
+ " word: %s", propertySettingStep.getClass().getSimpleName(), key);
+ throw new VerificationException(msg, traversal);
+ }
+ }
+ }
+ }
+ }
+
+ public static ReservedKeysVerificationStrategy create(final Configuration configuration) {
+ return build()
+ .reservedKeys(configuration.getList(KEYS, new ArrayList<>(DEFAULT_RESERVED_KEYS)).
+ stream().map(Object::toString).collect(Collectors.toSet()))
+ .throwException(configuration.getBoolean(THROW_EXCEPTION, false))
+ .logWarning(configuration.getBoolean(LOG_WARNING, false)).create();
+ }
+
+ public static ReservedKeysVerificationStrategy.Builder build() {
+ return new ReservedKeysVerificationStrategy.Builder();
+ }
+
+ public final static class Builder extends AbstractWarningVerificationStrategy.Builder<ReservedKeysVerificationStrategy, Builder> {
+ private Set<String> reservedKeys = DEFAULT_RESERVED_KEYS;
+
+ private Builder() {}
+
+ public Builder reservedKeys(final Set<String> keys) {
+ reservedKeys = keys;
+ return this;
+ }
+
+ @Override
+ public ReservedKeysVerificationStrategy create() {
+ return new ReservedKeysVerificationStrategy(this);
+ }
+ }
+ }
diff --cc gremlin-python/src/main/jython/gremlin_python/driver/protocol.py
index bb3ab24,476b3ee..cd5e50a
--- a/gremlin-python/src/main/jython/gremlin_python/driver/protocol.py
+++ b/gremlin-python/src/main/jython/gremlin_python/driver/protocol.py
@@@ -76,12 -72,11 +77,12 @@@ class GremlinServerWSProtocol(AbstractB
def data_received(self, message, results_dict):
# if Gremlin Server cuts off then we get a None for the message
if message is None:
- raise GremlinServerError(500, "500: Server disconnected - please try to reconnect")
+ raise GremlinServerError({'code': 500,
+ 'message': 'Server disconnected - please try to reconnect', 'attributes': {}})
- message = self._message_serializer.deserialize_message(json.loads(message.decode('utf-8')))
+ message = self._message_serializer.deserialize_message(message)
request_id = message['requestId']
- result_set = results_dict[request_id]
+ result_set = results_dict[request_id] if request_id in results_dict else ResultSet(None, None)
status_code = message['status']['code']
aggregate_to = message['result']['meta'].get('aggregateTo', 'list')
data = message['result']['data']
diff --cc gremlin-python/src/main/jython/gremlin_python/process/strategies.py
index 0f8e876,6cc1091..b8c0677
--- a/gremlin-python/src/main/jython/gremlin_python/process/strategies.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/strategies.py
@@@ -64,9 -59,8 +64,9 @@@ class PartitionStrategy(TraversalStrate
class SubgraphStrategy(TraversalStrategy):
-
++
def __init__(self, vertices=None, edges=None, vertex_properties=None):
- TraversalStrategy.__init__(self)
+ TraversalStrategy.__init__(self, fqcn="org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy")
if vertices is not None:
self.configuration["vertices"] = vertices
if edges is not None:
@@@ -172,12 -166,12 +172,13 @@@ class RepeatUnrollStrategy(TraversalStr
class GraphFilterStrategy(TraversalStrategy):
def __init__(self):
- TraversalStrategy.__init__(self)
+ TraversalStrategy.__init__(self, fqcn="org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.optimization.GraphFilterStrategy")
+
+
class EarlyLimitStrategy(TraversalStrategy):
def __init__(self):
- TraversalStrategy.__init__(self)
+ TraversalStrategy.__init__(self, fqcn="org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategy")
###########################
# VERIFICATION STRATEGIES #
@@@ -191,4 -185,19 +192,19 @@@ class LambdaRestrictionStrategy(Travers
class ReadOnlyStrategy(TraversalStrategy):
def __init__(self):
- TraversalStrategy.__init__(self)
+ TraversalStrategy.__init__(self, fqcn="org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy")
+
+
+ class EdgeLabelVerificationStrategy(TraversalStrategy):
+ def __init__(self, log_warning=False, throw_exception=False):
- TraversalStrategy.__init__(self)
++ TraversalStrategy.__init__(self, fqcn="org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.EdgeLabelVerificationStrategy")
+ self.configuration["logWarning"] = log_warning
+ self.configuration["throwException"] = throw_exception
+
+
+ class ReservedKeysVerificationStrategy(TraversalStrategy):
+ def __init__(self, log_warning=False, throw_exception=False, keys=["id", "label"]):
- TraversalStrategy.__init__(self)
++ TraversalStrategy.__init__(self, fqcn="org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReservedKeysVerificationStrategy")
+ self.configuration["logWarning"] = log_warning
+ self.configuration["throwException"] = throw_exception
+ self.configuration["keys"] = keys
diff --cc gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
index 52c272b,7e9add6..174fbc6
--- a/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
+++ b/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
@@@ -180,6 -179,16 +181,18 @@@ class TestDriverRemoteConnection(object
g = traversal().withRemote(remote_connection).withComputer()
assert 6 == g.V().count().next()
assert 6 == g.E().count().next()
+ #
+ g = traversal().withRemote(remote_connection). \
+ withStrategies(ReservedKeysVerificationStrategy(throw_exception=True))
+ try:
+ g.addV("person").property("id", "please-don't-use-id").iterate()
+ assert False
- except KeyError as gse:
++ except GremlinServerError as gse:
++ assert gse.status_code == 500
++ except KeyError as ke:
+ # gross we need to fix this: https://issues.apache.org/jira/browse/TINKERPOP-2297
+ # would prefer to assert a GremlinServerError status code
+ assert True
def test_side_effects(self, remote_connection):
statics.load_statics(globals())