diff --git a/README.md b/README.md index 87446fe..91fa5ee 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ await g.V().Has("demigod", "name", "hercules").OutE("battled") .Has("place", Geoshape.Point(38.1f, 23.7f)).Count().Promise(t => t.Next()); ``` -Only the point Geoshape is supported right now. +Only the `Point` Geoshape is supported right now. ## Version Compatibility @@ -78,11 +78,12 @@ The lowest supported JanusGraph version is 0.3.0. The following table shows the supported JanusGraph versions for each version of JanusGraph.Net: -| JanusGraph.Net | JanusGraph | -|---|---| -| 0.1.z | 0.3.z | -| 0.2.z | 0.4.z, 0.5.z | -| 0.3.z | 0.4.z, 0.5.z, 0.6.z | +| JanusGraph.Net | JanusGraph | +| -------------- | ---------------------- | +| 0.1.z | 0.3.z | +| 0.2.z | 0.4.z, 0.5.z | +| 0.3.z | 0.4.z, 0.5.z, 0.6.z | +| 0.4.z | (0.4.z, 0.5.z,)* 0.6.z | While it should also be possible to use JanusGraph.Net with other versions of JanusGraph than mentioned here, compatibility is not tested and some @@ -90,6 +91,30 @@ functionality (like added Gremlin steps) will not work as it is not supported yet in case of an older JanusGraph version or was removed in a newer JanusGraph version. +\* JanusGraph.Net 0.4 still supports older versions of JanusGraph, but the +`janusGraphPredicates` flag needs to be set to `false` in order to be able to +use JanusGraph's Text predicates. + +## Serialization Formats + +JanusGraph.Net supports GraphSON 3 as well as GraphBinary. GraphSON 3 is used +by default. GraphBinary can be configured like this: + +```c# +var client = JanusGraphClientBuilder.BuildClientForServer(new GremlinServer("localhost", 8182)) + .WithSerializer(new GraphBinaryMessageSerializer(JanusGraphTypeSerializerRegistry.Instance)).Create(); +``` + +Note that support for GraphBinary was only added in JanusGraph 0.6.0. So, the +server needs to be at least on that version. + +Not all of the JanusGraph-specific types are already supported by both formats: + +| Format | RelationIdentifier | Text predicates | Geoshapes | Geo predicates | +| ----------- | ------------------ | --------------- | --------- | -------------- | +| GraphSON3 | x | x | `Point` | - | +| GraphBinary | x | x | - | - | + ## Community JanusGraph.Net uses the same communication channels as JanusGraph in general. diff --git a/src/JanusGraph.Net/IO/GraphBinary/JanusGraphTypeSerializerRegistry.cs b/src/JanusGraph.Net/IO/GraphBinary/JanusGraphTypeSerializerRegistry.cs new file mode 100644 index 0000000..5fb1e34 --- /dev/null +++ b/src/JanusGraph.Net/IO/GraphBinary/JanusGraphTypeSerializerRegistry.cs @@ -0,0 +1,70 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.GraphBinary; +using Gremlin.Net.Structure.IO.GraphBinary.Types; +using JanusGraph.Net.IO.GraphBinary.Types; + +namespace JanusGraph.Net.IO.GraphBinary +{ + /// + /// Provides GraphBinary serializers for different types, including JanusGraph specific types. + /// + public static class JanusGraphTypeSerializerRegistry + { + /// + /// Provides a default instance with JanusGraph types already registered. + /// + public static readonly TypeSerializerRegistry Instance = Build().Create(); + + private static Builder Build() => new Builder(); + + /// + /// Builds a with serializers for JanusGraph types already registered. + /// + public class Builder + { + private readonly TypeSerializerRegistry.Builder _builder = TypeSerializerRegistry.Build(); + + internal Builder() + { + _builder.AddCustomType(typeof(RelationIdentifier), new RelationIdentifierSerializer()); + _builder.AddCustomType(typeof(JanusGraphP), new JanusGraphPSerializer()); + } + + /// + /// Adds a serializer for a custom type. + /// + /// The custom type supported by the serializer. + /// The serializer for the custom type. + public Builder AddCustomType(Type type, CustomTypeSerializer serializer) + { + _builder.AddCustomType(type, serializer); + return this; + } + + /// + /// Creates the . + /// + public TypeSerializerRegistry Create() => _builder.Create(); + } + } +} \ No newline at end of file diff --git a/src/JanusGraph.Net/IO/GraphBinary/Types/GraphBinaryType.cs b/src/JanusGraph.Net/IO/GraphBinary/Types/GraphBinaryType.cs new file mode 100644 index 0000000..8f69a05 --- /dev/null +++ b/src/JanusGraph.Net/IO/GraphBinary/Types/GraphBinaryType.cs @@ -0,0 +1,55 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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 JanusGraph.Net.IO.GraphBinary.Types +{ + /// + /// Represents a JanusGraph GraphBinary type with its type information needed for serialization. + /// + public class GraphBinaryType + { + internal static readonly GraphBinaryType RelationIdentifier = + new GraphBinaryType(0x1001, "janusgraph.RelationIdentifier"); + + internal static readonly GraphBinaryType JanusGraphP = + new GraphBinaryType(0x1002, "janusgraph.P"); + + /// + /// Initializes a new instance of the class. + /// + /// The JanusGraph internal id of the type. + /// The name of the type. + public GraphBinaryType(int typeId, string typeName) + { + TypeId = typeId; + TypeName = typeName; + } + + /// + /// Gets the JanusGraph internal id of the type. + /// + public int TypeId { get; } + + /// + /// Gets the name of the type. + /// + public string TypeName { get; } + } +} \ No newline at end of file diff --git a/src/JanusGraph.Net/IO/GraphBinary/Types/JanusGraphPSerializer.cs b/src/JanusGraph.Net/IO/GraphBinary/Types/JanusGraphPSerializer.cs new file mode 100644 index 0000000..1bdecb0 --- /dev/null +++ b/src/JanusGraph.Net/IO/GraphBinary/Types/JanusGraphPSerializer.cs @@ -0,0 +1,47 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.IO; +using System.Threading.Tasks; +using Gremlin.Net.Structure.IO.GraphBinary; + +namespace JanusGraph.Net.IO.GraphBinary.Types +{ + internal class JanusGraphPSerializer : JanusGraphTypeSerializer + { + public JanusGraphPSerializer() : base(GraphBinaryType.JanusGraphP) + { + } + + protected override async Task WriteNonNullableValueAsync(JanusGraphP value, Stream stream, + GraphBinaryWriter writer) + { + await writer.WriteValueAsync(value.OperatorName, stream, false).ConfigureAwait(false); + await writer.WriteAsync(value.Value, stream).ConfigureAwait(false); + } + + protected override async Task ReadNonNullableValueAsync(Stream stream, GraphBinaryReader reader) + { + var operatorName = (string)await reader.ReadValueAsync(stream, false).ConfigureAwait(false); + var value = await reader.ReadAsync(stream).ConfigureAwait(false); + return new JanusGraphP(operatorName, value); + } + } +} \ No newline at end of file diff --git a/src/JanusGraph.Net/IO/GraphBinary/Types/JanusGraphTypeSerializer.cs b/src/JanusGraph.Net/IO/GraphBinary/Types/JanusGraphTypeSerializer.cs new file mode 100644 index 0000000..5ca3688 --- /dev/null +++ b/src/JanusGraph.Net/IO/GraphBinary/Types/JanusGraphTypeSerializer.cs @@ -0,0 +1,123 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.IO; +using System.Threading.Tasks; +using Gremlin.Net.Structure.IO.GraphBinary; +using Gremlin.Net.Structure.IO.GraphBinary.Types; + +namespace JanusGraph.Net.IO.GraphBinary.Types +{ + /// + /// Base class for GraphBinary serializers of JanusGraph types. + /// + /// The JanusGraph type to be serialized. + public abstract class JanusGraphTypeSerializer : CustomTypeSerializer + { + private readonly GraphBinaryType _type; + + /// + /// Initializes a new instance of the class. + /// + /// The GraphBinaryType for this serializer. + protected JanusGraphTypeSerializer(GraphBinaryType type) + { + _type = type; + } + + /// + public override async Task WriteAsync(object value, Stream stream, GraphBinaryWriter writer) + { + await stream.WriteIntAsync(_type.TypeId).ConfigureAwait(false); + + await WriteValueAsync(value, stream, writer, true).ConfigureAwait(false); + } + + /// + public override async Task WriteValueAsync(object value, Stream stream, GraphBinaryWriter writer, bool nullable) + { + if (value == null) + { + if (!nullable) + { + throw new IOException("Unexpected null value when nullable is false"); + } + + await writer.WriteValueFlagNullAsync(stream).ConfigureAwait(false); + return; + } + + if (nullable) + { + await writer.WriteValueFlagNoneAsync(stream).ConfigureAwait(false); + } + + await WriteNonNullableValueAsync((T) value, stream, writer).ConfigureAwait(false); + } + + /// + /// Writes a non-nullable value without including type information. + /// + /// The value to write. + /// The stream to write to. + /// A that can be used to write nested values. + /// A task that represents the asynchronous write operation. + protected abstract Task WriteNonNullableValueAsync(T value, Stream stream, GraphBinaryWriter writer); + + /// + public override async Task ReadAsync(Stream stream, GraphBinaryReader reader) + { + var customTypeInfo = await stream.ReadIntAsync().ConfigureAwait(false); + if (customTypeInfo != _type.TypeId) + { + throw new IOException( + $"Custom type info {customTypeInfo} doesn't match expected type info {_type.TypeId}"); + } + + return await ReadValueAsync(stream, reader, true).ConfigureAwait(false); + } + + /// + public override async Task ReadValueAsync(Stream stream, GraphBinaryReader reader, bool nullable) + { + if (nullable) + { + var valueFlag = await stream.ReadByteAsync().ConfigureAwait(false); + if ((valueFlag & 1) == 1) + { + return null; + } + } + + return await ReadNonNullableValueAsync(stream, reader).ConfigureAwait(false); + } + + /// + /// Reads a non-nullable value from the stream. + /// + /// The GraphBinary data to parse. + /// A that can be used to read nested values. + /// The read value. + protected abstract Task ReadNonNullableValueAsync(Stream stream, GraphBinaryReader reader); + + /// + public override string TypeName => _type.TypeName; + } +} \ No newline at end of file diff --git a/src/JanusGraph.Net/IO/GraphBinary/Types/RelationIdentifierSerializer.cs b/src/JanusGraph.Net/IO/GraphBinary/Types/RelationIdentifierSerializer.cs new file mode 100644 index 0000000..d1187a3 --- /dev/null +++ b/src/JanusGraph.Net/IO/GraphBinary/Types/RelationIdentifierSerializer.cs @@ -0,0 +1,52 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.IO; +using System.Threading.Tasks; +using Gremlin.Net.Structure.IO.GraphBinary; + +namespace JanusGraph.Net.IO.GraphBinary.Types +{ + internal class RelationIdentifierSerializer : JanusGraphTypeSerializer + { + public RelationIdentifierSerializer() : base(GraphBinaryType.RelationIdentifier) + { + } + + protected override async Task WriteNonNullableValueAsync(RelationIdentifier value, Stream stream, + GraphBinaryWriter writer) + { + await stream.WriteLongAsync(value.OutVertexId).ConfigureAwait(false); + await stream.WriteLongAsync(value.TypeId).ConfigureAwait(false); + await stream.WriteLongAsync(value.RelationId).ConfigureAwait(false); + await stream.WriteLongAsync(value.InVertexId).ConfigureAwait(false); + } + + protected override async Task ReadNonNullableValueAsync(Stream stream, + GraphBinaryReader reader) + { + var outVertexId = await stream.ReadLongAsync().ConfigureAwait(false); + var typeId = await stream.ReadLongAsync().ConfigureAwait(false); + var relationId = await stream.ReadLongAsync().ConfigureAwait(false); + var inVertexId = await stream.ReadLongAsync().ConfigureAwait(false); + return new RelationIdentifier(outVertexId, typeId, relationId, inVertexId); + } + } +} \ No newline at end of file diff --git a/src/JanusGraph.Net/IO/GraphSON/JanusGraphGraphSONMessageSerializer.cs b/src/JanusGraph.Net/IO/GraphSON/JanusGraphGraphSONMessageSerializer.cs new file mode 100644 index 0000000..cf25d2e --- /dev/null +++ b/src/JanusGraph.Net/IO/GraphSON/JanusGraphGraphSONMessageSerializer.cs @@ -0,0 +1,80 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.Threading.Tasks; +using Gremlin.Net.Driver; +using Gremlin.Net.Driver.Messages; +using Gremlin.Net.Structure.IO.GraphSON; + +namespace JanusGraph.Net.IO.GraphSON +{ + /// + /// Serializes data to and from JanusGraph Server in GraphSON3 format. + /// + public class JanusGraphGraphSONMessageSerializer : IMessageSerializer + { + private readonly GraphSON3MessageSerializer _serializer; + + /// + /// Initializes a new instance of the class. + /// + /// The used to deserialize from GraphSON. + /// The used to serialize to GraphSON. + public JanusGraphGraphSONMessageSerializer(GraphSON3Reader graphSONReader, GraphSON3Writer graphSONWriter) + { + _serializer = new GraphSON3MessageSerializer(graphSONReader, graphSONWriter); + } + + /// + /// Initializes a new instance of the class. + /// + public JanusGraphGraphSONMessageSerializer() + : this(JanusGraphSONReaderBuilder.Build().Create(), JanusGraphSONWriterBuilder.Build().Create()) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// This value activates support for JanusGraph predicate serialization added in + /// JanusGraph 0.6.0. It should be set to true for JanusGraph Server versions >= 0.6.0 and to false for versions before + /// 0.6.0. + /// + public JanusGraphGraphSONMessageSerializer(bool janusGraphPredicates) + : this(JanusGraphSONReaderBuilder.Build().Create(), + JanusGraphSONWriterBuilder.Build(janusGraphPredicates).Create()) + { + } + + /// + public async Task SerializeMessageAsync(RequestMessage requestMessage) + { + return await _serializer.SerializeMessageAsync(requestMessage).ConfigureAwait(false); + } + + /// + public async Task>> DeserializeMessageAsync(byte[] message) + { + return await _serializer.DeserializeMessageAsync(message).ConfigureAwait(false); + } + } +} \ No newline at end of file diff --git a/src/JanusGraph.Net/IO/GraphSON/JanusGraphSONWriterBuilder.cs b/src/JanusGraph.Net/IO/GraphSON/JanusGraphSONWriterBuilder.cs index d76be2f..a35f0f0 100644 --- a/src/JanusGraph.Net/IO/GraphSON/JanusGraphSONWriterBuilder.cs +++ b/src/JanusGraph.Net/IO/GraphSON/JanusGraphSONWriterBuilder.cs @@ -51,7 +51,7 @@ private JanusGraphSONWriterBuilder(bool janusGraphPredicates) /// public static JanusGraphSONWriterBuilder Build() { - return new JanusGraphSONWriterBuilder(false); + return new JanusGraphSONWriterBuilder(true); } /// diff --git a/src/JanusGraph.Net/IO/GraphSON/RelationIdentifierSerializer.cs b/src/JanusGraph.Net/IO/GraphSON/RelationIdentifierSerializer.cs index 02c05ec..4b3488f 100644 --- a/src/JanusGraph.Net/IO/GraphSON/RelationIdentifierSerializer.cs +++ b/src/JanusGraph.Net/IO/GraphSON/RelationIdentifierSerializer.cs @@ -33,7 +33,7 @@ public Dictionary Dictify(dynamic objectData, GraphSONWriter wr private static Dictionary ValueDict(RelationIdentifier relationIdentifier) { - return new Dictionary {{"relationId", relationIdentifier.RelationId}}; + return new Dictionary {{"relationId", relationIdentifier.StringRepresentation}}; } } } \ No newline at end of file diff --git a/src/JanusGraph.Net/JanusGraph.Net.csproj b/src/JanusGraph.Net/JanusGraph.Net.csproj index 074011f..f318091 100644 --- a/src/JanusGraph.Net/JanusGraph.Net.csproj +++ b/src/JanusGraph.Net/JanusGraph.Net.csproj @@ -25,9 +25,9 @@ - + - + \ No newline at end of file diff --git a/src/JanusGraph.Net/JanusGraphClientBuilder.cs b/src/JanusGraph.Net/JanusGraphClientBuilder.cs index d47e3ca..248ee4d 100644 --- a/src/JanusGraph.Net/JanusGraphClientBuilder.cs +++ b/src/JanusGraph.Net/JanusGraphClientBuilder.cs @@ -33,6 +33,7 @@ public class JanusGraphClientBuilder private readonly GremlinServer _server; private readonly JanusGraphSONReaderBuilder _readerBuilder = JanusGraphSONReaderBuilder.Build(); private readonly JanusGraphSONWriterBuilder _writerBuilder; + private IMessageSerializer _serializer; private ConnectionPoolSettings _connectionPoolSettings; private JanusGraphClientBuilder(GremlinServer server, bool janusGraphPredicates) @@ -47,7 +48,7 @@ private JanusGraphClientBuilder(GremlinServer server, bool janusGraphPredicates) /// The requests should be sent to. public static JanusGraphClientBuilder BuildClientForServer(GremlinServer server) { - return new JanusGraphClientBuilder(server, false); + return new JanusGraphClientBuilder(server, true); } /// @@ -63,11 +64,22 @@ public static JanusGraphClientBuilder BuildClientForServer(GremlinServer server, return new JanusGraphClientBuilder(server, janusGraphPredicates); } + /// + /// Registers a used to serialize data to and from JanusGraph Server. + /// + /// The serializer to use. + public JanusGraphClientBuilder WithSerializer(IMessageSerializer serializer) + { + _serializer = serializer; + return this; + } + /// /// Registers a custom GraphSON deserializer for the given GraphSON type. /// /// The GraphSON type the deserializer should be registered for. /// The deserializer to register. + [Obsolete("Use WithSerializer() instead")] public JanusGraphClientBuilder RegisterDeserializer(string graphSONType, IGraphSONDeserializer deserializer) { _readerBuilder.RegisterDeserializer(graphSONType, deserializer); @@ -79,6 +91,7 @@ public JanusGraphClientBuilder RegisterDeserializer(string graphSONType, IGraphS /// /// The type the serializer should be registered for. /// The serializer to register. + [Obsolete("Use WithSerializer() instead")] public JanusGraphClientBuilder RegisterSerializer(Type type, IGraphSONSerializer serializer) { _writerBuilder.RegisterSerializer(type, serializer); @@ -100,9 +113,9 @@ public JanusGraphClientBuilder WithConnectionPoolSettings(ConnectionPoolSettings /// public IGremlinClient Create() { - return new GremlinClient(_server, - new GraphSON3MessageSerializer(_readerBuilder.Create(), _writerBuilder.Create()), - _connectionPoolSettings); + var serializer = _serializer ?? + new JanusGraphGraphSONMessageSerializer(_readerBuilder.Create(), _writerBuilder.Create()); + return new GremlinClient(_server, serializer, _connectionPoolSettings); } } } \ No newline at end of file diff --git a/src/JanusGraph.Net/RelationIdentifier.cs b/src/JanusGraph.Net/RelationIdentifier.cs index 2d6a203..b026028 100644 --- a/src/JanusGraph.Net/RelationIdentifier.cs +++ b/src/JanusGraph.Net/RelationIdentifier.cs @@ -19,6 +19,8 @@ #endregion using System; +using System.Text; +using JanusGraph.Net.Utils; namespace JanusGraph.Net { @@ -27,26 +29,84 @@ namespace JanusGraph.Net /// public class RelationIdentifier : IEquatable { + private const char ToStringDelimiter = '-'; + /// /// Initializes a new instance of the class. /// - /// The underlying relation id. - public RelationIdentifier(string relationId) + /// The underlying relation id. + public RelationIdentifier(string stringRepresentation) { + StringRepresentation = stringRepresentation; + + var elements = stringRepresentation.Split(ToStringDelimiter); + if (elements.Length != 3 && elements.Length != 4) + throw new ArgumentException($"Not a valid relation identifier: {stringRepresentation}"); + OutVertexId = LongEncoding.Decode(elements[1]); + TypeId = LongEncoding.Decode(elements[2]); + RelationId = LongEncoding.Decode(elements[0]); + if (elements.Length == 4) + { + InVertexId = LongEncoding.Decode(elements[3]); + } + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + /// + public RelationIdentifier(long outVertexId, long typeId, long relationId, long inVertexId) + { + OutVertexId = outVertexId; + TypeId = typeId; RelationId = relationId; + InVertexId = inVertexId; + + var sb = new StringBuilder(); + sb.Append(LongEncoding.Encode(relationId)).Append(ToStringDelimiter) + .Append(LongEncoding.Encode(outVertexId)).Append(ToStringDelimiter).Append(LongEncoding.Encode(typeId)); + if (inVertexId != 0) + { + sb.Append(ToStringDelimiter).Append(LongEncoding.Encode(inVertexId)); + } + + StringRepresentation = sb.ToString(); } /// - /// Gets the underlying relation id. + /// Gets the string representation of this . + /// + public string StringRepresentation { get; } + + /// + /// Gets the id of the outgoing vertex. + /// + public long OutVertexId { get; } + + /// + /// Gets the JanusGraph internal type id. + /// + public long TypeId { get; } + + /// + /// Gets the JanusGraph internal relation id. + /// + public long RelationId { get; } + + /// + /// Gets the id of the incoming vertex. /// - public string RelationId { get; } + public long InVertexId { get; } /// public bool Equals(RelationIdentifier other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return string.Equals(RelationId, other.RelationId); + return string.Equals(StringRepresentation, other.StringRepresentation); } /// @@ -61,13 +121,13 @@ public override bool Equals(object obj) /// public override int GetHashCode() { - return RelationId != null ? RelationId.GetHashCode() : 0; + return StringRepresentation != null ? StringRepresentation.GetHashCode() : 0; } /// public override string ToString() { - return RelationId; + return StringRepresentation; } } } \ No newline at end of file diff --git a/src/JanusGraph.Net/Utils/LongEncoding.cs b/src/JanusGraph.Net/Utils/LongEncoding.cs new file mode 100644 index 0000000..d82e31e --- /dev/null +++ b/src/JanusGraph.Net/Utils/LongEncoding.cs @@ -0,0 +1,63 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.Text; + +namespace JanusGraph.Net.Utils +{ + /// + /// Utility class for encoding longs in strings, re-implemented from its Java equivalent. + /// + internal static class LongEncoding + { + private const string BaseSymbols = "0123456789abcdefghijklmnopqrstuvwxyz"; + private static readonly int NrSymbols = BaseSymbols.Length; + + public static long Decode(string s) + { + long num = 0; + foreach (var ch in s) + { + num *= NrSymbols; + var pos = BaseSymbols.IndexOf(ch); + if (pos < 0) + throw new ArgumentException($"Symbol {ch} not allowed, only these symbols are: {BaseSymbols}"); + num += pos; + } + + return num; + } + + public static string Encode(long num) + { + var sb = new StringBuilder(); + while (num != 0) + { + sb.Append(BaseSymbols[(int)num % NrSymbols]); + num /= NrSymbols; + } + + var chars = sb.ToString().ToCharArray(); + Array.Reverse(chars); + return new string(chars); + } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/DocTraversalsTests.cs b/test/JanusGraph.Net.IntegrationTest/DocTraversalsTests.cs index bc6679b..9ff7899 100644 --- a/test/JanusGraph.Net.IntegrationTest/DocTraversalsTests.cs +++ b/test/JanusGraph.Net.IntegrationTest/DocTraversalsTests.cs @@ -28,17 +28,17 @@ namespace JanusGraph.Net.IntegrationTest [Collection("JanusGraph Server collection")] public class DocTraversalsTests : IDisposable { - private readonly RemoteConnectionFactory _connectionFactory; + protected virtual RemoteConnectionFactory ConnectionFactory { get; } public DocTraversalsTests(JanusGraphServerFixture fixture) { - _connectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); } [Fact] public void GremlinNetGettingStartedTest() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var herculesAge = g.V().Has("name", "hercules").Values("age").Next(); @@ -48,7 +48,7 @@ public void GremlinNetGettingStartedTest() [Fact] public void ReceivingEdgesTest() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var edges = g.V().Has("name", "hercules").OutE("battled").ToList(); @@ -56,9 +56,9 @@ public void ReceivingEdgesTest() } [Fact] - public void TextContainsPredicateTest() + public virtual void TextContainsPredicateTest() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var reasons = g.E().Has("reason", Text.TextContains("loves")).ToList(); @@ -66,9 +66,9 @@ public void TextContainsPredicateTest() } [Fact] - public void GeoTypesPointsReceivedTest() + public virtual void GeoTypesPointsReceivedTest() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var firstBattlePlace = g.V().Has("name", "hercules").OutE("battled").Order().By("time") .Values("place").Next(); @@ -78,16 +78,16 @@ public void GeoTypesPointsReceivedTest() } [Fact] - public void GeoTypesPointAsArgumentTest() + public virtual void GeoTypesPointAsArgumentTest() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); g.V().Has("name", "hercules").OutE("battled").Has("place", Geoshape.Point(38.1f, 23.7f)).Next(); } public void Dispose() { - _connectionFactory?.Dispose(); + ConnectionFactory?.Dispose(); } } } \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/GraphBinaryDocTraversalsTests.cs b/test/JanusGraph.Net.IntegrationTest/GraphBinaryDocTraversalsTests.cs new file mode 100644 index 0000000..55f7361 --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/GraphBinaryDocTraversalsTests.cs @@ -0,0 +1,51 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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.GraphBinary; +using JanusGraph.Net.IO.GraphBinary; +using Xunit; + +namespace JanusGraph.Net.IntegrationTest +{ + [Collection("JanusGraph Server collection")] + public class GraphBinaryDocTraversalsTests : DocTraversalsTests + { + protected override RemoteConnectionFactory ConnectionFactory { get; } + + public GraphBinaryDocTraversalsTests(JanusGraphServerFixture fixture) : base(fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port, + new GraphBinaryMessageSerializer(JanusGraphTypeSerializerRegistry.Instance)); + } + + [Fact(Skip = "Geoshapes not supported yet for GraphBinary")] + public override void GeoTypesPointsReceivedTest() + { + throw new NotImplementedException("GraphBinary support for Geo types not implemented yet."); + } + + [Fact(Skip = "Geoshapes not supported yet for GraphBinary")] + public override void GeoTypesPointAsArgumentTest() + { + throw new NotImplementedException("GraphBinary support for Geo types not implemented yet."); + } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/GraphBinaryTextTests.cs b/test/JanusGraph.Net.IntegrationTest/GraphBinaryTextTests.cs new file mode 100644 index 0000000..49dfa52 --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/GraphBinaryTextTests.cs @@ -0,0 +1,38 @@ +#region License + +/* + * Copyright 2018 JanusGraph.Net Authors + * + * Licensed 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 Gremlin.Net.Structure.IO.GraphBinary; +using JanusGraph.Net.IO.GraphBinary; +using Xunit; + +namespace JanusGraph.Net.IntegrationTest +{ + [Collection("JanusGraph Server collection")] + public class GraphBinaryTextTests : TextTests + { + public GraphBinaryTextTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port, + new GraphBinaryMessageSerializer(JanusGraphTypeSerializerRegistry.Instance)); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/GraphSONTextTests.cs b/test/JanusGraph.Net.IntegrationTest/GraphSONTextTests.cs new file mode 100644 index 0000000..2a0c01d --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/GraphSONTextTests.cs @@ -0,0 +1,36 @@ +#region License + +/* + * Copyright 2018 JanusGraph.Net Authors + * + * Licensed 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 Xunit; + +namespace JanusGraph.Net.IntegrationTest +{ + [Collection("JanusGraph Server collection")] + public class GraphSONTextTests : TextTests + { + public GraphSONTextTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = + new RemoteConnectionFactory(fixture.Host, fixture.Port); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GeoshapeDeserializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GeoshapeDeserializerTests.cs similarity index 71% rename from test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GeoshapeDeserializerTests.cs rename to test/JanusGraph.Net.IntegrationTest/IO/GeoshapeDeserializerTests.cs index 53e7fd5..d425dab 100644 --- a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GeoshapeDeserializerTests.cs +++ b/test/JanusGraph.Net.IntegrationTest/IO/GeoshapeDeserializerTests.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright 2018 JanusGraph.Net Authors + * Copyright 2021 JanusGraph.Net Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +24,17 @@ using Xunit; using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; -namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +namespace JanusGraph.Net.IntegrationTest.IO { [Collection("JanusGraph Server collection")] - public class GeoshapeDeserializerTests : IDisposable + public abstract class GeoshapeDeserializerTests : IDisposable { - private readonly RemoteConnectionFactory _connectionFactory; - - public GeoshapeDeserializerTests(JanusGraphServerFixture fixture) - { - _connectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); - } + protected abstract RemoteConnectionFactory ConnectionFactory { get; } [Fact] public async Task TraversalWithPointPropertyValue_PointReturned_ExpectedPoint() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var place = await g.V().Has("demigod", "name", "hercules").OutE("battled").Has("time", 1) .Values("place").Promise(t => t.Next()); @@ -51,7 +46,7 @@ public async Task TraversalWithPointPropertyValue_PointReturned_ExpectedPoint() public void Dispose() { - _connectionFactory?.Dispose(); + ConnectionFactory?.Dispose(); } } } \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GeoshapeSerializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GeoshapeSerializerTests.cs similarity index 69% rename from test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GeoshapeSerializerTests.cs rename to test/JanusGraph.Net.IntegrationTest/IO/GeoshapeSerializerTests.cs index 2e35f30..f658a97 100644 --- a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GeoshapeSerializerTests.cs +++ b/test/JanusGraph.Net.IntegrationTest/IO/GeoshapeSerializerTests.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright 2018 JanusGraph.Net Authors + * Copyright 2021 JanusGraph.Net Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +24,17 @@ using Xunit; using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; -namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +namespace JanusGraph.Net.IntegrationTest.IO { [Collection("JanusGraph Server collection")] - public class GeoshapeSerializerTests : IDisposable + public abstract class GeoshapeSerializerTests : IDisposable { - private readonly RemoteConnectionFactory _connectionFactory; - - public GeoshapeSerializerTests(JanusGraphServerFixture fixture) - { - _connectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); - } + protected abstract RemoteConnectionFactory ConnectionFactory { get; } [Fact] public async Task TraversalWithPointHasFilter_ExistingPoint_ElementFound() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.V().Has("demigod", "name", "hercules").OutE("battled") .Has("place", Geoshape.Point(38.1f, 23.7f)).Count().Promise(t => t.Next()); @@ -49,7 +44,7 @@ public async Task TraversalWithPointHasFilter_ExistingPoint_ElementFound() public void Dispose() { - _connectionFactory?.Dispose(); + ConnectionFactory?.Dispose(); } } } \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphBinary/GraphBinaryRelationIdentifierDeserializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GraphBinary/GraphBinaryRelationIdentifierDeserializerTests.cs new file mode 100644 index 0000000..c5c9a06 --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/IO/GraphBinary/GraphBinaryRelationIdentifierDeserializerTests.cs @@ -0,0 +1,38 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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 Gremlin.Net.Structure.IO.GraphBinary; +using JanusGraph.Net.IO.GraphBinary; +using Xunit; + +namespace JanusGraph.Net.IntegrationTest.IO.GraphBinary +{ + [Collection("JanusGraph Server collection")] + public class GraphBinaryRelationIdentifierDeserializerTests : RelationIdentifierDeserializerTests + { + public GraphBinaryRelationIdentifierDeserializerTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port, + new GraphBinaryMessageSerializer(JanusGraphTypeSerializerRegistry.Instance)); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphBinary/GraphBinaryRelationIdentifierSerializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GraphBinary/GraphBinaryRelationIdentifierSerializerTests.cs new file mode 100644 index 0000000..710e2da --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/IO/GraphBinary/GraphBinaryRelationIdentifierSerializerTests.cs @@ -0,0 +1,38 @@ +#region License + +/* + * Copyright 2021 JanusGraph.Net Authors + * + * Licensed 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 Gremlin.Net.Structure.IO.GraphBinary; +using JanusGraph.Net.IO.GraphBinary; +using Xunit; + +namespace JanusGraph.Net.IntegrationTest.IO.GraphBinary +{ + [Collection("JanusGraph Server collection")] + public class GraphBinaryRelationIdentifierSerializerTests : RelationIdentifierSerializerTests + { + public GraphBinaryRelationIdentifierSerializerTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port, + new GraphBinaryMessageSerializer(JanusGraphTypeSerializerRegistry.Instance)); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONGeoshapeDeserializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONGeoshapeDeserializerTests.cs new file mode 100644 index 0000000..6084f10 --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONGeoshapeDeserializerTests.cs @@ -0,0 +1,35 @@ +#region License + +/* + * Copyright 2018 JanusGraph.Net Authors + * + * Licensed 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 Xunit; + +namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +{ + [Collection("JanusGraph Server collection")] + public class GraphSONGeoshapeDeserializerTests : GeoshapeDeserializerTests + { + public GraphSONGeoshapeDeserializerTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONGeoshapeSerializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONGeoshapeSerializerTests.cs new file mode 100644 index 0000000..07c9daa --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONGeoshapeSerializerTests.cs @@ -0,0 +1,35 @@ +#region License + +/* + * Copyright 2018 JanusGraph.Net Authors + * + * Licensed 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 Xunit; + +namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +{ + [Collection("JanusGraph Server collection")] + public class GraphSONGeoshapeSerializerTests : GeoshapeSerializerTests + { + public GraphSONGeoshapeSerializerTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONRelationIdentifierDeserializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONRelationIdentifierDeserializerTests.cs new file mode 100644 index 0000000..2829665 --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONRelationIdentifierDeserializerTests.cs @@ -0,0 +1,35 @@ +#region License + +/* + * Copyright 2018 JanusGraph.Net Authors + * + * Licensed 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 Xunit; + +namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +{ + [Collection("JanusGraph Server collection")] + public class GraphSONRelationIdentifierDeserializerTests : RelationIdentifierDeserializerTests + { + public GraphSONRelationIdentifierDeserializerTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONRelationIdentifierSerializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONRelationIdentifierSerializerTests.cs new file mode 100644 index 0000000..0bd1f20 --- /dev/null +++ b/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/GraphSONRelationIdentifierSerializerTests.cs @@ -0,0 +1,35 @@ +#region License + +/* + * Copyright 2018 JanusGraph.Net Authors + * + * Licensed 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 Xunit; + +namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +{ + [Collection("JanusGraph Server collection")] + public class GraphSONRelationIdentifierSerializerTests : RelationIdentifierSerializerTests + { + public GraphSONRelationIdentifierSerializerTests(JanusGraphServerFixture fixture) + { + ConnectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); + } + + protected override RemoteConnectionFactory ConnectionFactory { get; } + } +} \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/RelationIdentifierDeserializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/RelationIdentifierDeserializerTests.cs similarity index 69% rename from test/JanusGraph.Net.IntegrationTest/IO/GraphSON/RelationIdentifierDeserializerTests.cs rename to test/JanusGraph.Net.IntegrationTest/IO/RelationIdentifierDeserializerTests.cs index e9ec94f..7202ad8 100644 --- a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/RelationIdentifierDeserializerTests.cs +++ b/test/JanusGraph.Net.IntegrationTest/IO/RelationIdentifierDeserializerTests.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright 2018 JanusGraph.Net Authors + * Copyright 2021 JanusGraph.Net Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,22 +23,17 @@ using Xunit; using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; -namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +namespace JanusGraph.Net.IntegrationTest.IO { [Collection("JanusGraph Server collection")] - public class RelationIdentifierDeserializerTests : IDisposable + public abstract class RelationIdentifierDeserializerTests : IDisposable { - private readonly RemoteConnectionFactory _connectionFactory; - - public RelationIdentifierDeserializerTests(JanusGraphServerFixture fixture) - { - _connectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); - } + protected abstract RemoteConnectionFactory ConnectionFactory { get; } [Fact] public async Task TraversalWithEdgeId_RelationIdentifierReturned_ValidRelationIdentifier() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var relationIdentifier = await g.V().Has("demigod", "name", "hercules").OutE("father").Id().Promise(t => t.Next()); @@ -49,7 +44,7 @@ public async Task TraversalWithEdgeId_RelationIdentifierReturned_ValidRelationId [Fact] public async Task TraversalWithEdge_EdgeReturned_EdgeWithIdOfTypeRelationIdentifier() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var edge = await g.V().Has("demigod", "name", "hercules").OutE("father").Promise(t => t.Next()); @@ -58,7 +53,7 @@ public async Task TraversalWithEdge_EdgeReturned_EdgeWithIdOfTypeRelationIdentif public void Dispose() { - _connectionFactory?.Dispose(); + ConnectionFactory?.Dispose(); } } } \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/RelationIdentifierSerializerTests.cs b/test/JanusGraph.Net.IntegrationTest/IO/RelationIdentifierSerializerTests.cs similarity index 68% rename from test/JanusGraph.Net.IntegrationTest/IO/GraphSON/RelationIdentifierSerializerTests.cs rename to test/JanusGraph.Net.IntegrationTest/IO/RelationIdentifierSerializerTests.cs index cbcee51..2297ca7 100644 --- a/test/JanusGraph.Net.IntegrationTest/IO/GraphSON/RelationIdentifierSerializerTests.cs +++ b/test/JanusGraph.Net.IntegrationTest/IO/RelationIdentifierSerializerTests.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright 2018 JanusGraph.Net Authors + * Copyright 2021 JanusGraph.Net Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,22 +23,17 @@ using Xunit; using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; -namespace JanusGraph.Net.IntegrationTest.IO.GraphSON +namespace JanusGraph.Net.IntegrationTest.IO { [Collection("JanusGraph Server collection")] - public class RelationIdentifierSerializerTests : IDisposable + public abstract class RelationIdentifierSerializerTests : IDisposable { - private readonly RemoteConnectionFactory _connectionFactory; - - public RelationIdentifierSerializerTests(JanusGraphServerFixture fixture) - { - _connectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); - } + protected abstract RemoteConnectionFactory ConnectionFactory { get; } [Fact] public async Task TraversalWithRelationIdentifierAsEdgeId_ExistingEdgeId_EdgeFound() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var edgeId = await g.E().Id().Promise(t => t.Next()); var count = await g.E(edgeId).Count().Promise(t => t.Next()); @@ -49,7 +44,7 @@ public async Task TraversalWithRelationIdentifierAsEdgeId_ExistingEdgeId_EdgeFou [Fact] public async Task TraversalWithEdge_ExistingEdge_EdgeFound() { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var edge = await g.E().Promise(t => t.Next()); var count = await g.E(edge).Count().Promise(t => t.Next()); @@ -59,7 +54,7 @@ public async Task TraversalWithEdge_ExistingEdge_EdgeFound() public void Dispose() { - _connectionFactory?.Dispose(); + ConnectionFactory?.Dispose(); } } } \ No newline at end of file diff --git a/test/JanusGraph.Net.IntegrationTest/RemoteConnectionFactory.cs b/test/JanusGraph.Net.IntegrationTest/RemoteConnectionFactory.cs index fb430c9..3c40c47 100644 --- a/test/JanusGraph.Net.IntegrationTest/RemoteConnectionFactory.cs +++ b/test/JanusGraph.Net.IntegrationTest/RemoteConnectionFactory.cs @@ -23,25 +23,33 @@ using Gremlin.Net.Driver; using Gremlin.Net.Driver.Remote; using Gremlin.Net.Process.Remote; +using JanusGraph.Net.IO.GraphSON; namespace JanusGraph.Net.IntegrationTest { - internal class RemoteConnectionFactory : IDisposable + public class RemoteConnectionFactory : IDisposable { private readonly IList _connections = new List(); private readonly string _host; private readonly int _port; + private readonly IMessageSerializer _serializer; public RemoteConnectionFactory(string host, int port) + : this(host, port, new JanusGraphGraphSONMessageSerializer()) + { + } + + public RemoteConnectionFactory(string host, int port, IMessageSerializer serializer) { _host = host; _port = port; + _serializer = serializer; } public IRemoteConnection CreateRemoteConnection() { var c = new DriverRemoteConnection(JanusGraphClientBuilder - .BuildClientForServer(new GremlinServer(_host, _port)).Create()); + .BuildClientForServer(new GremlinServer(_host, _port)).WithSerializer(_serializer).Create()); _connections.Add(c); return c; } diff --git a/test/JanusGraph.Net.IntegrationTest/TextTests.cs b/test/JanusGraph.Net.IntegrationTest/TextTests.cs index 17b7ef9..975dcc0 100644 --- a/test/JanusGraph.Net.IntegrationTest/TextTests.cs +++ b/test/JanusGraph.Net.IntegrationTest/TextTests.cs @@ -20,28 +20,22 @@ using System; using System.Threading.Tasks; -using Gremlin.Net.Structure; using Xunit; using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; namespace JanusGraph.Net.IntegrationTest { [Collection("JanusGraph Server collection")] - public class TextTests : IDisposable + public abstract class TextTests : IDisposable { - private readonly RemoteConnectionFactory _connectionFactory; - - public TextTests(JanusGraphServerFixture fixture) - { - _connectionFactory = new RemoteConnectionFactory(fixture.Host, fixture.Port); - } + protected abstract RemoteConnectionFactory ConnectionFactory { get; } [Theory] [InlineData("loves", 2)] [InlineData("shouldNotBeFound", 0)] public async Task TextContainsgivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.E().Has("reason", Text.TextContains(searchText)).Count().Promise(t => t.Next()); @@ -54,7 +48,7 @@ public async Task TextContainsgivenSearchText_ExpectedCountOfElements(string sea [InlineData("shouldNotBeFound", 0)] public async Task TextContainsPrefixgivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.E().Has("reason", Text.TextContainsPrefix(searchText)).Count().Promise(t => t.Next()); @@ -67,7 +61,7 @@ public async Task TextContainsPrefixgivenSearchText_ExpectedCountOfElements(stri [InlineData("shouldNotBeFound", 0)] public async Task TextContainsRegexgivenRegex_ExpectedCountOfElements(string regex, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.E().Has("reason", Text.TextContainsRegex(regex)).Count().Promise(t => t.Next()); @@ -79,7 +73,7 @@ public async Task TextContainsRegexgivenRegex_ExpectedCountOfElements(string reg [InlineData("shouldNotBeFound", 0)] public async Task TextContainsFuzzygivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.E().Has("reason", Text.TextContainsFuzzy(searchText)).Count().Promise(t => t.Next()); @@ -92,7 +86,7 @@ public async Task TextContainsFuzzygivenSearchText_ExpectedCountOfElements(strin [InlineData("shouldNotBeFound", 0)] public async Task TextPrefixgivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.V().Has("name", Text.TextPrefix(searchText)).Count().Promise(t => t.Next()); @@ -105,7 +99,7 @@ public async Task TextPrefixgivenSearchText_ExpectedCountOfElements(string searc [InlineData("shouldNotBeFound", 0)] public async Task TextRegexgivenRegex_ExpectedCountOfElements(string regex, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.V().Has("name", Text.TextRegex(regex)).Count().Promise(t => t.Next()); @@ -118,7 +112,7 @@ public async Task TextRegexgivenRegex_ExpectedCountOfElements(string regex, int [InlineData("shouldNotBeFound", 0)] public async Task TextFuzzygivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount) { - var g = Traversal().WithRemote(_connectionFactory.CreateRemoteConnection()); + var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection()); var count = await g.V().Has("name", Text.TextFuzzy(searchText)).Count().Promise(t => t.Next()); @@ -127,7 +121,7 @@ public async Task TextFuzzygivenSearchText_ExpectedCountOfElements(string search public void Dispose() { - _connectionFactory?.Dispose(); + ConnectionFactory?.Dispose(); } } } \ No newline at end of file diff --git a/test/JanusGraph.Net.UnitTest/IO/GraphSON/RelationIdentifierSerializationSymmetricyTests.cs b/test/JanusGraph.Net.UnitTest/IO/GraphSON/RelationIdentifierSerializationSymmetricyTests.cs index 49c6a52..9b1f758 100644 --- a/test/JanusGraph.Net.UnitTest/IO/GraphSON/RelationIdentifierSerializationSymmetricyTests.cs +++ b/test/JanusGraph.Net.UnitTest/IO/GraphSON/RelationIdentifierSerializationSymmetricyTests.cs @@ -29,7 +29,7 @@ public class RelationIdentifierSerializationSymmetricyTests [Fact] public void SerializeAndDeserialize_ValidRelationIdentifier_SameRelationIdentifier() { - var relationIdentifier = new RelationIdentifier("someRelationId"); + var relationIdentifier = new RelationIdentifier("4qp-360-7x1-3aw"); var writer = JanusGraphSONWriterBuilder.Build().Create(); var reader = JanusGraphSONReaderBuilder.Build().Create(); diff --git a/test/JanusGraph.Net.UnitTest/RelationIdentifierTests.cs b/test/JanusGraph.Net.UnitTest/RelationIdentifierTests.cs index 73ad1b6..910616b 100644 --- a/test/JanusGraph.Net.UnitTest/RelationIdentifierTests.cs +++ b/test/JanusGraph.Net.UnitTest/RelationIdentifierTests.cs @@ -32,5 +32,25 @@ public void ToString_ValidRelationId_RelationId() Assert.Equal(relationId, relationIdentifier.ToString()); } + + [Fact] + public void CtrWithStr_ValidRelationId_ExpectedLongValues() + { + var relationIdentifier = new RelationIdentifier("4qp-360-7x1-3aw"); + + Assert.Equal(4104, relationIdentifier.OutVertexId); + Assert.Equal(10261, relationIdentifier.TypeId); + Assert.Equal(6145, relationIdentifier.RelationId); + Assert.Equal(4280, relationIdentifier.InVertexId); + } + + [Fact] + public void CtrWithLongs_ValidLongValues_ExpectedStringRepresentation() + { + var relationIdentifier = new RelationIdentifier(4104, 10261, 6145, 4280); + + Assert.Equal("4qp-360-7x1-3aw", relationIdentifier.StringRepresentation); + Assert.Equal("4qp-360-7x1-3aw", relationIdentifier.ToString()); + } } } \ No newline at end of file