http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs new file mode 100644 index 0000000..3443e71 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Reorders filter- and order-steps according to their rank. + /// </summary> + public class FilterRankingStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs new file mode 100644 index 0000000..aaaee2c --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs @@ -0,0 +1,29 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + public class GraphFilterStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs new file mode 100644 index 0000000..08a4c46 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Looks for <c>Identity()</c>-steps and removes them. + /// </summary> + public class IdentityRemovalStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs new file mode 100644 index 0000000..75b98c2 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs @@ -0,0 +1,33 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Replaces <c>.OutE().InV()</c> with <c>.Out()</c>, <c>.InE().OutV()</c> with <c>In()</c> and <c>.BothE().BothV()</c> + /// with <c>Both()</c>. + /// </summary> + public class IncidentToAdjacentStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs new file mode 100644 index 0000000..8eade84 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Analyzes filter-steps with child traversals that themselves are pure filters. + /// </summary> + public class InlineFilterStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs new file mode 100644 index 0000000..b5cac4a --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs @@ -0,0 +1,33 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Inserts <c>Barrier()</c>-steps into a <see cref="ITraversal" /> where appropriate in order to gain the "bulking + /// optimization". + /// </summary> + public class LazyBarrierStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs new file mode 100644 index 0000000..d535963 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Folds any post<c>Where()</c> step that maintains a traversal constraint into <c>Match()</c>. + /// </summary> + public class MatchPredicateStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs new file mode 100644 index 0000000..82a8df9 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs @@ -0,0 +1,29 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + public class OrderLimitStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs new file mode 100644 index 0000000..2c8e106 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Helps to ensure that more traversals meet the local child constraint imposed on OLAP traversals. + /// </summary> + public class PathProcessorStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs new file mode 100644 index 0000000..e54fbb5 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs @@ -0,0 +1,29 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + public class PathRetractionStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs new file mode 100644 index 0000000..e3024bc --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + /// <summary> + /// Optimizes any occurrence of <c>Count()</c>-step followed by an <c>Is()</c>-step. + /// </summary> + public class RangeByIsCountStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs new file mode 100644 index 0000000..6cac454 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs @@ -0,0 +1,29 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Optimization +{ + public class RepeatUnrollStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs new file mode 100644 index 0000000..0f488ab --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Verification +{ + /// <summary> + /// Does not allow lambdas to be used in a <see cref="ITraversal" />. + /// </summary> + public class LambdaRestrictionStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs new file mode 100644 index 0000000..a703e18 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs @@ -0,0 +1,32 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal.Strategy.Verification +{ + /// <summary> + /// Detects mutating steps and throws an exception if one is found. + /// </summary> + public class ReadOnlyStrategy : AbstractTraversalStrategy + { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs new file mode 100644 index 0000000..b854213 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs @@ -0,0 +1,85 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal +{ + /// <summary> + /// Represents a predicate (boolean-valued function) used in a <see cref="ITraversal" />. + /// </summary> + public class TraversalPredicate + { + /// <summary> + /// Initializes a new instance of the <see cref="TraversalPredicate" /> class. + /// </summary> + /// <param name="operatorName">The name of the predicate.</param> + /// <param name="value">The value of the predicate.</param> + /// <param name="other">An optional other predicate that is used as an argument for this predicate.</param> + public TraversalPredicate(string operatorName, dynamic value, TraversalPredicate other = null) + { + OperatorName = operatorName; + Value = value; + Other = other; + } + + /// <summary> + /// Gets the name of the predicate. + /// </summary> + public string OperatorName { get; } + + /// <summary> + /// Gets the value of the predicate. + /// </summary> + public dynamic Value { get; } + + /// <summary> + /// Gets an optional other predicate that is used as an argument for this predicate. + /// </summary> + public TraversalPredicate Other { get; } + + /// <summary> + /// Returns a composed predicate that represents a logical AND of this predicate and another. + /// </summary> + /// <param name="otherPredicate">A predicate that will be logically-ANDed with this predicate.</param> + /// <returns>The composed predicate.</returns> + public TraversalPredicate And(TraversalPredicate otherPredicate) + { + return new TraversalPredicate("and", this, otherPredicate); + } + + /// <summary> + /// Returns a composed predicate that represents a logical OR of this predicate and another. + /// </summary> + /// <param name="otherPredicate">A predicate that will be logically-ORed with this predicate.</param> + /// <returns>The composed predicate.</returns> + public TraversalPredicate Or(TraversalPredicate otherPredicate) + { + return new TraversalPredicate("or", this, otherPredicate); + } + + /// <inheritdoc /> + public override string ToString() + { + return Other == null ? $"{OperatorName}({Value})" : $"{OperatorName}({Value},{Other})"; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs new file mode 100644 index 0000000..573e57f --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs @@ -0,0 +1,75 @@ +#region License + +/* + * 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. + */ + +#endregion + +namespace Gremlin.Net.Process.Traversal +{ + /// <summary> + /// A traverser represents the current state of an object flowing through a <see cref="ITraversal" />. + /// </summary> + public class Traverser + { + /// <summary> + /// Initializes a new instance of the <see cref="Traverser" /> class. + /// </summary> + /// <param name="obj">The object of the traverser.</param> + /// <param name="bulk">The number of traversers represented in this traverser.</param> + public Traverser(dynamic obj, long bulk = 1) + { + Object = obj; + Bulk = bulk; + } + + /// <summary> + /// Gets the object of this traverser. + /// </summary> + public dynamic Object { get; } + + /// <summary> + /// Gets the number of traversers represented in this traverser. + /// </summary> + public long Bulk { get; internal set; } + + /// <inheritdoc /> + public bool Equals(Traverser other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(Object, other.Object); + } + + /// <inheritdoc /> + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((Traverser) obj); + } + + /// <inheritdoc /> + public override int GetHashCode() + { + return Object != null ? Object.GetHashCode() : 0; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs new file mode 100644 index 0000000..2315ed4 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs @@ -0,0 +1,133 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; +using Gremlin.Net.Driver.ResultsAggregation; +using Gremlin.Net.Structure.IO.GraphSON; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Driver +{ + internal class Connection : IConnection + { + private readonly GraphSONReader _graphSONReader; + private readonly GraphSONWriter _graphSONWriter; + private readonly JsonMessageSerializer _messageSerializer = new JsonMessageSerializer(); + private readonly Uri _uri; + private readonly WebSocketConnection _webSocketConnection = new WebSocketConnection(); + + public Connection(Uri uri, GraphSONReader graphSONReader, GraphSONWriter graphSONWriter) + { + _uri = uri; + _graphSONReader = graphSONReader; + _graphSONWriter = graphSONWriter; + } + + public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage) + { + await SendAsync(requestMessage).ConfigureAwait(false); + return await ReceiveAsync<T>().ConfigureAwait(false); + } + + public async Task ConnectAsync() + { + await _webSocketConnection.ConnectAsync(_uri).ConfigureAwait(false); + } + + public async Task CloseAsync() + { + await _webSocketConnection.CloseAsync().ConfigureAwait(false); + } + + private async Task SendAsync(RequestMessage message) + { + var graphsonMsg = _graphSONWriter.WriteObject(message); + var serializedMsg = _messageSerializer.SerializeMessage(graphsonMsg); + await _webSocketConnection.SendMessageAsync(serializedMsg).ConfigureAwait(false); + } + + private async Task<IReadOnlyCollection<T>> ReceiveAsync<T>() + { + ResponseStatus status; + IAggregator aggregator = null; + var isAggregatingSideEffects = false; + var result = new List<T>(); + do + { + var received = await _webSocketConnection.ReceiveMessageAsync().ConfigureAwait(false); + var receivedMsg = _messageSerializer.DeserializeMessage<ResponseMessage<JToken>>(received); + + status = receivedMsg.Status; + status.ThrowIfStatusIndicatesError(); + + if (status.Code != ResponseStatusCode.NoContent) + { + var receivedData = _graphSONReader.ToObject(receivedMsg.Result.Data); + foreach (var d in receivedData) + if (receivedMsg.Result.Meta.ContainsKey(Tokens.ArgsSideEffectKey)) + { + if (aggregator == null) + aggregator = + new AggregatorFactory().GetAggregatorFor( + (string) receivedMsg.Result.Meta[Tokens.ArgsAggregateTo]); + aggregator.Add(d); + isAggregatingSideEffects = true; + } + else + { + result.Add(d); + } + } + } while (status.Code == ResponseStatusCode.PartialContent); + + if (isAggregatingSideEffects) + return new List<T> {(T) aggregator.GetAggregatedResult()}; + return result; + } + + #region IDisposable Support + + private bool _disposed; + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + _webSocketConnection?.Dispose(); + _disposed = true; + } + } + + #endregion + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs new file mode 100644 index 0000000..d31817c --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs @@ -0,0 +1,47 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using Gremlin.Net.Structure.IO.GraphSON; + +namespace Gremlin.Net.Driver +{ + internal class ConnectionFactory + { + private readonly GraphSONReader _graphSONReader; + private readonly GraphSONWriter _graphSONWriter; + private readonly Uri _uri; + + public ConnectionFactory(Uri uri, GraphSONReader graphSONReader, GraphSONWriter graphSONWriter) + { + _uri = uri; + _graphSONReader = graphSONReader; + _graphSONWriter = graphSONWriter; + } + + public Connection CreateConnection() + { + return new Connection(_uri, _graphSONReader, _graphSONWriter); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs new file mode 100644 index 0000000..e9ce9a8 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs @@ -0,0 +1,114 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Gremlin.Net.Driver +{ + internal class ConnectionPool : IDisposable + { + private readonly ConnectionFactory _connectionFactory; + private readonly ConcurrentBag<Connection> _connections = new ConcurrentBag<Connection>(); + private readonly object _connectionsLock = new object(); + + public ConnectionPool(ConnectionFactory connectionFactory) + { + _connectionFactory = connectionFactory; + } + + public int NrConnections { get; private set; } + + public async Task<IConnection> GetAvailableConnectionAsync() + { + Connection connection = null; + lock (_connectionsLock) + { + if (!_connections.IsEmpty) + _connections.TryTake(out connection); + } + + if (connection == null) + connection = await CreateNewConnectionAsync().ConfigureAwait(false); + + return new ProxyConnection(connection, AddConnection); + } + + private async Task<Connection> CreateNewConnectionAsync() + { + NrConnections++; + var newConnection = _connectionFactory.CreateConnection(); + await newConnection.ConnectAsync().ConfigureAwait(false); + return newConnection; + } + + private void AddConnection(Connection connection) + { + lock (_connectionsLock) + { + _connections.Add(connection); + } + } + + #region IDisposable Support + + private bool _disposed; + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + lock (_connectionsLock) + { + if (_connections != null && !_connections.IsEmpty) + { + TeardownAsync().Wait(); + + foreach (var conn in _connections) + conn.Dispose(); + } + } + _disposed = true; + } + } + + private async Task TeardownAsync() + { + var closeTasks = new List<Task>(_connections.Count); + closeTasks.AddRange(_connections.Select(conn => conn.CloseAsync())); + await Task.WhenAll(closeTasks).ConfigureAwait(false); + } + + #endregion + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs new file mode 100644 index 0000000..4706723 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs @@ -0,0 +1,37 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Driver.Exceptions +{ + /// <summary> + /// The exception that is thrown when a response is received from Gremlin Server that indicates that an error occurred. + /// </summary> + public class ResponseException : Exception + { + internal ResponseException(string message) : base(message) + { + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs new file mode 100644 index 0000000..7833088 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs @@ -0,0 +1,95 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; +using Gremlin.Net.Structure.IO.GraphSON; + +namespace Gremlin.Net.Driver +{ + /// <summary> + /// Provides a mechanism for submitting Gremlin requests to one Gremlin Server. + /// </summary> + public class GremlinClient : IGremlinClient + { + private readonly ConnectionPool _connectionPool; + + /// <summary> + /// Initializes a new instance of the <see cref="GremlinClient" /> class for the specified Gremlin Server. + /// </summary> + /// <param name="gremlinServer">The <see cref="GremlinServer" /> the requests should be sent to.</param> + /// <param name="graphSONReader">A <see cref="GraphSONReader" /> instance to read received GraphSON data.</param> + /// <param name="graphSONWriter">a <see cref="GraphSONWriter" /> instance to write GraphSON data.</param> + public GremlinClient(GremlinServer gremlinServer, GraphSONReader graphSONReader = null, + GraphSONWriter graphSONWriter = null) + { + var reader = graphSONReader ?? new GraphSONReader(); + var writer = graphSONWriter ?? new GraphSONWriter(); + var connectionFactory = new ConnectionFactory(gremlinServer.Uri, reader, writer); + _connectionPool = new ConnectionPool(connectionFactory); + } + + /// <summary> + /// Gets the number of open connections. + /// </summary> + public int NrConnections => _connectionPool.NrConnections; + + /// <inheritdoc /> + public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage) + { + using (var connection = await _connectionPool.GetAvailableConnectionAsync().ConfigureAwait(false)) + { + return await connection.SubmitAsync<T>(requestMessage).ConfigureAwait(false); + } + } + + #region IDisposable Support + + private bool _disposed; + + /// <inheritdoc /> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Releases the resources used by the <see cref="GremlinClient" /> instance. + /// </summary> + /// <param name="disposing">Specifies whether managed resources should be released.</param> + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + _connectionPool?.Dispose(); + _disposed = true; + } + } + + #endregion + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs new file mode 100644 index 0000000..4aad73e --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs @@ -0,0 +1,140 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; + +namespace Gremlin.Net.Driver +{ + /// <summary> + /// Provides extension methods for the <see cref="IGremlinClient" /> interface. + /// </summary> + public static class GremlinClientExtensions + { + /// <summary> + /// Submits a request message that consists of a script with bindings as an asynchronous operation where only a single + /// result gets returned. + /// </summary> + /// <remarks> + /// If multiple results are received from Gremlin Server, then only the first gets returned. Use + /// <see cref="SubmitAsync{T}" /> instead when you expect a collection of results. + /// </remarks> + /// <typeparam name="T">The type of the expected result.</typeparam> + /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param> + /// <param name="requestScript">The Gremlin request script to send.</param> + /// <param name="bindings">Bindings for parameters used in the requestScript.</param> + /// <returns>A single result received from the Gremlin Server.</returns> + /// <exception cref="Exceptions.ResponseException"> + /// Thrown when a response is received from Gremlin Server that indicates + /// that an error occurred. + /// </exception> + public static async Task<T> SubmitWithSingleResultAsync<T>(this IGremlinClient gremlinClient, + string requestScript, + Dictionary<string, object> bindings = null) + { + var resultCollection = await gremlinClient.SubmitAsync<T>(requestScript, bindings).ConfigureAwait(false); + return resultCollection.FirstOrDefault(); + } + + /// <summary> + /// Submits a request message as an asynchronous operation where only a single result gets returned. + /// </summary> + /// <remarks> + /// If multiple results are received from Gremlin Server, then only the first gets returned. Use + /// <see cref="SubmitAsync{T}" /> instead when you expect a collection of results. + /// </remarks> + /// <typeparam name="T">The type of the expected result.</typeparam> + /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param> + /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param> + /// <returns>A single result received from the Gremlin Server.</returns> + /// <exception cref="Exceptions.ResponseException"> + /// Thrown when a response is received from Gremlin Server that indicates + /// that an error occurred. + /// </exception> + public static async Task<T> SubmitWithSingleResultAsync<T>(this IGremlinClient gremlinClient, + RequestMessage requestMessage) + { + var resultCollection = await gremlinClient.SubmitAsync<T>(requestMessage).ConfigureAwait(false); + return resultCollection.FirstOrDefault(); + } + + /// <summary> + /// Submits a request message that consists of a script with bindings as an asynchronous operation without returning + /// the result received from the Gremlin Server. + /// </summary> + /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param> + /// <param name="requestScript">The Gremlin request script to send.</param> + /// <param name="bindings">Bindings for parameters used in the requestScript.</param> + /// <returns>The task object representing the asynchronous operation.</returns> + /// <exception cref="Exceptions.ResponseException"> + /// Thrown when a response is received from Gremlin Server that indicates + /// that an error occurred. + /// </exception> + public static async Task SubmitAsync(this IGremlinClient gremlinClient, string requestScript, + Dictionary<string, object> bindings = null) + { + await gremlinClient.SubmitAsync<object>(requestScript, bindings).ConfigureAwait(false); + } + + /// <summary> + /// Submits a request message as an asynchronous operation without returning the result received from the Gremlin + /// Server. + /// </summary> + /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param> + /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param> + /// <returns>The task object representing the asynchronous operation.</returns> + /// <exception cref="Exceptions.ResponseException"> + /// Thrown when a response is received from Gremlin Server that indicates + /// that an error occurred. + /// </exception> + public static async Task SubmitAsync(this IGremlinClient gremlinClient, RequestMessage requestMessage) + { + await gremlinClient.SubmitAsync<object>(requestMessage).ConfigureAwait(false); + } + + /// <summary> + /// Submits a request message that consists of a script with bindings as an asynchronous operation. + /// </summary> + /// <typeparam name="T">The type of the expected results.</typeparam> + /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param> + /// <param name="requestScript">The Gremlin request script to send.</param> + /// <param name="bindings">Bindings for parameters used in the requestScript.</param> + /// <returns>A collection of the data returned from the server.</returns> + /// <exception cref="Exceptions.ResponseException"> + /// Thrown when a response is received from Gremlin Server that indicates + /// that an error occurred. + /// </exception> + public static async Task<IReadOnlyCollection<T>> SubmitAsync<T>(this IGremlinClient gremlinClient, + string requestScript, + Dictionary<string, object> bindings = null) + { + var msgBuilder = RequestMessage.Build(Tokens.OpsEval).AddArgument(Tokens.ArgsGremlin, requestScript); + if (bindings != null) + msgBuilder.AddArgument(Tokens.ArgsBindings, bindings); + var msg = msgBuilder.Create(); + return await gremlinClient.SubmitAsync<T>(msg).ConfigureAwait(false); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs new file mode 100644 index 0000000..8da6d0b --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs @@ -0,0 +1,56 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Driver +{ + /// <summary> + /// Represents a Gremlin Server. + /// </summary> + public class GremlinServer + { + /// <summary> + /// Initializes a new instance of the <see cref="GremlinServer" /> class with the specified connection parameters. + /// </summary> + /// <param name="hostname">The hostname of the server.</param> + /// <param name="port">The port on which Gremlin Server can be reached.</param> + /// <param name="enableSsl">Specifies whether SSL should be enabled.</param> + public GremlinServer(string hostname, int port = 8182, bool enableSsl = false) + { + Uri = CreateUri(hostname, port, enableSsl); + } + + /// <summary> + /// Gets the URI of the Gremlin Server. + /// </summary> + /// <value>The WebSocket <see cref="System.Uri" /> that the Gremlin Server responds to.</value> + public Uri Uri { get; } + + private Uri CreateUri(string hostname, int port, bool enableSsl) + { + var scheme = enableSsl ? "wss" : "ws"; + return new Uri($"{scheme}://{hostname}:{port}/gremlin"); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs new file mode 100644 index 0000000..e1651a6 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs @@ -0,0 +1,35 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; + +namespace Gremlin.Net.Driver +{ + internal interface IConnection : IDisposable + { + Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs new file mode 100644 index 0000000..7a7048a --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs @@ -0,0 +1,48 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; + +namespace Gremlin.Net.Driver +{ + /// <summary> + /// Provides a mechanism for submitting Gremlin requests. + /// </summary> + public interface IGremlinClient : IDisposable + { + /// <summary> + /// Submits a request message as an asynchronous operation. + /// </summary> + /// <typeparam name="T">The type of the expected results.</typeparam> + /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param> + /// <returns>A collection of the data returned from the server.</returns> + /// <exception cref="Exceptions.ResponseException"> + /// Thrown when a response is received from Gremlin Server that indicates + /// that an error occurred. + /// </exception> + Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs new file mode 100644 index 0000000..c3270bf --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs @@ -0,0 +1,49 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Text; +using Newtonsoft.Json; + +namespace Gremlin.Net.Driver +{ + internal class JsonMessageSerializer + { + private const string MimeType = "application/vnd.gremlin-v2.0+json"; + + public byte[] SerializeMessage(string msg) + { + return Encoding.UTF8.GetBytes(MessageWithHeader(msg)); + } + + private string MessageWithHeader(string messageContent) + { + return $"{(char) MimeType.Length}{MimeType}{messageContent}"; + } + + public TMessage DeserializeMessage<TMessage>(byte[] message) + { + var responseStr = Encoding.UTF8.GetString(message); + return JsonConvert.DeserializeObject<TMessage>(responseStr); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs new file mode 100644 index 0000000..550d9c0 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs @@ -0,0 +1,143 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; + +namespace Gremlin.Net.Driver.Messages +{ + /// <summary> + /// The model for a request message sent to the server. + /// </summary> + public class RequestMessage + { + private RequestMessage(Guid requestId, string operation, string processor, Dictionary<string, object> arguments) + { + RequestId = requestId; + Operation = operation; + Processor = processor; + Arguments = arguments; + } + + /// <summary> + /// Gets the ID of this request message. + /// </summary> + /// <value>A UUID representing the unique identification for the request.</value> + public Guid RequestId { get; } + + /// <summary> + /// Gets the name of the operation that should be executed by the Gremlin Server. + /// </summary> + /// <value> + /// The name of the "operation" to execute based on the available OpProcessor configured in the Gremlin Server. This + /// defaults to "eval" which evaluates a request script. + /// </value> + public string Operation { get; } + + /// <summary> + /// Gets the name of the OpProcessor to utilize. + /// </summary> + /// <value> + /// The name of the OpProcessor to utilize. This defaults to an empty string which represents the default + /// OpProcessor for evaluating scripts. + /// </value> + public string Processor { get; } + + /// <summary> + /// Gets arguments of the <see cref="RequestMessage" />. + /// </summary> + public Dictionary<string, object> Arguments { get; } + + /// <summary> + /// Initializes a <see cref="Builder" /> to build a <see cref="RequestMessage" />. + /// </summary> + /// <param name="operation">The name of the OpProcessor to utilize.</param> + /// <returns>A <see cref="Builder" /> to build a <see cref="RequestMessage" />.</returns> + public static Builder Build(string operation) + { + return new Builder(operation); + } + + /// <summary> + /// Allows to build <see cref="RequestMessage" /> objects. + /// </summary> + public class Builder + { + private const string DefaultProcessor = ""; + private readonly Dictionary<string, object> _arguments = new Dictionary<string, object>(); + private readonly string _operation; + private string _processor = DefaultProcessor; + private Guid _requestId = Guid.NewGuid(); + + internal Builder(string operation) + { + _operation = operation; + } + + /// <summary> + /// If this value is not set in the builder then the <see cref="RequestMessage.Processor" /> defaults to + /// the standard op processor (empty string). + /// </summary> + /// <param name="processor">The name of the processor.</param> + /// <returns>The <see cref="Builder" />.</returns> + public Builder Processor(string processor) + { + _processor = processor; + return this; + } + + /// <summary> + /// Overrides the request identifier with a specified one, otherwise the + /// <see cref="Builder" /> will randomly generate a <see cref="Guid" />. + /// </summary> + /// <param name="requestId">The request identifier to use.</param> + /// <returns>The <see cref="Builder" />.</returns> + public Builder OverrideRequestId(Guid requestId) + { + _requestId = requestId; + return this; + } + + /// <summary> + /// Adds and argument to the <see cref="RequestMessage" />. + /// </summary> + /// <param name="key">The key of the argument.</param> + /// <param name="value">The value of the argument.</param> + /// <returns>The <see cref="Builder" />.</returns> + public Builder AddArgument(string key, object value) + { + _arguments.Add(key, value); + return this; + } + + /// <summary> + /// Creates the <see cref="RequestMessage" /> given the settings provided to the <see cref="Builder" />. + /// </summary> + /// <returns>The built <see cref="RequestMessage" />.</returns> + public RequestMessage Create() + { + return new RequestMessage(_requestId, _operation, _processor, _arguments); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs new file mode 100644 index 0000000..602b013 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs @@ -0,0 +1,40 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using Newtonsoft.Json; + +namespace Gremlin.Net.Driver.Messages +{ + internal class ResponseMessage<T> + { + [JsonProperty(PropertyName = "requestId")] + public Guid RequestId { get; set; } + + [JsonProperty(PropertyName = "status")] + public ResponseStatus Status { get; set; } + + [JsonProperty(PropertyName = "result")] + public ResponseResult<T> Result { get; set; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs new file mode 100644 index 0000000..643fbe8 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs @@ -0,0 +1,37 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Gremlin.Net.Driver.Messages +{ + internal class ResponseResult<T> + { + [JsonProperty(PropertyName = "data")] + public List<T> Data { get; set; } + + [JsonProperty(PropertyName = "meta")] + public Dictionary<string, object> Meta { get; set; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs new file mode 100644 index 0000000..e3c1797 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs @@ -0,0 +1,50 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System.Collections.Generic; +using Gremlin.Net.Driver.Exceptions; +using Newtonsoft.Json; + +namespace Gremlin.Net.Driver.Messages +{ + internal class ResponseStatus + { + [JsonProperty(PropertyName = "code")] + public ResponseStatusCode Code { get; set; } + + [JsonProperty(PropertyName = "attributes")] + public Dictionary<string, object> Attributes { get; set; } + + [JsonProperty(PropertyName = "message")] + public string Message { get; set; } + } + + internal static class ResponseStatusExtensions + { + public static void ThrowIfStatusIndicatesError(this ResponseStatus status) + { + if (status.Code.IndicatesError()) + throw new ResponseException($"{status.Code}: {status.Message}"); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs new file mode 100644 index 0000000..7b0bc94 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs @@ -0,0 +1,67 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Driver.Messages +{ + internal enum ResponseStatusCode + { + Success = 200, + NoContent = 204, + PartialContent = 206, + Unauthorized = 401, + Authenticate = 407, + MalformedRequest = 498, + InvalidRequestArguments = 499, + ServerError = 500, + ScriptEvaluationError = 597, + ServerTimeout = 598, + ServerSerializationError = 599 + } + + internal static class ResponseStatusCodeExtensions + { + public static bool IndicatesError(this ResponseStatusCode statusCode) + { + switch (statusCode) + { + case ResponseStatusCode.Success: + case ResponseStatusCode.NoContent: + case ResponseStatusCode.PartialContent: + return false; + case ResponseStatusCode.Unauthorized: + case ResponseStatusCode.Authenticate: + case ResponseStatusCode.MalformedRequest: + case ResponseStatusCode.InvalidRequestArguments: + case ResponseStatusCode.ServerError: + case ResponseStatusCode.ScriptEvaluationError: + case ResponseStatusCode.ServerTimeout: + case ResponseStatusCode.ServerSerializationError: + return true; + default: + throw new ArgumentOutOfRangeException(nameof(statusCode), statusCode, null); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs new file mode 100644 index 0000000..cbe15ec --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs @@ -0,0 +1,52 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; + +namespace Gremlin.Net.Driver +{ + internal sealed class ProxyConnection : IConnection + { + private readonly Connection _realConnection; + private readonly Action<Connection> _releaseAction; + + public ProxyConnection(Connection realConnection, Action<Connection> releaseAction) + { + _realConnection = realConnection; + _releaseAction = releaseAction; + } + + public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage) + { + return await _realConnection.SubmitAsync<T>(requestMessage).ConfigureAwait(false); + } + + public void Dispose() + { + _releaseAction(_realConnection); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs new file mode 100644 index 0000000..2ba5d6c --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs @@ -0,0 +1,80 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Gremlin.Net.Driver.Messages; +using Gremlin.Net.Process.Remote; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Driver.Remote +{ + /// <summary> + /// A <see cref="IRemoteConnection" /> implementation for Gremlin Server. + /// </summary> + public class DriverRemoteConnection : IRemoteConnection, IDisposable + { + private readonly IGremlinClient _client; + + /// <summary> + /// Initializes a new <see cref="IRemoteConnection" />. + /// </summary> + /// <param name="client">The <see cref="IGremlinClient" /> that will be used for the connection.</param> + /// <exception cref="ArgumentNullException">Thrown when client is null.</exception> + public DriverRemoteConnection(IGremlinClient client) + { + _client = client ?? throw new ArgumentNullException(nameof(client)); + } + + /// <summary> + /// Submits <see cref="Bytecode" /> for evaluation to a remote Gremlin Server. + /// </summary> + /// <param name="bytecode">The <see cref="Bytecode" /> to submit.</param> + /// <returns>A <see cref="ITraversal" /> allowing to access the results and side-effects.</returns> + public async Task<ITraversal> SubmitAsync(Bytecode bytecode) + { + var requestId = Guid.NewGuid(); + var resultSet = await SubmitBytecodeAsync(requestId, bytecode).ConfigureAwait(false); + return new DriverRemoteTraversal(_client, requestId, resultSet); + } + + private async Task<IEnumerable<Traverser>> SubmitBytecodeAsync(Guid requestid, Bytecode bytecode) + { + var requestMsg = + RequestMessage.Build(Tokens.OpsBytecode) + .Processor(Tokens.ProcessorTraversal) + .OverrideRequestId(requestid) + .AddArgument(Tokens.ArgsGremlin, bytecode) + .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", "g"}}) + .Create(); + return await _client.SubmitAsync<Traverser>(requestMsg).ConfigureAwait(false); + } + + /// <inheritdoc /> + public void Dispose() + { + _client?.Dispose(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fd81c7f6/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs new file mode 100644 index 0000000..f3f26d1 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs @@ -0,0 +1,39 @@ +#region License + +/* + * 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. + */ + +#endregion + +using System; +using System.Collections.Generic; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Driver.Remote +{ + internal class DriverRemoteTraversal : DefaultTraversal + { + public DriverRemoteTraversal(IGremlinClient gremlinClient, Guid requestId, + IEnumerable<Traverser> traversers) + { + Traversers = traversers; + SideEffects = new DriverRemoteTraversalSideEffects(gremlinClient, requestId); + } + } +} \ No newline at end of file