TINKERPOP-1779 Bump to GMavenPlus 1.6 Moved embedded groovy scripts that were in the pom to their own files. They are more manageable that way as you get some syntax highlighting/intellisense in the IDE when they have the right file extension. It also makes the pom a bit easier to follow. Removed a bunch of python test resources that were no longer in use. Centralized the scripts that start/stop Gremlin Server for GLV tests so that we don't have them copy/pasted everywhere.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e9801e6a Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e9801e6a Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e9801e6a Branch: refs/heads/TINKERPOP-1784 Commit: e9801e6af60dbfbaa83a1f8b5b947451dd27092c Parents: c59393f Author: Stephen Mallette <sp...@genoprime.com> Authored: Tue Sep 12 11:18:41 2017 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Tue Sep 12 19:05:26 2017 -0400 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 1 + giraph-gremlin/pom.xml | 14 + gremlin-console/pom.xml | 14 + gremlin-dotnet/glv/generate.groovy | 220 +++++++++++++++ gremlin-dotnet/pom.xml | 216 +------------- .../appsettings.json | 4 +- gremlin-dotnet/test/pom.xml | 79 ++---- gremlin-groovy-test/pom.xml | 14 + gremlin-groovy/pom.xml | 14 + .../glv/GraphTraversalSource.template | 102 +++++++ gremlin-python/glv/TraversalSource.template | 282 +++++++++++++++++++ gremlin-python/glv/generate.groovy | 94 +++++++ gremlin-python/pom.xml | 166 +++-------- .../resources/GraphTraversalSource.template | 102 ------- .../src/main/resources/TraversalSource.template | 282 ------------------- .../gremlin/python/driver/credentials.kryo | Bin 138 -> 0 bytes .../python/driver/generate-modern.groovy | 33 --- .../driver/gremlin-server-modern-secure-py.yaml | 63 ----- .../driver/tinkergraph-credentials.properties | 22 -- .../python/driver/tinkergraph-empty.properties | 18 -- .../tinkerpop/gremlin/server/Settings.java | 3 +- .../gremlin/server/util/MetricManager.java | 5 +- .../src/test/scripts/test-server-start.groovy | 49 ++++ .../src/test/scripts/test-server-stop.groovy | 32 +++ hadoop-gremlin/pom.xml | 14 + pom.xml | 16 +- spark-gremlin/pom.xml | 14 + 27 files changed, 946 insertions(+), 927 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/CHANGELOG.asciidoc ---------------------------------------------------------------------- diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index c15835c..4e64fd6 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima TinkerPop 3.2.7 (Release Date: NOT OFFICIALLY RELEASED YET) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* Bump to GMavenPlus 1.6. * Bump to Jackson 2.8.10. * Added an `EmbeddedRemoteConnection` so that it's possible to mimic a remote connection within the same JVM. * The Console's `plugin.txt` file is only updated if there were manually uninstalled plugins. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/giraph-gremlin/pom.xml ---------------------------------------------------------------------- diff --git a/giraph-gremlin/pom.xml b/giraph-gremlin/pom.xml index cacf54c..f55a6a4 100644 --- a/giraph-gremlin/pom.xml +++ b/giraph-gremlin/pom.xml @@ -227,6 +227,20 @@ limitations under the License. <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>addSources</goal> + <goal>addTestSources</goal> + <goal>generateStubs</goal> + <goal>compile</goal> + <goal>generateTestStubs</goal> + <goal>compileTests</goal> + <goal>removeStubs</goal> + <goal>removeTestStubs</goal> + </goals> + </execution> + </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-console/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-console/pom.xml b/gremlin-console/pom.xml index 0531af3..50d7b0e 100644 --- a/gremlin-console/pom.xml +++ b/gremlin-console/pom.xml @@ -203,6 +203,20 @@ limitations under the License. <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>addSources</goal> + <goal>addTestSources</goal> + <goal>generateStubs</goal> + <goal>compile</goal> + <goal>generateTestStubs</goal> + <goal>compileTests</goal> + <goal>removeStubs</goal> + <goal>removeTestStubs</goal> + </goals> + </execution> + </executions> </plugin> </plugins> </build> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-dotnet/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/glv/generate.groovy b/gremlin-dotnet/glv/generate.groovy new file mode 100644 index 0000000..8f66c26 --- /dev/null +++ b/gremlin-dotnet/glv/generate.groovy @@ -0,0 +1,220 @@ +/* + * 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. + */ + +import org.apache.tinkerpop.gremlin.jsr223.CoreImports +import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource +import org.apache.tinkerpop.gremlin.process.traversal.P +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ +import org.apache.tinkerpop.gremlin.structure.Direction +import java.lang.reflect.Modifier + +def toCSharpTypeMap = ["Long": "long", + "Integer": "int", + "String": "string", + "Object": "object", + "java.util.Map<java.lang.String, E2>": "IDictionary<string, E2>", + "java.util.Map<java.lang.String, B>": "IDictionary<string, E2>", + "java.util.List<E>": "IList<E>", + "java.util.Map<K, V>": "IDictionary<K, V>", + "java.util.Collection<E2>": "ICollection<E2>", + "java.util.Collection<B>": "ICollection<E2>", + "java.util.Map<K, java.lang.Long>": "IDictionary<K, long>", + "TraversalMetrics": "E2"] + +def useE2 = ["E2", "E2"]; +def methodsWithSpecificTypes = ["constant": useE2, + "limit": useE2, + "mean": useE2, + "optional": useE2, + "range": useE2, + "select": ["IDictionary<string, E2>", "E2"], + "sum": useE2, + "tail": useE2, + "tree": ["object"], + "unfold": useE2] + +def getCSharpGenericTypeParam = { typeName -> + def tParam = "" + if (typeName.contains("E2")) { + tParam = "<E2>" + } + else if (typeName.contains("<K, V>")) { + tParam = "<K, V>" + } + else if (typeName.contains("<K, ")) { + tParam = "<K>" + } + return tParam +} + +def toCSharpType = { name -> + String typeName = toCSharpTypeMap.getOrDefault(name, name); + if (typeName.equals(name) && (typeName.contains("? extends") || typeName.equals("Tree"))) { + typeName = "E2" + } + return typeName; +} + +def toCSharpMethodName = { symbol -> (String) Character.toUpperCase(symbol.charAt(0)) + symbol.substring(1) } + +def getJavaParameterTypeNames = { method -> + def typeArguments = method.genericReturnType.actualTypeArguments; + return typeArguments. + collect { (it instanceof Class) ? ((Class)it).simpleName : it.typeName }. + collect { name -> + if (name.equals("A")) { + name = "object" + } + else if (name.equals("B")) { + name = "E2"; + } + name + } +} + +def binding = ["pmethods": P.class.getMethods(). + findAll { Modifier.isStatic(it.getModifiers()) }. + findAll { P.class.isAssignableFrom(it.returnType) }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "sourceStepMethods": GraphTraversalSource.getMethods(). // SOURCE STEPS + findAll { GraphTraversalSource.class.equals(it.returnType) }. + findAll { + !it.name.equals("clone") && + !it.name.equals(TraversalSource.Symbols.withBindings) && + !it.name.equals(TraversalSource.Symbols.withRemote) && + !it.name.equals(TraversalSource.Symbols.withComputer) + }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "sourceSpawnMethods": GraphTraversalSource.getMethods(). // SPAWN STEPS + findAll { GraphTraversal.class.equals(it.returnType) && !it.name.equals('inject')}. + collect { [methodName: it.name, typeArguments: it.genericReturnType.actualTypeArguments.collect{t -> ((java.lang.Class)t).simpleName}] }. + unique(). + sort { a, b -> a.methodName <=> b.methodName }, + "graphStepMethods": GraphTraversal.getMethods(). + findAll { GraphTraversal.class.equals(it.returnType) }. + findAll { !it.name.equals("clone") && !it.name.equals("iterate") }. + groupBy { it.name }. + // Select unique by name, with the most amount of parameters + collect { it.value.sort { a, b -> b.parameterCount <=> a.parameterCount }.first() }. + sort { a, b -> a.name <=> b.name }. + collect { javaMethod -> + def typeNames = getJavaParameterTypeNames(javaMethod) + def t1 = toCSharpType(typeNames[0]) + def t2 = toCSharpType(typeNames[1]) + def tParam = getCSharpGenericTypeParam(t2) + return ["methodName": javaMethod.name, "t1":t1, "t2":t2, "tParam":tParam] + }, + "anonStepMethods": __.class.getMethods(). + findAll { GraphTraversal.class.equals(it.returnType) }. + findAll { Modifier.isStatic(it.getModifiers()) }. + findAll { !it.name.equals("__") && !it.name.equals("start") }. + groupBy { it.name }. + // Select unique by name, with the most amount of parameters + collect { it.value.sort { a, b -> b.parameterCount <=> a.parameterCount }.first() }. + sort { it.name }. + collect { javaMethod -> + def typeNames = getJavaParameterTypeNames(javaMethod) + def t2 = toCSharpType(typeNames[1]) + def tParam = getCSharpGenericTypeParam(t2) + def specificTypes = methodsWithSpecificTypes.get(javaMethod.name) + if (specificTypes) { + t2 = specificTypes[0] + tParam = specificTypes.size() > 1 ? "<" + specificTypes[1] + ">" : "" + } + return ["methodName": javaMethod.name, "t2":t2, "tParam":tParam] + }, + "toCSharpMethodName": toCSharpMethodName] + +def engine = new groovy.text.GStringTemplateEngine() +def traversalTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/GraphTraversal.template")).make(binding) +def traversalFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs") +traversalFile.newWriter().withWriter{ it << traversalTemplate } + +def graphTraversalTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/GraphTraversalSource.template")).make(binding) +def graphTraversalFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs") +graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate } + +def anonymousTraversalTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/AnonymousTraversal.template")).make(binding) +def anonymousTraversalFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/__.cs") +anonymousTraversalFile.newWriter().withWriter{ it << anonymousTraversalTemplate } + +def pTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/P.template")).make(binding) +def pFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/P.cs") +pFile.newWriter().withWriter{ it << pTemplate } + +// Process enums +def toCSharpName = { enumClass, itemName -> + if (enumClass.equals(Direction.class)) { + itemName = itemName.toLowerCase() + } + + return itemName.substring(0, 1).toUpperCase() + itemName.substring(1) +} + +def createEnum = { enumClass, csharpToJava -> + def b = ["enumClass": enumClass, + "constants": enumClass.getEnumConstants(). + sort { a, b -> a.name() <=> b.name() }. + collect { value -> + def csharpName = toCSharpName(enumClass, value.name()) + csharpToJava.put(enumClass.simpleName + "." + csharpName, value.name()) + return csharpName + }.join(",\n\t\t")] + + def enumTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/Enum.template")).make(b) + def enumFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/" + enumClass.getSimpleName() + ".cs") + enumFile.newWriter().withWriter{ it << enumTemplate } +} + +def enumCSharpToJavaNames = [:] +CoreImports.getClassImports().findAll { Enum.class.isAssignableFrom(it) }. + sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }. + each { createEnum(it, enumCSharpToJavaNames) } + +def lastIndex = (enumCSharpToJavaNames.size() - 1); +def body = new StringBuilder() +enumCSharpToJavaNames.eachWithIndex{ node, i -> + body.append("""{"$node.key", "$node.value"}""") + body.append(i == lastIndex ? "\n" : ",\n ") +} + +def namingConversionsTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/NamingConversions.template")).make(["body":body]) +def namingConversionsFile = new File("${projectBaseDir}/src/Gremlin.Net/Process/Traversal/NamingConversions.cs") +namingConversionsFile.newWriter().withWriter{ it << namingConversionsTemplate } + +def determineVersion = { + def env = System.getenv() + def mavenVersion = env.containsKey("TP_RELEASE_VERSION") ? env.get("DOTNET_RELEASE_VERSION") : "${projectVersion}" + + // only want to generate a timestamp for the version if this is a nuget deploy + if (!mavenVersion.endsWith("-SNAPSHOT") || null == System.getProperty("nuget")) return mavenVersion + + return mavenVersion.replace("-SNAPSHOT", "-dev-" + System.currentTimeMillis()) +} + +def versionToUse = determineVersion() +def csprojTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/Gremlin.Net.csproj.template")).make(["projectVersion":versionToUse]) +def csprojFile = new File("${projectBaseDir}/src/Gremlin.Net/Gremlin.Net.csproj") +csprojFile.newWriter().withWriter{ it << csprojTemplate } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-dotnet/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/pom.xml b/gremlin-dotnet/pom.xml index d2ab17c..a0ef34f 100644 --- a/gremlin-dotnet/pom.xml +++ b/gremlin-dotnet/pom.xml @@ -54,6 +54,7 @@ limitations under the License. <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>${groovy.version}</version> + <classifier>indy</classifier> <scope>runtime</scope> </dependency> <dependency> @@ -71,211 +72,18 @@ limitations under the License. <goal>execute</goal> </goals> <configuration> + <properties> + <property> + <name>projectBaseDir</name> + <value>${project.basedir}</value> + </property> + <property> + <name>projectVersion</name> + <value>${project.version}</value> + </property> + </properties> <scripts> - <script><![CDATA[ -import org.apache.tinkerpop.gremlin.jsr223.CoreImports -import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource -import org.apache.tinkerpop.gremlin.process.traversal.P -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ -import org.apache.tinkerpop.gremlin.structure.Direction -import java.lang.reflect.Modifier - -def toCSharpTypeMap = ["Long": "long", - "Integer": "int", - "String": "string", - "Object": "object", - "java.util.Map<java.lang.String, E2>": "IDictionary<string, E2>", - "java.util.Map<java.lang.String, B>": "IDictionary<string, E2>", - "java.util.List<E>": "IList<E>", - "java.util.Map<K, V>": "IDictionary<K, V>", - "java.util.Collection<E2>": "ICollection<E2>", - "java.util.Collection<B>": "ICollection<E2>", - "java.util.Map<K, java.lang.Long>": "IDictionary<K, long>", - "TraversalMetrics": "E2"] - -def useE2 = ["E2", "E2"]; -def methodsWithSpecificTypes = ["constant": useE2, - "limit": useE2, - "mean": useE2, - "optional": useE2, - "range": useE2, - "select": ["IDictionary<string, E2>", "E2"], - "sum": useE2, - "tail": useE2, - "tree": ["object"], - "unfold": useE2] - -def getCSharpGenericTypeParam = { typeName -> - def tParam = "" - if (typeName.contains("E2")) { - tParam = "<E2>" - } - else if (typeName.contains("<K, V>")) { - tParam = "<K, V>" - } - else if (typeName.contains("<K, ")) { - tParam = "<K>" - } - return tParam -} - -def toCSharpType = { name -> - String typeName = toCSharpTypeMap.getOrDefault(name, name); - if (typeName.equals(name) && (typeName.contains("? extends") || typeName.equals("Tree"))) { - typeName = "E2" - } - return typeName; -} - -def toCSharpMethodName = { symbol -> (String) Character.toUpperCase(symbol.charAt(0)) + symbol.substring(1) } - -def getJavaParameterTypeNames = { method -> - def typeArguments = method.genericReturnType.actualTypeArguments; - return typeArguments. - collect { (it instanceof Class) ? ((Class)it).simpleName : it.typeName }. - collect { name -> - if (name.equals("A")) { - name = "object" - } - else if (name.equals("B")) { - name = "E2"; - } - name - } -} - -def binding = ["pmethods": P.class.getMethods(). - findAll { Modifier.isStatic(it.getModifiers()) }. - findAll { P.class.isAssignableFrom(it.returnType) }. - collect { it.name }. - unique(). - sort { a, b -> a <=> b }, - "sourceStepMethods": GraphTraversalSource.getMethods(). // SOURCE STEPS - findAll { GraphTraversalSource.class.equals(it.returnType) }. - findAll { - !it.name.equals("clone") && - !it.name.equals(TraversalSource.Symbols.withBindings) && - !it.name.equals(TraversalSource.Symbols.withRemote) && - !it.name.equals(TraversalSource.Symbols.withComputer) - }. - collect { it.name }. - unique(). - sort { a, b -> a <=> b }, - "sourceSpawnMethods": GraphTraversalSource.getMethods(). // SPAWN STEPS - findAll { GraphTraversal.class.equals(it.returnType) && !it.name.equals('inject')}. - collect { [methodName: it.name, typeArguments: it.genericReturnType.actualTypeArguments.collect{t -> ((java.lang.Class)t).simpleName}] }. - unique(). - sort { a, b -> a.methodName <=> b.methodName }, - "graphStepMethods": GraphTraversal.getMethods(). - findAll { GraphTraversal.class.equals(it.returnType) }. - findAll { !it.name.equals("clone") && !it.name.equals("iterate") }. - groupBy { it.name }. - // Select unique by name, with the most amount of parameters - collect { it.value.sort { a, b -> b.parameterCount <=> a.parameterCount }.first() }. - sort { a, b -> a.name <=> b.name }. - collect { javaMethod -> - def typeNames = getJavaParameterTypeNames(javaMethod) - def t1 = toCSharpType(typeNames[0]) - def t2 = toCSharpType(typeNames[1]) - def tParam = getCSharpGenericTypeParam(t2) - return ["methodName": javaMethod.name, "t1":t1, "t2":t2, "tParam":tParam] - }, - "anonStepMethods": __.class.getMethods(). - findAll { GraphTraversal.class.equals(it.returnType) }. - findAll { Modifier.isStatic(it.getModifiers()) }. - findAll { !it.name.equals("__") && !it.name.equals("start") }. - groupBy { it.name }. - // Select unique by name, with the most amount of parameters - collect { it.value.sort { a, b -> b.parameterCount <=> a.parameterCount }.first() }. - sort { it.name }. - collect { javaMethod -> - def typeNames = getJavaParameterTypeNames(javaMethod) - def t2 = toCSharpType(typeNames[1]) - def tParam = getCSharpGenericTypeParam(t2) - def specificTypes = methodsWithSpecificTypes.get(javaMethod.name) - if (specificTypes) { - t2 = specificTypes[0] - tParam = specificTypes.size() > 1 ? "<" + specificTypes[1] + ">" : "" - } - return ["methodName": javaMethod.name, "t2":t2, "tParam":tParam] - }, - "toCSharpMethodName": toCSharpMethodName] - -def engine = new groovy.text.GStringTemplateEngine() -def traversalTemplate = engine.createTemplate(new File('${project.basedir}/glv/GraphTraversal.template')).make(binding) -def traversalFile = new File('${project.basedir}/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs') -traversalFile.newWriter().withWriter{ it << traversalTemplate } - -def graphTraversalTemplate = engine.createTemplate(new File('${project.basedir}/glv/GraphTraversalSource.template')).make(binding) -def graphTraversalFile = new File('${project.basedir}/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs') -graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate } - -def anonymousTraversalTemplate = engine.createTemplate(new File('${project.basedir}/glv/AnonymousTraversal.template')).make(binding) -def anonymousTraversalFile = new File('${project.basedir}/src/Gremlin.Net/Process/Traversal/__.cs') -anonymousTraversalFile.newWriter().withWriter{ it << anonymousTraversalTemplate } - -def pTemplate = engine.createTemplate(new File('${project.basedir}/glv/P.template')).make(binding) -def pFile = new File('${project.basedir}/src/Gremlin.Net/Process/Traversal/P.cs') -pFile.newWriter().withWriter{ it << pTemplate } - -// Process enums -def toCSharpName = { enumClass, itemName -> - if (enumClass.equals(Direction.class)) { - itemName = itemName.toLowerCase() - } - - return itemName.substring(0, 1).toUpperCase() + itemName.substring(1) -} - -def createEnum = { enumClass, csharpToJava -> - def b = ["enumClass": enumClass, - "constants": enumClass.getEnumConstants(). - sort { a, b -> a.name() <=> b.name() }. - collect { value -> - def csharpName = toCSharpName(enumClass, value.name()) - csharpToJava.put(enumClass.simpleName + "." + csharpName, value.name()) - return csharpName - }.join(",\n\t\t")] - - def enumTemplate = engine.createTemplate(new File('${project.basedir}/glv/Enum.template')).make(b) - def enumFile = new File('${project.basedir}/src/Gremlin.Net/Process/Traversal/' + enumClass.getSimpleName() + '.cs') - enumFile.newWriter().withWriter{ it << enumTemplate } -} - -def enumCSharpToJavaNames = [:] -CoreImports.getClassImports().findAll { Enum.class.isAssignableFrom(it) }. - sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }. - each { createEnum(it, enumCSharpToJavaNames) } - -def lastIndex = (enumCSharpToJavaNames.size() - 1); -def body = new StringBuilder() -enumCSharpToJavaNames.eachWithIndex{ node, i -> - body.append("""{"$node.key", "$node.value"}""") - body.append(i == lastIndex ? "\n" : ",\n ") -} - -def namingConversionsTemplate = engine.createTemplate(new File('${project.basedir}/glv/NamingConversions.template')).make(["body":body]) -def namingConversionsFile = new File('${project.basedir}/src/Gremlin.Net/Process/Traversal/NamingConversions.cs') -namingConversionsFile.newWriter().withWriter{ it << namingConversionsTemplate } - -def determineVersion = { - def env = System.getenv() - def mavenVersion = env.containsKey("TP_RELEASE_VERSION") ? env.get("DOTNET_RELEASE_VERSION") : '${project.version}' - - // only want to generate a timestamp for the version if this is a nuget deploy - if (!mavenVersion.endsWith("-SNAPSHOT") || null == System.getProperty("nuget")) return mavenVersion - - return mavenVersion.replace("-SNAPSHOT", "-dev-" + System.currentTimeMillis()) -} - -def versionToUse = determineVersion() -def csprojTemplate = engine.createTemplate(new File('${project.basedir}/glv/Gremlin.Net.csproj.template')).make(["projectVersion":versionToUse]) -def csprojFile = new File('${project.basedir}/src/Gremlin.Net/Gremlin.Net.csproj') -csprojFile.newWriter().withWriter{ it << csprojTemplate } -]]> - </script> + <script>${project.basedir}/glv/generate.groovy</script> </scripts> </configuration> </execution> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json index 5788e50..1adda9a 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json @@ -1,5 +1,5 @@ { "TestServerIpAddress": "localhost", - "TestServerPort": 45950, - "TestSecureServerPort": 45951 + "TestServerPort": 45940, + "TestSecureServerPort": 45941 } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-dotnet/test/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/pom.xml b/gremlin-dotnet/test/pom.xml index ea61c22..7b82a2e 100644 --- a/gremlin-dotnet/test/pom.xml +++ b/gremlin-dotnet/test/pom.xml @@ -128,41 +128,22 @@ limitations under the License. <goal>execute</goal> </goals> <configuration> + <properties> + <property> + <name>skipTests</name> + <value>${skipTests}</value> + </property> + <property> + <name>gremlinServerDir</name> + <value>${gremlin.server.dir}</value> + </property> + <property> + <name>executionName</name> + <value>${project.name}</value> + </property> + </properties> <scripts> - <script> - <![CDATA[ -import org.apache.tinkerpop.gremlin.server.GremlinServer -import org.apache.tinkerpop.gremlin.server.Settings -import org.apache.tinkerpop.gremlin.server.Settings.ScriptEngineSettings - -if (${skipTests}) return - -log.info("Starting Gremlin Server instances for native testing of gremlin-dotnet") -def settings = Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern.yaml") -settings.graphs.graph = "${gremlin.server.dir}/conf/tinkergraph-empty.properties" -settings.scriptEngines["gremlin-groovy"].scripts = ["${gremlin.server.dir}/scripts/generate-modern.groovy"] -settings.port = 45950 - -def server = new GremlinServer(settings) -server.start().join() - -project.setContextValue("gremlin.dotnet.server", server) -log.info("Gremlin Server with no authentication started on port 45950") - -def settingsSecure = Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern.yaml") -settingsSecure.graphs.graph = "${gremlin.server.dir}/conf/tinkergraph-empty.properties" -settingsSecure.scriptEngines["gremlin-groovy"].scripts = ["${gremlin.server.dir}/scripts/generate-modern.groovy"] -settingsSecure.port = 45951 -settingsSecure.authentication.className = "org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator" -settingsSecure.authentication.config = [credentialsDb: "${gremlin.server.dir}/conf/tinkergraph-credentials.properties", credentialsDbLocation: "${gremlin.server.dir}/data/credentials.kryo"] - -def serverSecure = new GremlinServer(settingsSecure) -serverSecure.start().join() - -project.setContextValue("gremlin.dotnet.server.secure", serverSecure) -log.info("Gremlin Server with authentication started on port 45951") -]]> - </script> + <script>${gremlin.server.dir}/src/test/scripts/test-server-start.groovy</script> </scripts> </configuration> </execution> @@ -173,26 +154,18 @@ log.info("Gremlin Server with authentication started on port 45951") <goal>execute</goal> </goals> <configuration> + <properties> + <property> + <name>skipTests</name> + <value>${skipTests}</value> + </property> + <property> + <name>executionName</name> + <value>${project.name}</value> + </property> + </properties> <scripts> - <script> - <![CDATA[ -import org.apache.tinkerpop.gremlin.server.GremlinServer - -if (${skipTests}) return - -log.info("Tests for native gremlin-dotnet complete") - -def server = project.getContextValue("gremlin.dotnet.server") -log.info("Shutting down $server") -server.stop().join() - -def serverSecure = project.getContextValue("gremlin.dotnet.server.secure") -log.info("Shutting down $serverSecure") -serverSecure.stop().join() - -log.info("Gremlin Server instance shutdown for gremlin-dotnet") -]]> - </script> + <script>${gremlin.server.dir}/src/test/scripts/test-server-stop.groovy</script> </scripts> </configuration> </execution> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-groovy-test/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-groovy-test/pom.xml b/gremlin-groovy-test/pom.xml index ef96f0c..4fa6ea5 100644 --- a/gremlin-groovy-test/pom.xml +++ b/gremlin-groovy-test/pom.xml @@ -50,6 +50,20 @@ limitations under the License. <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>addSources</goal> + <goal>addTestSources</goal> + <goal>generateStubs</goal> + <goal>compile</goal> + <goal>generateTestStubs</goal> + <goal>compileTests</goal> + <goal>removeStubs</goal> + <goal>removeTestStubs</goal> + </goals> + </execution> + </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-groovy/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-groovy/pom.xml b/gremlin-groovy/pom.xml index 0a10534..53806ab 100644 --- a/gremlin-groovy/pom.xml +++ b/gremlin-groovy/pom.xml @@ -113,6 +113,20 @@ limitations under the License. <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>addSources</goal> + <goal>addTestSources</goal> + <goal>generateStubs</goal> + <goal>compile</goal> + <goal>generateTestStubs</goal> + <goal>compileTests</goal> + <goal>removeStubs</goal> + <goal>removeTestStubs</goal> + </goals> + </execution> + </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/glv/GraphTraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-python/glv/GraphTraversalSource.template b/gremlin-python/glv/GraphTraversalSource.template new file mode 100644 index 0000000..54b339e --- /dev/null +++ b/gremlin-python/glv/GraphTraversalSource.template @@ -0,0 +1,102 @@ +''' +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. +''' + +import sys +from .traversal import Traversal +from .traversal import TraversalStrategies +from .strategies import VertexProgramStrategy +from .traversal import Bytecode +from ..driver.remote_connection import RemoteStrategy +from .. import statics +from ..statics import long + +class GraphTraversalSource(object): + def __init__(self, graph, traversal_strategies, bytecode=None): + self.graph = graph + self.traversal_strategies = traversal_strategies + if bytecode is None: + bytecode = Bytecode() + self.bytecode = bytecode + self.graph_traversal = GraphTraversal + def __repr__(self): + return "graphtraversalsource[" + str(self.graph) + "]" + def get_graph_traversal_source(self): + return self.__class__(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode)) + def get_graph_traversal(self): + return self.graph_traversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode)) + +<% sourceStepMethods.each{ method -> %> + def <%= method %>(self, *args): + source = self.get_graph_traversal_source() + source.bytecode.add_source("<%= toJava.call(method) %>", *args) + return source +<% } %> + + def withRemote(self, remote_connection): + source = self.get_graph_traversal_source() + source.traversal_strategies.add_strategies([RemoteStrategy(remote_connection)]) + return source + def withComputer(self,graph_computer=None, workers=None, result=None, persist=None, vertices=None, edges=None, configuration=None): + return self.withStrategies(VertexProgramStrategy(graph_computer,workers,result,persist,vertices,edges,configuration)) + +<% sourceSpawnMethods.each { method -> %> + def <%= method %>(self, *args): + traversal = self.get_graph_traversal() + traversal.bytecode.add_step("<%= toJava.call(method) %>", *args) + return traversal +<% } %> + +class GraphTraversal(Traversal): + def __init__(self, graph, traversal_strategies, bytecode): + super(GraphTraversal, self).__init__(graph, traversal_strategies, bytecode) + def __getitem__(self, index): + if isinstance(index, int): + return self.range(long(index), long(index + 1)) + elif isinstance(index, slice): + return self.range(long(0) if index.start is None else long(index.start), long(sys.maxsize) if index.stop is None else long(index.stop)) + else: + raise TypeError("Index must be int or slice") + def __getattr__(self, key): + return self.values(key) +<% graphStepMethods.each { method -> %> + def <%= method %>(self, *args): + self.bytecode.add_step("<%= toJava.call(method) %>", *args) + return self +<% } %> + +class __(object): + graph_traversal = GraphTraversal + @classmethod + def start(cls): + return GraphTraversal(None, None, Bytecode()) + @classmethod + def __(cls, *args): + return __.inject(*args) + +<% anonStepMethods.each{ method -> %> + @classmethod + def <%= method %>(cls, *args): + return cls.graph_traversal(None, None, Bytecode()).<%= method %>(*args) +<% } %> + +<% anonStepMethods.each{ method -> %> +def <%= method %>(*args): + return __.<%= method %>(*args) +statics.add_static('<%= method %>', <%= method %>) +<% } %> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/glv/TraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-python/glv/TraversalSource.template b/gremlin-python/glv/TraversalSource.template new file mode 100644 index 0000000..66ea940 --- /dev/null +++ b/gremlin-python/glv/TraversalSource.template @@ -0,0 +1,282 @@ +''' +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. +''' + +from aenum import Enum +from .. import statics +from ..statics import long + +class Traversal(object): + def __init__(self, graph, traversal_strategies, bytecode): + self.graph = graph + self.traversal_strategies = traversal_strategies + self.bytecode = bytecode + self.side_effects = TraversalSideEffects() + self.traversers = None + self.last_traverser = None + def __repr__(self): + return str(self.bytecode) + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.bytecode == other.bytecode + else: + return False + def __iter__(self): + return self + def __next__(self): + if self.traversers is None: + self.traversal_strategies.apply_strategies(self) + if self.last_traverser is None: + self.last_traverser = next(self.traversers) + object = self.last_traverser.object + self.last_traverser.bulk = self.last_traverser.bulk - 1 + if self.last_traverser.bulk <= 0: + self.last_traverser = None + return object + def toList(self): + return list(iter(self)) + def toSet(self): + return set(iter(self)) + def iterate(self): + while True: + try: self.nextTraverser() + except StopIteration: return self + def nextTraverser(self): + if self.traversers is None: + self.traversal_strategies.apply_strategies(self) + if self.last_traverser is None: + return next(self.traversers) + else: + temp = self.last_traverser + self.last_traverser = None + return temp + def next(self, amount=None): + if amount is None: + return self.__next__() + else: + count = 0 + tempList = [] + while count < amount: + count = count + 1 + try: temp = self.__next__() + except StopIteration: return tempList + tempList.append(temp) + return tempList + def promise(self, cb=None): + self.traversal_strategies.apply_async_strategies(self) + future_traversal = self.remote_results + future = type(future_traversal)() + def process(f): + try: + traversal = f.result() + except Exception as e: + future.set_exception(e) + else: + self.traversers = iter(traversal.traversers) + self.side_effects = traversal.side_effects + if cb: + try: + result = cb(self) + except Exception as e: + future.set_exception(e) + else: + future.set_result(result) + else: + future.set_result(self) + future_traversal.add_done_callback(process) + return future + +<% enums.each { e -> %> +<%= e.getSimpleName() %> = Enum('<%= e.getSimpleName() %>', ' <%= e.getEnumConstants().sort{a, b -> a.name() <=> b.name()}.collect{v -> toPython.call(v.name())}.join(" ") %>') +<% e.getEnumConstants().each {v -> %> +statics.add_static('<%= toPython.call(v.name()) %>', <%= v.getDeclaringClass().getSimpleName() %>.<%= toPython.call(v.name()) %>)<% } %> +<% } %> + +class P(object): + def __init__(self, operator, value, other=None): + self.operator = operator + self.value = value + self.other = other + +<% pmethods.each { method -> %> + @staticmethod + def <%= method %>(*args): + return P("<%= toPython.call(method) %>", *args) +<% } %> + def and_(self, arg): + return P("and", self, arg) + def or_(self, arg): + return P("or", self, arg) + def __eq__(self, other): + return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other + def __repr__(self): + return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")" + def and_(self, arg): + return P("and", self, arg) + def or_(self, arg): + return P("or", self, arg) + def __eq__(self, other): + return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other + def __repr__(self): + return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")" +<% pmethods.findAll{!it.equals("clone")}.each { method -> %> +def <%= method %>(*args): + return P.<%= method %>(*args) +statics.add_static('<%= method %>',<%= method %>) +<% } %> + +''' +TRAVERSER +''' + +class Traverser(object): + def __init__(self, object, bulk=None): + if bulk is None: + bulk = long(1) + self.object = object + self.bulk = bulk + def __repr__(self): + return str(self.object) + def __eq__(self, other): + return isinstance(other, self.__class__) and self.object == other.object + +''' +TRAVERSAL SIDE-EFFECTS +''' + +class TraversalSideEffects(object): + def keys(self): + return set() + def get(self, key): + raise KeyError(key) + def __getitem__(self, key): + return self.get(key) + def __repr__(self): + return "sideEffects[size:" + str(len(self.keys())) + "]" + +''' +TRAVERSAL STRATEGIES +''' + +class TraversalStrategies(object): + global_cache = {} + def __init__(self, traversal_strategies=None): + self.traversal_strategies = traversal_strategies.traversal_strategies if traversal_strategies is not None else [] + def add_strategies(self, traversal_strategies): + self.traversal_strategies = self.traversal_strategies + traversal_strategies + def apply_strategies(self, traversal): + for traversal_strategy in self.traversal_strategies: + traversal_strategy.apply(traversal) + def apply_async_strategies(self, traversal): + for traversal_strategy in self.traversal_strategies: + traversal_strategy.apply_async(traversal) + def __repr__(self): + return str(self.traversal_strategies) + + +class TraversalStrategy(object): + def __init__(self, strategy_name=None, configuration=None): + self.strategy_name = type(self).__name__ if strategy_name is None else strategy_name + self.configuration = {} if configuration is None else configuration + def apply(self, traversal): + return + def apply_async(self, traversal): + return + def __eq__(self, other): + return isinstance(other, self.__class__) + def __hash__(self): + return hash(self.strategy_name) + def __repr__(self): + return self.strategy_name + +''' +BYTECODE +''' + +class Bytecode(object): + def __init__(self, bytecode=None): + self.source_instructions = [] + self.step_instructions = [] + self.bindings = {} + if bytecode is not None: + self.source_instructions = list(bytecode.source_instructions) + self.step_instructions = list(bytecode.step_instructions) + def add_source(self, source_name, *args): + instruction = [source_name] + for arg in args: + instruction.append(self.__convertArgument(arg)) + self.source_instructions.append(instruction) + def add_step(self, step_name, *args): + instruction = [step_name] + for arg in args: + instruction.append(self.__convertArgument(arg)) + self.step_instructions.append(instruction) + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.source_instructions == other.source_instructions and self.step_instructions == other.step_instructions + else: + return False + def __convertArgument(self,arg): + if isinstance(arg, Traversal): + self.bindings.update(arg.bytecode.bindings) + return arg.bytecode + elif isinstance(arg, dict): + newDict = {} + for key in arg: + newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key]) + return newDict + elif isinstance(arg, list): + newList = [] + for item in arg: + newList.append(self.__convertArgument(item)) + return newList + elif isinstance(arg, set): + newSet = set() + for item in arg: + newSet.add(self.__convertArgument(item)) + return newSet + elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str): + self.bindings[arg[0]] = arg[1] + return Binding(arg[0],self.__convertArgument(arg[1])) + else: + return arg + def __repr__(self): + return (str(self.source_instructions) if len(self.source_instructions) > 0 else "") + \\ + (str(self.step_instructions) if len(self.step_instructions) > 0 else "") + + +''' +BINDINGS +''' + +class Bindings(object): + def of(self,key,value): + if not isinstance(key, str): + raise TypeError("Key must be str") + return (key,value) + +class Binding(object): + def __init__(self,key,value): + self.key = key + self.value = value + def __eq__(self, other): + return isinstance(other, self.__class__) and self.key == other.key and self.value == other.value + def __hash__(self): + return hash(self.key) + hash(self.value) + def __repr__(self): + return "binding[" + self.key + "=" + str(self.value) + "]" \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-python/glv/generate.groovy b/gremlin-python/glv/generate.groovy new file mode 100644 index 0000000..4873d12 --- /dev/null +++ b/gremlin-python/glv/generate.groovy @@ -0,0 +1,94 @@ +/* + * 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. + */ + +import org.apache.tinkerpop.gremlin.jsr223.CoreImports +import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource +import org.apache.tinkerpop.gremlin.process.traversal.P +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ +import java.lang.reflect.Modifier + +// this is a bit of a copy of what's in SymbolHelper - no way around it because this code generation task occurs +// before the SymbolHelper is available to the plugin. +def toPythonMap = ["global": "global_", + "as": "as_", + "in": "in_", + "and": "and_", + "or": "or_", + "is": "is_", + "not": "not_", + "from": "from_", + "list": "list_", + "set": "set_", + "all": "all_"] +def toJavaMap = toPythonMap.collectEntries{k,v -> [(v):k]} + +def toPython = { symbol -> toPythonMap.getOrDefault(symbol, symbol) } +def toJava = { symbol -> toJavaMap.getOrDefault(symbol, symbol) } + +def binding = ["enums": CoreImports.getClassImports() + .findAll { Enum.class.isAssignableFrom(it) } + .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }, + "pmethods": P.class.getMethods(). + findAll { Modifier.isStatic(it.getModifiers()) }. + findAll { P.class.isAssignableFrom(it.returnType) }. + collect { toPython(it.name) }. + unique(). + sort { a, b -> a <=> b }, + "sourceStepMethods": GraphTraversalSource.getMethods(). // SOURCE STEPS + findAll { GraphTraversalSource.class.equals(it.returnType) }. + findAll { + !it.name.equals("clone") && + !it.name.equals(TraversalSource.Symbols.withBindings) && + !it.name.equals(TraversalSource.Symbols.withRemote) && + !it.name.equals(TraversalSource.Symbols.withComputer) + }. + collect { toPython(it.name) }. + unique(). + sort { a, b -> a <=> b }, + "sourceSpawnMethods": GraphTraversalSource.getMethods(). // SPAWN STEPS + findAll { GraphTraversal.class.equals(it.returnType) }. + collect { toPython(it.name) }. + unique(). + sort { a, b -> a <=> b }, + "graphStepMethods": GraphTraversal.getMethods(). + findAll { GraphTraversal.class.equals(it.returnType) }. + findAll { !it.name.equals("clone") && !it.name.equals("iterate") }. + collect { toPython(it.name) }. + unique(). + sort { a, b -> a <=> b }, + "anonStepMethods": __.class.getMethods(). + findAll { GraphTraversal.class.equals(it.returnType) }. + findAll { Modifier.isStatic(it.getModifiers()) }. + findAll { !it.name.equals("__") && !it.name.equals("start") }. + collect { toPython(it.name) }. + unique(). + sort { a, b -> a <=> b }, + "toPython": toPython, + "toJava": toJava] + +def engine = new groovy.text.GStringTemplateEngine() +def traversalTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/TraversalSource.template")).make(binding) +def traversalFile = new File("${projectBaseDir}/src/main/jython/gremlin_python/process/traversal.py") +traversalFile.newWriter().withWriter{ it << traversalTemplate } + +def graphTraversalTemplate = engine.createTemplate(new File("${projectBaseDir}/glv/GraphTraversalSource.template")).make(binding) +def graphTraversalFile = new File("${projectBaseDir}/src/main/jython/gremlin_python/process/graph_traversal.py") +graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml index 1b70325..b60b867 100644 --- a/gremlin-python/pom.xml +++ b/gremlin-python/pom.xml @@ -467,7 +467,8 @@ limitations under the License. <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> - <version>${groovy.version}</version> + <version>2.4.11</version> + <classifier>indy</classifier> <scope>runtime</scope> </dependency> <dependency> @@ -485,84 +486,14 @@ limitations under the License. <goal>execute</goal> </goals> <configuration> + <properties> + <property> + <name>projectBaseDir</name> + <value>${project.basedir}</value> + </property> + </properties> <scripts> - <script><![CDATA[ -import org.apache.tinkerpop.gremlin.jsr223.CoreImports -import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource -import org.apache.tinkerpop.gremlin.process.traversal.P -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ -import java.lang.reflect.Modifier - -// this is a bit of a copy of what's in SymbolHelper - no way around it because this code generation task occurs -// before the SymbolHelper is available to the plugin. -def toPythonMap = ["global": "global_", - "as": "as_", - "in": "in_", - "and": "and_", - "or": "or_", - "is": "is_", - "not": "not_", - "from": "from_", - "list": "list_", - "set": "set_", - "all": "all_"] -def toJavaMap = toPythonMap.collectEntries{k,v -> [(v):k]} - -def toPython = { symbol -> toPythonMap.getOrDefault(symbol, symbol) } -def toJava = { symbol -> toJavaMap.getOrDefault(symbol, symbol) } - -def binding = ["enums": CoreImports.getClassImports() - .findAll { Enum.class.isAssignableFrom(it) } - .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }, - "pmethods": P.class.getMethods(). - findAll { Modifier.isStatic(it.getModifiers()) }. - findAll { P.class.isAssignableFrom(it.returnType) }. - collect { toPython(it.name) }. - unique(). - sort { a, b -> a <=> b }, - "sourceStepMethods": GraphTraversalSource.getMethods(). // SOURCE STEPS - findAll { GraphTraversalSource.class.equals(it.returnType) }. - findAll { - !it.name.equals("clone") && - !it.name.equals(TraversalSource.Symbols.withBindings) && - !it.name.equals(TraversalSource.Symbols.withRemote) && - !it.name.equals(TraversalSource.Symbols.withComputer) - }. - collect { toPython(it.name) }. - unique(). - sort { a, b -> a <=> b }, - "sourceSpawnMethods": GraphTraversalSource.getMethods(). // SPAWN STEPS - findAll { GraphTraversal.class.equals(it.returnType) }. - collect { toPython(it.name) }. - unique(). - sort { a, b -> a <=> b }, - "graphStepMethods": GraphTraversal.getMethods(). - findAll { GraphTraversal.class.equals(it.returnType) }. - findAll { !it.name.equals("clone") && !it.name.equals("iterate") }. - collect { toPython(it.name) }. - unique(). - sort { a, b -> a <=> b }, - "anonStepMethods": __.class.getMethods(). - findAll { GraphTraversal.class.equals(it.returnType) }. - findAll { Modifier.isStatic(it.getModifiers()) }. - findAll { !it.name.equals("__") && !it.name.equals("start") }. - collect { toPython(it.name) }. - unique(). - sort { a, b -> a <=> b }, - "toPython": toPython, - "toJava": toJava] - -def engine = new groovy.text.GStringTemplateEngine() -def traversalTemplate = engine.createTemplate(new File('${project.basedir}/src/main/resources/TraversalSource.template')).make(binding) -def traversalFile = new File('${project.basedir}/src/main/jython/gremlin_python/process/traversal.py') -traversalFile.newWriter().withWriter{ it << traversalTemplate } - -def graphTraversalTemplate = engine.createTemplate(new File('${project.basedir}/src/main/resources/GraphTraversalSource.template')).make(binding) -def graphTraversalFile = new File('${project.basedir}/src/main/jython/gremlin_python/process/graph_traversal.py') -graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate } -]]> </script> + <script>${project.basedir}/glv/generate.groovy</script> </scripts> </configuration> </execution> @@ -573,41 +504,22 @@ graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate } <goal>execute</goal> </goals> <configuration> + <properties> + <property> + <name>skipTests</name> + <value>${skipTests}</value> + </property> + <property> + <name>gremlinServerDir</name> + <value>${gremlin.server.dir}</value> + </property> + <property> + <name>executionName</name> + <value>${project.name}</value> + </property> + </properties> <scripts> - <script> - <![CDATA[ -import org.apache.tinkerpop.gremlin.server.GremlinServer -import org.apache.tinkerpop.gremlin.server.Settings -import org.apache.tinkerpop.gremlin.server.Settings.ScriptEngineSettings - -if (${skipTests}) return - -log.info("Starting Gremlin Server instances for native testing of gremlin-python") -def settings = Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern-py.yaml") -settings.graphs.graph = "${gremlin.server.dir}/conf/tinkergraph-empty.properties" -settings.scriptEngines["gremlin-groovy"].scripts = ["${gremlin.server.dir}/scripts/generate-modern.groovy"] -settings.port = 45940 - -def server = new GremlinServer(settings) -server.start().join() - -project.setContextValue("gremlin.py.server", server) -log.info("Gremlin Server with no authentication started on port 45940") - -def settingsSecure = Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern-py.yaml") -settingsSecure.graphs.graph = "${gremlin.server.dir}/conf/tinkergraph-empty.properties" -settingsSecure.scriptEngines["gremlin-groovy"].scripts = ["${gremlin.server.dir}/scripts/generate-modern.groovy"] -settingsSecure.port = 45941 -settingsSecure.authentication.className = "org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator" -settingsSecure.authentication.config = [credentialsDb: "${gremlin.server.dir}/conf/tinkergraph-credentials.properties"] - -def serverSecure = new GremlinServer(settingsSecure) -serverSecure.start().join() - -project.setContextValue("gremlin.py.server.secure", serverSecure) -log.info("Gremlin Server with authentication started on port 45941") -]]> - </script> + <script>${gremlin.server.dir}/src/test/scripts/test-server-start.groovy</script> </scripts> </configuration> </execution> @@ -618,26 +530,18 @@ log.info("Gremlin Server with authentication started on port 45941") <goal>execute</goal> </goals> <configuration> + <properties> + <property> + <name>skipTests</name> + <value>${skipTests}</value> + </property> + <property> + <name>executionName</name> + <value>${project.name}</value> + </property> + </properties> <scripts> - <script> - <![CDATA[ -import org.apache.tinkerpop.gremlin.server.GremlinServer - -if (${skipTests}) return - -log.info("Tests for native gremlin-python complete") - -def server = project.getContextValue("gremlin.py.server") -log.info("Shutting down $server") -server.stop().join() - -def serverSecure = project.getContextValue("gremlin.py.server.secure") -log.info("Shutting down $serverSecure") -serverSecure.stop().join() - -log.info("All Gremlin Server instances are shutdown for gremlin-python") -]]> - </script> + <script>${gremlin.server.dir}/src/test/scripts/test-server-stop.groovy</script> </scripts> </configuration> </execution> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/src/main/resources/GraphTraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/resources/GraphTraversalSource.template b/gremlin-python/src/main/resources/GraphTraversalSource.template deleted file mode 100644 index 54b339e..0000000 --- a/gremlin-python/src/main/resources/GraphTraversalSource.template +++ /dev/null @@ -1,102 +0,0 @@ -''' -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. -''' - -import sys -from .traversal import Traversal -from .traversal import TraversalStrategies -from .strategies import VertexProgramStrategy -from .traversal import Bytecode -from ..driver.remote_connection import RemoteStrategy -from .. import statics -from ..statics import long - -class GraphTraversalSource(object): - def __init__(self, graph, traversal_strategies, bytecode=None): - self.graph = graph - self.traversal_strategies = traversal_strategies - if bytecode is None: - bytecode = Bytecode() - self.bytecode = bytecode - self.graph_traversal = GraphTraversal - def __repr__(self): - return "graphtraversalsource[" + str(self.graph) + "]" - def get_graph_traversal_source(self): - return self.__class__(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode)) - def get_graph_traversal(self): - return self.graph_traversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode)) - -<% sourceStepMethods.each{ method -> %> - def <%= method %>(self, *args): - source = self.get_graph_traversal_source() - source.bytecode.add_source("<%= toJava.call(method) %>", *args) - return source -<% } %> - - def withRemote(self, remote_connection): - source = self.get_graph_traversal_source() - source.traversal_strategies.add_strategies([RemoteStrategy(remote_connection)]) - return source - def withComputer(self,graph_computer=None, workers=None, result=None, persist=None, vertices=None, edges=None, configuration=None): - return self.withStrategies(VertexProgramStrategy(graph_computer,workers,result,persist,vertices,edges,configuration)) - -<% sourceSpawnMethods.each { method -> %> - def <%= method %>(self, *args): - traversal = self.get_graph_traversal() - traversal.bytecode.add_step("<%= toJava.call(method) %>", *args) - return traversal -<% } %> - -class GraphTraversal(Traversal): - def __init__(self, graph, traversal_strategies, bytecode): - super(GraphTraversal, self).__init__(graph, traversal_strategies, bytecode) - def __getitem__(self, index): - if isinstance(index, int): - return self.range(long(index), long(index + 1)) - elif isinstance(index, slice): - return self.range(long(0) if index.start is None else long(index.start), long(sys.maxsize) if index.stop is None else long(index.stop)) - else: - raise TypeError("Index must be int or slice") - def __getattr__(self, key): - return self.values(key) -<% graphStepMethods.each { method -> %> - def <%= method %>(self, *args): - self.bytecode.add_step("<%= toJava.call(method) %>", *args) - return self -<% } %> - -class __(object): - graph_traversal = GraphTraversal - @classmethod - def start(cls): - return GraphTraversal(None, None, Bytecode()) - @classmethod - def __(cls, *args): - return __.inject(*args) - -<% anonStepMethods.each{ method -> %> - @classmethod - def <%= method %>(cls, *args): - return cls.graph_traversal(None, None, Bytecode()).<%= method %>(*args) -<% } %> - -<% anonStepMethods.each{ method -> %> -def <%= method %>(*args): - return __.<%= method %>(*args) -statics.add_static('<%= method %>', <%= method %>) -<% } %> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/src/main/resources/TraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/resources/TraversalSource.template b/gremlin-python/src/main/resources/TraversalSource.template deleted file mode 100644 index 66ea940..0000000 --- a/gremlin-python/src/main/resources/TraversalSource.template +++ /dev/null @@ -1,282 +0,0 @@ -''' -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. -''' - -from aenum import Enum -from .. import statics -from ..statics import long - -class Traversal(object): - def __init__(self, graph, traversal_strategies, bytecode): - self.graph = graph - self.traversal_strategies = traversal_strategies - self.bytecode = bytecode - self.side_effects = TraversalSideEffects() - self.traversers = None - self.last_traverser = None - def __repr__(self): - return str(self.bytecode) - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.bytecode == other.bytecode - else: - return False - def __iter__(self): - return self - def __next__(self): - if self.traversers is None: - self.traversal_strategies.apply_strategies(self) - if self.last_traverser is None: - self.last_traverser = next(self.traversers) - object = self.last_traverser.object - self.last_traverser.bulk = self.last_traverser.bulk - 1 - if self.last_traverser.bulk <= 0: - self.last_traverser = None - return object - def toList(self): - return list(iter(self)) - def toSet(self): - return set(iter(self)) - def iterate(self): - while True: - try: self.nextTraverser() - except StopIteration: return self - def nextTraverser(self): - if self.traversers is None: - self.traversal_strategies.apply_strategies(self) - if self.last_traverser is None: - return next(self.traversers) - else: - temp = self.last_traverser - self.last_traverser = None - return temp - def next(self, amount=None): - if amount is None: - return self.__next__() - else: - count = 0 - tempList = [] - while count < amount: - count = count + 1 - try: temp = self.__next__() - except StopIteration: return tempList - tempList.append(temp) - return tempList - def promise(self, cb=None): - self.traversal_strategies.apply_async_strategies(self) - future_traversal = self.remote_results - future = type(future_traversal)() - def process(f): - try: - traversal = f.result() - except Exception as e: - future.set_exception(e) - else: - self.traversers = iter(traversal.traversers) - self.side_effects = traversal.side_effects - if cb: - try: - result = cb(self) - except Exception as e: - future.set_exception(e) - else: - future.set_result(result) - else: - future.set_result(self) - future_traversal.add_done_callback(process) - return future - -<% enums.each { e -> %> -<%= e.getSimpleName() %> = Enum('<%= e.getSimpleName() %>', ' <%= e.getEnumConstants().sort{a, b -> a.name() <=> b.name()}.collect{v -> toPython.call(v.name())}.join(" ") %>') -<% e.getEnumConstants().each {v -> %> -statics.add_static('<%= toPython.call(v.name()) %>', <%= v.getDeclaringClass().getSimpleName() %>.<%= toPython.call(v.name()) %>)<% } %> -<% } %> - -class P(object): - def __init__(self, operator, value, other=None): - self.operator = operator - self.value = value - self.other = other - -<% pmethods.each { method -> %> - @staticmethod - def <%= method %>(*args): - return P("<%= toPython.call(method) %>", *args) -<% } %> - def and_(self, arg): - return P("and", self, arg) - def or_(self, arg): - return P("or", self, arg) - def __eq__(self, other): - return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other - def __repr__(self): - return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")" - def and_(self, arg): - return P("and", self, arg) - def or_(self, arg): - return P("or", self, arg) - def __eq__(self, other): - return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other - def __repr__(self): - return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")" -<% pmethods.findAll{!it.equals("clone")}.each { method -> %> -def <%= method %>(*args): - return P.<%= method %>(*args) -statics.add_static('<%= method %>',<%= method %>) -<% } %> - -''' -TRAVERSER -''' - -class Traverser(object): - def __init__(self, object, bulk=None): - if bulk is None: - bulk = long(1) - self.object = object - self.bulk = bulk - def __repr__(self): - return str(self.object) - def __eq__(self, other): - return isinstance(other, self.__class__) and self.object == other.object - -''' -TRAVERSAL SIDE-EFFECTS -''' - -class TraversalSideEffects(object): - def keys(self): - return set() - def get(self, key): - raise KeyError(key) - def __getitem__(self, key): - return self.get(key) - def __repr__(self): - return "sideEffects[size:" + str(len(self.keys())) + "]" - -''' -TRAVERSAL STRATEGIES -''' - -class TraversalStrategies(object): - global_cache = {} - def __init__(self, traversal_strategies=None): - self.traversal_strategies = traversal_strategies.traversal_strategies if traversal_strategies is not None else [] - def add_strategies(self, traversal_strategies): - self.traversal_strategies = self.traversal_strategies + traversal_strategies - def apply_strategies(self, traversal): - for traversal_strategy in self.traversal_strategies: - traversal_strategy.apply(traversal) - def apply_async_strategies(self, traversal): - for traversal_strategy in self.traversal_strategies: - traversal_strategy.apply_async(traversal) - def __repr__(self): - return str(self.traversal_strategies) - - -class TraversalStrategy(object): - def __init__(self, strategy_name=None, configuration=None): - self.strategy_name = type(self).__name__ if strategy_name is None else strategy_name - self.configuration = {} if configuration is None else configuration - def apply(self, traversal): - return - def apply_async(self, traversal): - return - def __eq__(self, other): - return isinstance(other, self.__class__) - def __hash__(self): - return hash(self.strategy_name) - def __repr__(self): - return self.strategy_name - -''' -BYTECODE -''' - -class Bytecode(object): - def __init__(self, bytecode=None): - self.source_instructions = [] - self.step_instructions = [] - self.bindings = {} - if bytecode is not None: - self.source_instructions = list(bytecode.source_instructions) - self.step_instructions = list(bytecode.step_instructions) - def add_source(self, source_name, *args): - instruction = [source_name] - for arg in args: - instruction.append(self.__convertArgument(arg)) - self.source_instructions.append(instruction) - def add_step(self, step_name, *args): - instruction = [step_name] - for arg in args: - instruction.append(self.__convertArgument(arg)) - self.step_instructions.append(instruction) - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.source_instructions == other.source_instructions and self.step_instructions == other.step_instructions - else: - return False - def __convertArgument(self,arg): - if isinstance(arg, Traversal): - self.bindings.update(arg.bytecode.bindings) - return arg.bytecode - elif isinstance(arg, dict): - newDict = {} - for key in arg: - newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key]) - return newDict - elif isinstance(arg, list): - newList = [] - for item in arg: - newList.append(self.__convertArgument(item)) - return newList - elif isinstance(arg, set): - newSet = set() - for item in arg: - newSet.add(self.__convertArgument(item)) - return newSet - elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str): - self.bindings[arg[0]] = arg[1] - return Binding(arg[0],self.__convertArgument(arg[1])) - else: - return arg - def __repr__(self): - return (str(self.source_instructions) if len(self.source_instructions) > 0 else "") + \\ - (str(self.step_instructions) if len(self.step_instructions) > 0 else "") - - -''' -BINDINGS -''' - -class Bindings(object): - def of(self,key,value): - if not isinstance(key, str): - raise TypeError("Key must be str") - return (key,value) - -class Binding(object): - def __init__(self,key,value): - self.key = key - self.value = value - def __eq__(self, other): - return isinstance(other, self.__class__) and self.key == other.key and self.value == other.value - def __hash__(self): - return hash(self.key) + hash(self.value) - def __repr__(self): - return "binding[" + self.key + "=" + str(self.value) + "]" \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e9801e6a/gremlin-python/src/test/resources/org/apache/tinkerpop/gremlin/python/driver/credentials.kryo ---------------------------------------------------------------------- diff --git a/gremlin-python/src/test/resources/org/apache/tinkerpop/gremlin/python/driver/credentials.kryo b/gremlin-python/src/test/resources/org/apache/tinkerpop/gremlin/python/driver/credentials.kryo deleted file mode 100644 index 163d2ef..0000000 Binary files a/gremlin-python/src/test/resources/org/apache/tinkerpop/gremlin/python/driver/credentials.kryo and /dev/null differ