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 2023/01/04 20:39:40 UTC

[tinkerpop] branch master updated (8caa6749da -> 9fc279fb0e)

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


    from 8caa6749da Merge branch '3.6-dev'
     add a2f629ef06 TINKERPOP-2842 Parsed requestId in GremlinScriptChecker
     new 0adaa5ff81 Merge branch 'TINKERPOP-2842' into 3.5-dev
     new 2e57d05d60 Merge branch '3.5-dev' into 3.6-dev
     new 9fc279fb0e Merge branch '3.6-dev'

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CHANGELOG.asciidoc                                 |   1 +
 .../gremlin/jsr223/GremlinScriptChecker.java       | 226 ++++++++++++---------
 .../gremlin/jsr223/GremlinScriptCheckerTest.java   | 113 ++++++++++-
 3 files changed, 242 insertions(+), 98 deletions(-)


[tinkerpop] 01/03: Merge branch 'TINKERPOP-2842' into 3.5-dev

Posted by sp...@apache.org.
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 0adaa5ff819eb1e87dffc4959c08da6913de222e
Merge: ada82b8025 a2f629ef06
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Wed Jan 4 15:16:46 2023 -0500

    Merge branch 'TINKERPOP-2842' into 3.5-dev

 CHANGELOG.asciidoc                                 |   1 +
 .../groovy/jsr223/GremlinScriptChecker.java        | 226 ++++++++++++---------
 .../groovy/jsr223/GremlinScriptCheckerTest.java    | 113 ++++++++++-
 3 files changed, 242 insertions(+), 98 deletions(-)



[tinkerpop] 02/03: Merge branch '3.5-dev' into 3.6-dev

Posted by sp...@apache.org.
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 2e57d05d603f5e08a055bc82a45cc26e7b983f74
Merge: 69fe9694be 0adaa5ff81
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Wed Jan 4 15:39:13 2023 -0500

    Merge branch '3.5-dev' into 3.6-dev

 CHANGELOG.asciidoc                                 |   1 +
 .../gremlin/jsr223/GremlinScriptChecker.java       | 226 ++++++++++++---------
 .../gremlin/jsr223/GremlinScriptCheckerTest.java   | 113 ++++++++++-
 3 files changed, 242 insertions(+), 98 deletions(-)

diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java
index 4952fb3bd6,0000000000..3cea1db7a6
mode 100644,000000..100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java
@@@ -1,203 -1,0 +1,239 @@@
 +/*
 + * 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.jsr223;
 +
 +import java.util.Arrays;
- import java.util.List;
++import java.util.HashSet;
 +import java.util.Optional;
++import java.util.Set;
 +import java.util.regex.Matcher;
 +import java.util.regex.Pattern;
 +
 +/**
-  * Processes Gremlin strings using regex so as to try to detect certain properties from the script without actual
++ * Processes Gremlin strings using regex to try to detect certain properties from the script without actual
 + * having to execute a {@code eval()} on it.
 + */
 +public class GremlinScriptChecker {
 +
-     public static final Result EMPTY_RESULT = new Result(0);
-     private static final List<String> tokens = Arrays.asList("evaluationTimeout", "scriptEvaluationTimeout",
-                                                              "ARGS_EVAL_TIMEOUT", "ARGS_SCRIPT_EVAL_TIMEOUT");
++    /**
++     * An empty result whose properties return as empty.
++     */
++    public static final Result EMPTY_RESULT = new Result(null, null);
 +
++    /**
++     * At least one of these tokens should be present somewhere in the Gremlin string for {@link #parse(String)} to
++     * take any action at all.
++     */
++    private static final Set<String> tokens = new HashSet<>(Arrays.asList("evaluationTimeout", "scriptEvaluationTimeout",
++                                                                          "ARGS_EVAL_TIMEOUT", "ARGS_SCRIPT_EVAL_TIMEOUT",
++                                                                          "requestId", "REQUEST_ID"));
 +    /**
 +     * Matches single line comments, multi-line comments and space characters.
 +     * <pre>
++     * From https://regex101.com/
++     *
 +     * 	OR: match either of the followings
 +     * Sequence: match all of the followings in order
 +     * / /
 +     * Repeat
 +     * AnyCharacterExcept\n
 +     * zero or more times
 +     * EndOfLine
 +     * Sequence: match all of the followings in order
 +     * /
 +     * *
 +     * Repeat
 +     * CapturingGroup
 +     * GroupNumber:1
 +     * OR: match either of the followings
 +     * AnyCharacterExcept\n
 +     * AnyCharIn[ CarriageReturn NewLine]
 +     * zero or more times (ungreedy)
 +     * *
 +     * /
 +     * WhiteSpaceCharacter
 +     * </pre>
 +     */
 +    private static final Pattern patternClean = Pattern.compile("//.*$|/\\*(.|[\\r\\n])*?\\*/|\\s", Pattern.MULTILINE);
 +
 +    /**
 +     * Regex fragment for the timeout tokens to look for. There are basically four:
 +     * <ul>
 +     *     <li>{@code evaluationTimeout} which is a string value and thus single or double quoted</li>
 +     *     <li>{@code scriptEvaluationTimeout} which is a string value and thus single or double quoted</li>
 +     *     <li>{@code ARGS_EVAL_TIMEOUT} which is a enum type of value which can be referenced with or without a {@code Tokens} qualifier</li>
 +     *     <li>{@code ARGS_SCRIPT_EVAL_TIMEOUT} which is a enum type of value which can be referenced with or without a {@code Tokens} qualifier</li>
 +     * </ul>
-      * <pre>
-      * 	OR: match either of the followings
-      * Sequence: match all of the followings in order
-      * AnyCharIn[ " ']
-      * e v a l u a t i o n T i m e o u t
-      * AnyCharIn[ " ']
-      * Sequence: match all of the followings in order
-      * AnyCharIn[ " ']
-      * s c r i p t E v a l u a t i o n T i m e o u t
-      * AnyCharIn[ " ']
-      * Sequence: match all of the followings in order
-      * Repeat
-      * CapturingGroup
-      * (NonCapturingGroup)
-      * Sequence: match all of the followings in order
-      * T o k e n s
-      * .
-      * optional
-      * A R G S _ E V A L _ T I M E O U T
-      * Sequence: match all of the followings in order
-      * Repeat
-      * CapturingGroup
-      * (NonCapturingGroup)
-      * Sequence: match all of the followings in order
-      * T o k e n s
-      * .
-      * optional
-      * A R G S _ S C R I P T _ E V A L _ T I M E O U T
-      * </pre>
++     * See {@link #patternWithOptions} for explain as this regex is embedded in there.
 +     */
 +    private static final String timeoutTokens = "[\"']evaluationTimeout[\"']|[\"']scriptEvaluationTimeout[\"']|(?:Tokens\\.)?ARGS_EVAL_TIMEOUT|(?:Tokens\\.)?ARGS_SCRIPT_EVAL_TIMEOUT";
 +
++    /**
++     * Regex fragment for the timeout tokens to look for. There are basically four:
++     * <ul>
++     *     <li>{@code requestId} which is a string value and thus single or double quoted</li>
++     *     <li>{@code REQUEST_ID} which is a enum type of value which can be referenced with or without a {@code Tokens} qualifier</li>
++     * </ul>
++     * See {@link #patternWithOptions} for a full explain as this regex is embedded in there.
++     */
++    private static final String requestIdTokens = "[\"']requestId[\"']|(?:Tokens\\.)?REQUEST_ID";
++
 +    /**
 +     * Matches {@code .with({timeout-token},{timeout})} with a matching group on the {@code timeout}.
 +     *
 +     * <pre>
-      * Sequence: match all of the followings in order
-      * .
-      * w i t h
-      * (
-      * CapturingGroup
-      * (NonCapturingGroup)
-      * OR: match either of the followings
-      * Sequence: match all of the followings in order
-      * AnyCharIn[ " ']
-      * e v a l u a t i o n T i m e o u t
-      * AnyCharIn[ " ']
-      * Sequence: match all of the followings in order
-      * AnyCharIn[ " ']
-      * s c r i p t E v a l u a t i o n T i m e o u t
-      * AnyCharIn[ " ']
-      * Sequence: match all of the followings in order
-      * Repeat
-      * CapturingGroup
-      * (NonCapturingGroup)
-      * Sequence: match all of the followings in order
-      * T o k e n s
-      * .
-      * optional
-      * A R G S _ E V A L _ T I M E O U T
-      * Sequence: match all of the followings in order
-      * Repeat
-      * CapturingGroup
-      * (NonCapturingGroup)
-      * Sequence: match all of the followings in order
-      * T o k e n s
-      * .
-      * optional
-      * A R G S _ S C R I P T _ E V A L _ T I M E O U T
-      * ,
-      * CapturingGroup
-      * GroupNumber:1
-      * Repeat
-      * Digit
-      * zero or more times
-      * Repeat
-      * CapturingGroup
-      * GroupNumber:2
-      * OR: match either of the followings
-      * Sequence: match all of the followings in order
-      * Repeat
-      * :
-      * optional
-      * L
-      * l
-      * optional
-      * )
++     * From https://regex101.com/
++     *
++     * \.with\((?:(?:["']evaluationTimeout["']|["']scriptEvaluationTimeout["']|(?:Tokens\.)?ARGS_EVAL_TIMEOUT|(?:Tokens\.)?ARGS_SCRIPT_EVAL_TIMEOUT),(?<to>\d*)(:?L|l)?)|(?:(?:["']requestId["']|(?:Tokens\.)?REQUEST_ID),["'](?<rid>.*?))["']\)
++     *
++     * gm
++     * 1st Alternative \.with\((?:(?:["']evaluationTimeout["']|["']scriptEvaluationTimeout["']|(?:Tokens\.)?ARGS_EVAL_TIMEOUT|(?:Tokens\.)?ARGS_SCRIPT_EVAL_TIMEOUT),(?<to>\d*)(:?L|l)?)
++     * \. matches the character . with index 4610 (2E16 or 568) literally (case sensitive)
++     * with matches the characters with literally (case sensitive)
++     * \( matches the character ( with index 4010 (2816 or 508) literally (case sensitive)
++     * Non-capturing group (?:(?:["']evaluationTimeout["']|["']scriptEvaluationTimeout["']|(?:Tokens\.)?ARGS_EVAL_TIMEOUT|(?:Tokens\.)?ARGS_SCRIPT_EVAL_TIMEOUT),(?<to>\d*)(:?L|l)?)
++     * Non-capturing group (?:["']evaluationTimeout["']|["']scriptEvaluationTimeout["']|(?:Tokens\.)?ARGS_EVAL_TIMEOUT|(?:Tokens\.)?ARGS_SCRIPT_EVAL_TIMEOUT)
++     * 1st Alternative ["']evaluationTimeout["']
++     * Match a single character present in the list below ["']
++     * "' matches a single character in the list "' (case sensitive)
++     * evaluationTimeout matches the characters evaluationTimeout literally (case sensitive)
++     * Match a single character present in the list below ["']
++     * "' matches a single character in the list "' (case sensitive)
++     * 2nd Alternative ["']scriptEvaluationTimeout["']
++     * Match a single character present in the list below ["']
++     * "' matches a single character in the list "' (case sensitive)
++     * scriptEvaluationTimeout matches the characters scriptEvaluationTimeout literally (case sensitive)
++     * Match a single character present in the list below ["']
++     * "' matches a single character in the list "' (case sensitive)
++     * 3rd Alternative (?:Tokens\.)?ARGS_EVAL_TIMEOUT
++     * Non-capturing group (?:Tokens\.)?
++     * ? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
++     * Tokens matches the characters Tokens literally (case sensitive)
++     * \. matches the character . with index 4610 (2E16 or 568) literally (case sensitive)
++     * ARGS_EVAL_TIMEOUT matches the characters ARGS_EVAL_TIMEOUT literally (case sensitive)
++     * 4th Alternative (?:Tokens\.)?ARGS_SCRIPT_EVAL_TIMEOUT
++     * Non-capturing group (?:Tokens\.)?
++     * ? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
++     * Tokens matches the characters Tokens literally (case sensitive)
++     * \. matches the character . with index 4610 (2E16 or 568) literally (case sensitive)
++     * ARGS_SCRIPT_EVAL_TIMEOUT matches the characters ARGS_SCRIPT_EVAL_TIMEOUT literally (case sensitive)
++     * , matches the character , with index 4410 (2C16 or 548) literally (case sensitive)
++     * Named Capture Group to (?<to>\d*)
++     * \d matches a digit (equivalent to [0-9])
++     * * matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
++     * 2nd Capturing Group (:?L|l)?
++     * ? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
++     * 1st Alternative :?L
++     * : matches the character : with index 5810 (3A16 or 728) literally (case sensitive)
++     * ? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
++     * L matches the character L with index 7610 (4C16 or 1148) literally (case sensitive)
++     * 2nd Alternative l
++     * l matches the character l with index 10810 (6C16 or 1548) literally (case sensitive)
++     * 2nd Alternative (?:(?:["']requestId["']|(?:Tokens\.)?REQUEST_ID),["'](?<rid>.*?))["']\)
++     * Non-capturing group (?:(?:["']requestId["']|(?:Tokens\.)?REQUEST_ID),["'](?<rid>.*?))
++     * Non-capturing group (?:["']requestId["']|(?:Tokens\.)?REQUEST_ID)
++     * 1st Alternative ["']requestId["']
++     * 2nd Alternative (?:Tokens\.)?REQUEST_ID
++     * , matches the character , with index 4410 (2C16 or 548) literally (case sensitive)
++     * Match a single character present in the list below ["']
++     * "' matches a single character in the list "' (case sensitive)
++     * Named Capture Group rid (?<rid>.*?)
++     * . matches any character (except for line terminators)
++     * *? matches the previous token between zero and unlimited times, as few times as possible, expanding as needed (lazy)
++     * Match a single character present in the list below ["']
++     * "' matches a single character in the list "' (case sensitive)
++     * \) matches the character ) with index 4110 (2916 or 518) literally (case sensitive)
 +     * </pre>
 +     */
-     private static final Pattern patternTimeout = Pattern.compile("\\.with\\((?:" + timeoutTokens + "),(\\d*)(:?L|l)?\\)");
++    private static final Pattern patternWithOptions =
++            Pattern.compile("\\.with\\(((?:" + timeoutTokens + "),(?<to>\\d*)(:?L|l)?)|((?:" + requestIdTokens + "),[\"'](?<rid>.*?))[\"']\\)");
 +
 +    /**
 +     * Parses a Gremlin script and extracts a {@code Result} containing properties that are relevant to the checker.
 +     */
 +    public static Result parse(final String gremlin) {
 +        if (gremlin.isEmpty()) return EMPTY_RESULT;
 +
 +        // do a cheap check for tokens we care about - no need to parse unless one of these tokens is present in
 +        // the string.
 +        if (tokens.stream().noneMatch(gremlin::contains)) return EMPTY_RESULT;
 +
 +        // kill out comments/whitespace. for whitespace, ignoring the need to keep string literals together as that
 +        // isn't currently a requirement
 +        final String cleanGremlin = patternClean.matcher(gremlin).replaceAll("");
 +
-         final Matcher m = patternTimeout.matcher(cleanGremlin);
++        final Matcher m = patternWithOptions.matcher(cleanGremlin);
 +        if (!m.find()) return EMPTY_RESULT;
 +
-         long l = Long.parseLong(m.group(1));
-         while (m.find()) {
-             l += Long.parseLong(m.group(1));
-         }
++        // arguments given to Result class as null mean they weren't assigned (or the parser didn't find them somehow - eek!)
++        Long timeout = null;
++        String requestId = null;
++        do {
++            // timeout is added up across all scripts
++            final String to = m.group("to");
++            if (to != null) {
++                if (null == timeout) timeout = 0L;
++                timeout += Long.parseLong(to);
++            }
++
++            // request id just uses the last one found
++            final String rid = m.group("rid");
++            if (rid != null) requestId = rid;
++        } while (m.find());
 +
-         return new Result(l);
++        return new Result(timeout, requestId);
 +    }
 +
++    /**
++     * A result returned from a {@link #parse(String)} of a Gremlin string.
++     */
 +    public static class Result {
-         private final long timeout;
++        private final Long timeout;
++        private final String requestId;
 +
-         private Result(final long timeout) {
++        private Result(final Long timeout, final String requestId) {
 +            this.timeout = timeout;
++            this.requestId = requestId;
 +        }
 +
 +        /**
 +         * Gets the value of the timeouts that were set using the {@code with()} source step. If there are multiple
 +         * commands using this step, the timeouts are summed together.
 +         */
 +        public final Optional<Long> getTimeout() {
-             return timeout == 0 ? Optional.empty() : Optional.of(timeout);
++            return null == timeout ? Optional.empty() : Optional.of(timeout);
++        }
++
++        /**
++         * Gets the value of the request identifier supplied using the {@code with()} source step. If there are
++         * multiple commands using this step, the last usage should represent the id returned here.
++         */
++        public Optional<String> getRequestId() {
++            return null == requestId ? Optional.empty() : Optional.of(requestId);
++        }
++
++        @Override
++        public String toString() {
++            return "GremlinScriptChecker.Result{" +
++                    "timeout=" + timeout +
++                    ", requestId='" + requestId + '\'' +
++                    '}';
 +        }
 +    }
 +}
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java
index 35662ccf13,0000000000..620ea0e73a
mode 100644,000000..100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java
@@@ -1,300 -1,0 +1,407 @@@
 +/*
 + * 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.jsr223;
 +
 +import org.junit.Test;
 +
 +import java.util.Optional;
 +
 +import static org.apache.tinkerpop.gremlin.jsr223.GremlinScriptChecker.EMPTY_RESULT;
++import static org.hamcrest.MatcherAssert.assertThat;
++import static org.hamcrest.core.Is.is;
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertSame;
 +
 +public class GremlinScriptCheckerTest {
 +
 +    @Test
-     public void shouldNotFindTimeout() {
-         assertEquals(Optional.empty(), GremlinScriptChecker.parse("g.with(true).V().out('knows')").getTimeout());
++    public void shouldNotFindAResult() {
++        final GremlinScriptChecker.Result r = GremlinScriptChecker.parse("g.with(true).V().out('knows')");
++        assertEquals(Optional.empty(), r.getTimeout());
++        assertEquals(Optional.empty(), r.getRequestId());
 +    }
 +
 +    @Test
 +    public void shouldReturnEmpty() {
-         assertSame(EMPTY_RESULT, GremlinScriptChecker.parse(""));
++        final GremlinScriptChecker.Result r = GremlinScriptChecker.parse("");
++        assertSame(EMPTY_RESULT, r);
++        assertEquals(Optional.empty(), r.getTimeout());
++        assertEquals(Optional.empty(), r.getRequestId());
 +    }
 +
 +    @Test
 +    public void shouldNotFindTimeoutCozWeCommentedItOut() {
 +        assertEquals(Optional.empty(), GremlinScriptChecker.parse("g.\n" +
 +                "                                                  // with('evaluationTimeout', 1000L).\n" +
 +                "                                                  with(true).V().out('knows')").getTimeout());
 +    }
 +
++    @Test
++    public void shouldIdentifyTimeoutWithOddSpacing() {
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout' , 1000L).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout'   ,  1000L).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout',1000L).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++    }
++
++    @Test
++    public void shouldIdentifyRequestIdWithOddSpacing() {
++        assertEquals("4F53FB59-CFC9-4984-B477-452073A352FD", GremlinScriptChecker.parse("g.with('requestId' , '4F53FB59-CFC9-4984-B477-452073A352FD').with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("4F53FB59-CFC9-4984-B477-452073A352FD", GremlinScriptChecker.parse("g.with('requestId'   ,  '4F53FB59-CFC9-4984-B477-452073A352FD').with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("4F53FB59-CFC9-4984-B477-452073A352FD", GremlinScriptChecker.parse("g.with('requestId','4F53FB59-CFC9-4984-B477-452073A352FD').with(true).V().out('knows')").
++                getRequestId().get());
++    }
++
++    @Test
++    public void shouldIdentifyRequestIdWithEmbeddedQuote() {
++        assertEquals("te\"st", GremlinScriptChecker.parse("g.with('requestId','te\"st').with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("te\\\"st", GremlinScriptChecker.parse("g.with('requestId', \"te\\\"st\").with(true).V().out('knows')").
++                getRequestId().get());
++    }
++
++    @Test
++    public void shouldIdentifyTimeoutWithLowerL() {
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000l).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++    }
++
++    @Test
++    public void shouldIdentifyTimeoutWithNoL() {
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++        assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout', 1000).with(true).V().out('knows')").
++                getTimeout().get().longValue());
++    }
++
 +    @Test
 +    public void shouldIdentifyTimeoutAsStringKeySingleQuoted() {
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +    }
 +
++    @Test
++    public void shouldIdentifyRequestIdAsStringKeySingleQuoted() {
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with('requestId', 'db024fca-ed15-4375-95de-4c6106aef895').with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(\"requestId\", 'db024fca-ed15-4375-95de-4c6106aef895').with(true).V().out('knows')").
++                getRequestId().get());
++    }
++
 +    @Test
 +    public void shouldIdentifyTimeoutAsStringKeyDoubleQuoted() {
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with(\"evaluationTimeout\", 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with(\"scriptEvaluationTimeout\", 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +    }
 +
++    @Test
++    public void shouldIdentifyRequestIdAsStringKeyDoubleQuoted() {
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(\"requestId\", \"db024fca-ed15-4375-95de-4c6106aef895\").with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(\"requestId\", \"db024fca-ed15-4375-95de-4c6106aef895\").with(true).V().out('knows')").
++                getRequestId().get());
++    }
++
 +    @Test
 +    public void shouldIdentifyTimeoutAsTokenKey() {
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with(Tokens.ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +    }
 +
++    @Test
++    public void shouldIdentifyRequestIdAsTokenKey() {
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(Tokens.REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(Tokens.REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").with(true).V().out('knows')").
++                getRequestId().get());
++    }
++
 +    @Test
 +    public void shouldIdentifyTimeoutAsTokenKeyWithoutClassName() {
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with(ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with(ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')").
 +                getTimeout().get().longValue());
 +    }
 +
++    @Test
++    public void shouldIdentifyRequestIdAsTokenKeyWithoutClassName() {
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").with(true).V().out('knows')").
++                getRequestId().get());
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", GremlinScriptChecker.parse("g.with(REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").with(true).V().out('knows')").
++                getRequestId().get());
++    }
++
 +    @Test
 +    public void shouldIdentifyMultipleTimeouts() {
 +        assertEquals(6000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows');" +
 +                "g.with('evaluationTimeout', 1000L).with(true).V().out('knows');\n" +
 +                "                                                   //g.with('evaluationTimeout', 1000L).with(true).V().out('knows');\n" +
 +                "                                                   /* g.with('evaluationTimeout', 1000L).with(true).V().out('knows');*/\n" +
 +                "                                                   /* \n" +
 +                "g.with('evaluationTimeout', 1000L).with(true).V().out('knows'); \n" +
 +                "*/ \n" +
 +                "                                                   g.with('evaluationTimeout', 1000L).with(true).V().out('knows');\n" +
 +                "                                                   g.with(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows');\n" +
 +                "                                                   g.with(ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows');\n" +
 +                "                                                   g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows');").
 +                getTimeout().get().longValue());
 +    }
 +
++    @Test
++    public void shouldIdentifyMultipleRequestIds() {
++        assertEquals("test9", GremlinScriptChecker.parse("g.with('requestId', 'test1').with(true).V().out('knows');" +
++                        "g.with('requestId', 'test2').with(true).V().out('knows');\n" +
++                        "                                                   //g.with('requestId', 'test3').with(true).V().out('knows');\n" +
++                        "                                                   /* g.with('requestId', 'test4').with(true).V().out('knows');*/\n" +
++                        "                                                   /* \n" +
++                        "g.with('requestId', 'test5').with(true).V().out('knows'); \n" +
++                        "*/ \n" +
++                        "                                                   g.with('requestId', 'test6').with(true).V().out('knows');\n" +
++                        "                                                   g.with(Tokens.REQUEST_ID, 'test7').with(true).V().out('knows');\n" +
++                        "                                                   g.with(REQUEST_ID, 'test8').with(true).V().out('knows');\n" +
++                        "                                                   g.with('requestId', 'test9').with(true).V().out('knows');").
++                getRequestId().get());
++    }
++
++    @Test
++    public void shouldFindAllResults() {
++        final GremlinScriptChecker.Result r = GremlinScriptChecker.parse(
++                "g.with('evaluationTimeout', 1000).with(true).with(REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").V().out('knows')");
++        assertEquals(1000, r.getTimeout().get().longValue());
++        assertEquals("db024fca-ed15-4375-95de-4c6106aef895", r.getRequestId().get());
++    }
++
 +    @Test
 +    public void shouldParseLong() {
 +        assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).addV().property(id, 'blue').as('b').\n" +
 +                "  addV().property(id, 'orange').as('o').\n" +
 +                "  addV().property(id, 'red').as('r').\n" +
 +                "  addV().property(id, 'green').as('g').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('b').\n" +
 +                "  addE('bridge').from('g').to('o').\n" +
 +                "  addE('bridge').from('g').to('r').\n" +
 +                "  addE('bridge').from('g').to('r').\n" +
 +                "  addE('bridge').from('o').to('b').\n" +
 +                "  addE('bridge').from('o').to('b').\n" +
 +                "  addE('bridge').from('o').to('r').\n" +
 +                "  addE('bridge').from('o').to('r').iterate()").
 +                getTimeout().get().longValue());
 +    }
 +}


[tinkerpop] 03/03: Merge branch '3.6-dev'

Posted by sp...@apache.org.
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 9fc279fb0ebf7c656e09176ce32b78af04a71331
Merge: 8caa6749da 2e57d05d60
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Wed Jan 4 15:39:28 2023 -0500

    Merge branch '3.6-dev'

 CHANGELOG.asciidoc                                 |   1 +
 .../gremlin/jsr223/GremlinScriptChecker.java       | 226 ++++++++++++---------
 .../gremlin/jsr223/GremlinScriptCheckerTest.java   | 113 ++++++++++-
 3 files changed, 242 insertions(+), 98 deletions(-)