csharp/rocketmq-client-csharp/Endpoints.cs (151 lines of code) (raw):

/* * 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. */ using System; using System.Collections.Generic; using System.Linq; using Proto = Apache.Rocketmq.V2; namespace Org.Apache.Rocketmq { public class Endpoints : IEquatable<Endpoints> { private const string HttpPrefix = "http://"; private const string HttpsPrefix = "https://"; private const int DefaultPort = 80; private static readonly AddressListEqualityComparer AddressListComparer = new AddressListEqualityComparer(); private const string EndpointSeparator = ":"; public List<Address> Addresses { get; } private AddressScheme Scheme { get; } private readonly int _hashCode; public Endpoints(Proto.Endpoints endpoints) { Addresses = new List<Address>(); foreach (var address in endpoints.Addresses) { Addresses.Add(new Address(address)); } if (!Addresses.Any()) { throw new NotSupportedException("No available address"); } switch (endpoints.Scheme) { case Proto.AddressScheme.Ipv4: Scheme = AddressScheme.Ipv4; break; case Proto.AddressScheme.Ipv6: Scheme = AddressScheme.Ipv6; break; case Proto.AddressScheme.DomainName: case Proto.AddressScheme.Unspecified: default: Scheme = AddressScheme.DomainName; if (Addresses.Count > 1) { throw new NotSupportedException("Multiple addresses are not allowed in domain scheme"); } break; } unchecked { var hash = 17; hash = (hash * 31) + AddressListComparer.GetHashCode(Addresses); hash = (hash * 31) + (int)Scheme; _hashCode = hash; } } // TODO: Multiple addresses has not been supported yet. public Endpoints(string endpoints) { if (endpoints.StartsWith(HttpPrefix)) { endpoints = endpoints[HttpPrefix.Length..]; } if (endpoints.StartsWith(HttpsPrefix)) { endpoints = endpoints[HttpsPrefix.Length..]; } var index = endpoints.IndexOf(EndpointSeparator, StringComparison.Ordinal); var port = index > 0 ? int.Parse(endpoints[(1 + index)..]) : DefaultPort; var host = index > 0 ? endpoints.Substring(0, index) : endpoints; var uriHostNameType = Uri.CheckHostName(host); Scheme = AddressScheme.DomainName; switch (uriHostNameType) { case UriHostNameType.IPv4: Scheme = AddressScheme.Ipv4; break; case UriHostNameType.IPv6: Scheme = AddressScheme.Ipv6; break; case UriHostNameType.Dns: case UriHostNameType.Basic: case UriHostNameType.Unknown: default: Scheme = AddressScheme.DomainName; break; } var address = new Address(host, port); var addresses = new List<Address> { address }; Addresses = addresses; unchecked { var hash = 17; hash = (hash * 31) + AddressListComparer.GetHashCode(Addresses); hash = (hash * 31) + (int)Scheme; _hashCode = hash; } } public override string ToString() { foreach (var address in Addresses) { return address.Host + EndpointSeparator + address.Port; } throw new ArgumentException("No available address"); } // TODO: Support multiple addresses. public string GrpcTarget(bool sslEnabled) { var prefix = sslEnabled ? HttpsPrefix : HttpPrefix; foreach (var address in Addresses) { return prefix + address.Host + EndpointSeparator + address.Port; } throw new ArgumentException("No available address"); } public bool Equals(Endpoints other) { if (ReferenceEquals(null, other)) { return false; } if (ReferenceEquals(this, other)) { return true; } return Addresses.SequenceEqual(other.Addresses) && Scheme == other.Scheme; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } if (ReferenceEquals(this, obj)) { return true; } return obj.GetType() == GetType() && Equals((Endpoints)obj); } public override int GetHashCode() { return _hashCode; } public Proto.Endpoints ToProtobuf() { var endpoints = new Proto.Endpoints(); foreach (var address in Addresses) { endpoints.Addresses.Add(address.ToProtobuf()); } endpoints.Scheme = AddressSchemeHelper.ToProtobuf(Scheme); return endpoints; } } }