< Summary

Information
Class: Ice.Internal.RoutableReference
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/Internal/Reference.cs
Tag: 71_18251537082
Line coverage
95%
Covered lines: 287
Uncovered lines: 14
Coverable lines: 301
Total lines: 1277
Line coverage: 95.3%
Branch coverage
93%
Covered branches: 133
Total branches: 142
Branch coverage: 93.6%
Method coverage
100%
Covered methods: 54
Total methods: 54
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_batchRequestQueue()100%11100%
getEndpoints()100%11100%
getAdapterId()100%11100%
getLocatorInfo()100%11100%
getRouterInfo()100%11100%
getCollocationOptimized()100%11100%
getCacheConnection()100%11100%
getEndpointSelection()100%11100%
getLocatorCacheTimeout()100%11100%
getConnectionId()100%11100%
changeMode(...)100%11100%
getThreadPool()100%11100%
getConnection()100%11100%
changeEncoding(...)100%66100%
changeCompress(...)100%66100%
changeEndpoints(...)100%11100%
changeAdapterId(...)100%11100%
changeLocator(...)100%11100%
changeRouter(...)100%11100%
changeCollocationOptimized(...)100%11100%
changeCacheConnection(...)100%11100%
changeEndpointSelection(...)100%11100%
changeLocatorCacheTimeout(...)100%11100%
changeConnectionId(...)100%44100%
changeConnection(...)100%11100%
isIndirect()100%11100%
isWellKnown()100%22100%
streamWrite(...)100%44100%
ToString()91.67%12.791282.35%
toProperty(...)100%1414100%
GetHashCode()100%22100%
Equals(...)100%2222100%
Clone()100%11100%
.ctor(...)100%11100%
setEndpoints(...)50%2.26260%
setException(...)100%11100%
getRequestHandler()100%44100%
getConnection(...)100%22100%
.ctor(...)100%11100%
setEndpoints(...)100%22100%
setException(...)100%11100%
.ctor(...)100%11100%
setConnection(...)100%11100%
setException(...)50%7.58664.71%
getConnectionNoRouterInfo(...)100%44100%
.ctor(...)100%44100%
applyOverrides(...)75%4.07483.33%
filterEndpoints(...)91.67%2424100%
.ctor(...)100%11100%
setConnection(...)100%44100%
setException(...)100%66100%
createConnection(...)83.33%6.17683.33%
setBatchRequestQueue()100%22100%
.cctor()100%11100%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/Internal/Reference.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4using System.Globalization;
 5using System.Text;
 6
 7namespace Ice.Internal;
 8
 9public abstract class Reference : IEquatable<Reference>
 10{
 11    /// <summary>
 12    /// Represents the invocation mode of a proxy.
 13    /// </summary>
 14    public enum Mode
 15    {
 16        /// <summary>
 17        /// A two-way invocation that always expects a response.
 18        /// </summary>
 19        ModeTwoway,
 20
 21        /// <summary>
 22        /// A one-way invocation that does not expect a response and completes as soon as the request is sent.
 23        /// </summary>
 24        ModeOneway,
 25
 26        /// <summary>
 27        /// A batch one-way invocation that allows grouping several one-way invocations into a single batch.
 28        /// </summary>
 29        ModeBatchOneway,
 30
 31        /// <summary>
 32        /// A datagram invocation that does not expect a response and is sent using UDP.
 33        /// </summary>
 34        ModeDatagram,
 35
 36        /// <summary>
 37        /// A batch datagram invocation that allows grouping several datagram invocations into a single batch.
 38        /// </summary>
 39        ModeBatchDatagram
 40    }
 41
 42    public interface GetConnectionCallback
 43    {
 44        void setConnection(Ice.ConnectionI connection, bool compress);
 45
 46        void setException(Ice.LocalException ex);
 47    }
 48
 49    internal abstract BatchRequestQueue batchRequestQueue { get; }
 50
 51    internal bool isBatch => _mode is Mode.ModeBatchOneway or Mode.ModeBatchDatagram;
 52
 53    internal bool isTwoway => _mode is Mode.ModeTwoway;
 54
 55    public Mode getMode() => _mode;
 56
 57    public Ice.ProtocolVersion getProtocol() => _protocol;
 58
 59    public Ice.EncodingVersion getEncoding() => _encoding;
 60
 61    public Ice.Identity getIdentity() => _identity;
 62
 63    public string getFacet() => _facet;
 64
 65    public Instance getInstance() => _instance;
 66
 67    public Dictionary<string, string> getContext() => _context;
 68
 69    public TimeSpan
 70    getInvocationTimeout() => _invocationTimeout;
 71
 72    public bool?
 73    getCompress() => _compress;
 74
 75    public Ice.Communicator getCommunicator() => _communicator;
 76
 77    public abstract EndpointI[] getEndpoints();
 78
 79    public abstract string getAdapterId();
 80
 81    public abstract LocatorInfo getLocatorInfo();
 82
 83    public abstract RouterInfo getRouterInfo();
 84
 85    public abstract bool getCollocationOptimized();
 86
 87    public abstract bool getCacheConnection();
 88
 89    public abstract Ice.EndpointSelectionType getEndpointSelection();
 90
 91    public abstract TimeSpan getLocatorCacheTimeout();
 92
 93    public abstract string getConnectionId();
 94
 95    public abstract ThreadPool getThreadPool();
 96
 97    public abstract Connection getConnection();
 98
 99    //
 100    // The change* methods (here and in derived classes) create
 101    // a new reference based on the existing one, with the
 102    // corresponding value changed.
 103    //
 104    public Reference changeContext(Dictionary<string, string> newContext)
 105    {
 106        newContext ??= _emptyContext;
 107        Reference r = _instance.referenceFactory().copy(this);
 108        if (newContext.Count == 0)
 109        {
 110            r._context = _emptyContext;
 111        }
 112        else
 113        {
 114            r._context = new Dictionary<string, string>(newContext);
 115        }
 116        return r;
 117    }
 118
 119    public virtual Reference changeMode(Mode newMode)
 120    {
 121        Reference r = _instance.referenceFactory().copy(this);
 122        r._mode = newMode;
 123        return r;
 124    }
 125
 126    public Reference changeIdentity(Ice.Identity newIdentity)
 127    {
 128        Reference r = _instance.referenceFactory().copy(this);
 129        // Identity is a reference type, therefore we make a copy of newIdentity.
 130        r._identity = newIdentity with { };
 131        return r;
 132    }
 133
 134    public Reference changeFacet(string newFacet)
 135    {
 136        Reference r = _instance.referenceFactory().copy(this);
 137        r._facet = newFacet;
 138        return r;
 139    }
 140
 141    public Reference changeInvocationTimeout(TimeSpan newTimeout)
 142    {
 143        Reference r = _instance.referenceFactory().copy(this);
 144        r._invocationTimeout = newTimeout;
 145        return r;
 146    }
 147
 148    public virtual Reference changeEncoding(Ice.EncodingVersion newEncoding)
 149    {
 150        Reference r = _instance.referenceFactory().copy(this);
 151        r._encoding = newEncoding;
 152        return r;
 153    }
 154
 155    public virtual Reference changeCompress(bool newCompress)
 156    {
 157        Reference r = _instance.referenceFactory().copy(this);
 158        r._compress = newCompress;
 159        return r;
 160    }
 161
 162    public abstract Reference changeEndpoints(EndpointI[] newEndpoints);
 163
 164    public abstract Reference changeAdapterId(string newAdapterId);
 165
 166    public abstract Reference changeLocator(Ice.LocatorPrx newLocator);
 167
 168    public abstract Reference changeRouter(Ice.RouterPrx newRouter);
 169
 170    public abstract Reference changeCollocationOptimized(bool newCollocationOptimized);
 171
 172    public abstract Reference changeCacheConnection(bool newCache);
 173
 174    public abstract Reference changeEndpointSelection(Ice.EndpointSelectionType newType);
 175
 176    public abstract Reference changeLocatorCacheTimeout(TimeSpan newTimeout);
 177
 178    public abstract Reference changeConnectionId(string connectionId);
 179
 180    public abstract Reference changeConnection(Ice.ConnectionI connection);
 181
 182    // Gets the effective compression setting, taking into account the override.
 183    public bool? getCompressOverride()
 184    {
 185        DefaultsAndOverrides defaultsAndOverrides = getInstance().defaultsAndOverrides();
 186        return defaultsAndOverrides.overrideCompress ?? _compress;
 187    }
 188
 189    public abstract bool isIndirect();
 190
 191    public abstract bool isWellKnown();
 192
 193    //
 194    // Marshal the reference.
 195    //
 196    public virtual void streamWrite(Ice.OutputStream s)
 197    {
 198        //
 199        // Don't write the identity here. Operations calling streamWrite
 200        // write the identity.
 201        //
 202
 203        //
 204        // For compatibility with the old FacetPath.
 205        //
 206        if (_facet.Length == 0)
 207        {
 208            s.writeStringSeq(null);
 209        }
 210        else
 211        {
 212            string[] facetPath = { _facet };
 213            s.writeStringSeq(facetPath);
 214        }
 215
 216        s.writeByte((byte)_mode);
 217
 218        s.writeBool(false); // the secure field is no longer used
 219
 220        if (!s.getEncoding().Equals(Ice.Util.Encoding_1_0))
 221        {
 222            ProtocolVersion.ice_write(s, _protocol);
 223            EncodingVersion.ice_write(s, _encoding);
 224        }
 225
 226        // Derived class writes the remainder of the reference.
 227    }
 228
 229    //
 230    // Convert the reference to its string form.
 231    //
 232    public override string ToString()
 233    {
 234        //
 235        // WARNING: Certain features, such as proxy validation in Glacier2,
 236        // depend on the format of proxy strings. Changes to toString() and
 237        // methods called to generate parts of the reference string could break
 238        // these features. Please review for all features that depend on the
 239        // format of proxyToString() before changing this and related code.
 240        //
 241        var s = new StringBuilder();
 242
 243        Ice.ToStringMode toStringMode = _instance.toStringMode();
 244
 245        //
 246        // If the encoded identity string contains characters which
 247        // the reference parser uses as separators, then we enclose
 248        // the identity string in quotes.
 249        //
 250        string id = Ice.Util.identityToString(_identity, toStringMode);
 251        if (Ice.UtilInternal.StringUtil.findFirstOf(id, " :@") != -1)
 252        {
 253            s.Append('"');
 254            s.Append(id);
 255            s.Append('"');
 256        }
 257        else
 258        {
 259            s.Append(id);
 260        }
 261
 262        if (_facet.Length > 0)
 263        {
 264            //
 265            // If the encoded facet string contains characters which
 266            // the reference parser uses as separators, then we enclose
 267            // the facet string in quotes.
 268            //
 269            s.Append(" -f ");
 270            string fs = Ice.UtilInternal.StringUtil.escapeString(_facet, "", toStringMode);
 271            if (Ice.UtilInternal.StringUtil.findFirstOf(fs, " :@") != -1)
 272            {
 273                s.Append('"');
 274                s.Append(fs);
 275                s.Append('"');
 276            }
 277            else
 278            {
 279                s.Append(fs);
 280            }
 281        }
 282
 283        switch (_mode)
 284        {
 285            case Mode.ModeTwoway:
 286            {
 287                // Don't print the default mode.
 288                break;
 289            }
 290
 291            case Mode.ModeOneway:
 292            {
 293                s.Append(" -o");
 294                break;
 295            }
 296
 297            case Mode.ModeBatchOneway:
 298            {
 299                s.Append(" -O");
 300                break;
 301            }
 302
 303            case Mode.ModeDatagram:
 304            {
 305                s.Append(" -d");
 306                break;
 307            }
 308
 309            case Mode.ModeBatchDatagram:
 310            {
 311                s.Append(" -D");
 312                break;
 313            }
 314        }
 315
 316        if (_protocol != Ice.Util.Protocol_1_0)
 317        {
 318            // We print the protocol unless it's 1.0.
 319            s.Append(" -p ");
 320            s.Append(Ice.Util.protocolVersionToString(_protocol));
 321        }
 322
 323        // We print the encoding if it's not 1.1 or if Ice.Default.EncodingVersion is set to something other than 1.1.
 324        if (_encoding != Ice.Util.Encoding_1_1 ||
 325            _instance.defaultsAndOverrides().defaultEncoding != Ice.Util.Encoding_1_1)
 326        {
 327            s.Append(" -e ");
 328            s.Append(Ice.Util.encodingVersionToString(_encoding));
 329        }
 330
 331        return s.ToString();
 332
 333        // Derived class writes the remainder of the string.
 334    }
 335
 336    public abstract Dictionary<string, string> toProperty(string prefix);
 337
 338    internal abstract RequestHandler getRequestHandler();
 339
 340    public static bool operator ==(Reference lhs, Reference rhs) => lhs is null ? rhs is null : lhs.Equals(rhs);
 341
 342    public static bool operator !=(Reference lhs, Reference rhs) => !(lhs == rhs);
 343
 344    public override int GetHashCode()
 345    {
 346        var hash = new HashCode();
 347        hash.Add(_mode);
 348        hash.Add(_identity);
 349        hash.Add(_context.Count); // we only hash the count, not the contents
 350        hash.Add(_facet);
 351        hash.Add(_compress);
 352        // We don't hash protocol and encoding; they are usually "1.0" and "1.1" respectively.
 353        hash.Add(_invocationTimeout);
 354        return hash.ToHashCode();
 355    }
 356
 357    public virtual bool Equals(Reference other)
 358    {
 359        // The derived class checks ReferenceEquals and guarantees other is not null.
 360        Debug.Assert(other is not null);
 361
 362        return _mode == other._mode &&
 363            _identity == other._identity &&
 364            _context.DictionaryEqual(other._context) &&
 365            _facet == other._facet &&
 366            _compress == other._compress &&
 367            _protocol == other._protocol &&
 368            _encoding == other._encoding &&
 369            _invocationTimeout == other._invocationTimeout;
 370    }
 371
 372    public override bool Equals(object obj) => Equals(obj as Reference);
 373
 374    public virtual Reference Clone() => (Reference)MemberwiseClone();
 375
 376    private static readonly Dictionary<string, string> _emptyContext = new Dictionary<string, string>();
 377
 378    private protected Instance _instance;
 379    private readonly Ice.Communicator _communicator;
 380
 381    private Mode _mode;
 382    private Ice.Identity _identity;
 383    private Dictionary<string, string> _context;
 384    private string _facet;
 385    private Ice.ProtocolVersion _protocol;
 386    private Ice.EncodingVersion _encoding;
 387    private TimeSpan _invocationTimeout;
 388    private bool? _compress;
 389
 390    protected Reference(
 391        Instance instance,
 392        Ice.Communicator communicator,
 393        Ice.Identity identity,
 394        string facet,
 395        Mode mode,
 396        bool? compress,
 397        Ice.ProtocolVersion protocol,
 398        Ice.EncodingVersion encoding,
 399        TimeSpan invocationTimeout,
 400        Dictionary<string, string> context)
 401    {
 402        // Validate string arguments.
 403        Debug.Assert(facet != null);
 404
 405        _instance = instance;
 406        _communicator = communicator;
 407        _mode = mode;
 408        _identity = identity;
 409        _context = context != null ? new Dictionary<string, string>(context) : _emptyContext;
 410        _facet = facet;
 411        _protocol = protocol;
 412        _encoding = encoding;
 413        _invocationTimeout = invocationTimeout;
 414        _compress = compress;
 415    }
 416
 417    protected static Random rand_ = new Random(unchecked((int)DateTime.Now.Ticks));
 418}
 419
 420public class FixedReference : Reference
 421{
 422    internal override BatchRequestQueue batchRequestQueue => _fixedConnection.getBatchRequestQueue();
 423
 424    public FixedReference(
 425        Instance instance,
 426        Ice.Communicator communicator,
 427        Ice.Identity identity,
 428        string facet,
 429        Mode mode,
 430        bool? compress,
 431        Ice.ProtocolVersion protocol,
 432        Ice.EncodingVersion encoding,
 433        Ice.ConnectionI connection,
 434        TimeSpan invocationTimeout,
 435        Dictionary<string, string> context)
 436    : base(
 437        instance,
 438        communicator,
 439        identity,
 440        facet,
 441        mode,
 442        compress,
 443        protocol,
 444        encoding,
 445        invocationTimeout,
 446        context) =>
 447        _fixedConnection = connection;
 448
 449    public override EndpointI[] getEndpoints() => _emptyEndpoints;
 450
 451    public override string getAdapterId() => "";
 452
 453    public override LocatorInfo getLocatorInfo() => null;
 454
 455    public override RouterInfo getRouterInfo() => null;
 456
 457    public override bool getCollocationOptimized() => false;
 458
 459    public override bool getCacheConnection() => true;
 460
 461    public override Ice.EndpointSelectionType getEndpointSelection() => Ice.EndpointSelectionType.Random;
 462
 463    public override TimeSpan getLocatorCacheTimeout() => TimeSpan.Zero;
 464
 465    public override string getConnectionId() => "";
 466
 467    public override ThreadPool getThreadPool() => _fixedConnection.getThreadPool();
 468
 469    public override Connection getConnection() => _fixedConnection;
 470
 471    public override Reference changeEndpoints(EndpointI[] newEndpoints) => throw new Ice.FixedProxyException();
 472
 473    public override Reference changeAdapterId(string newAdapterId) => throw new Ice.FixedProxyException();
 474
 475    public override Reference changeLocator(Ice.LocatorPrx newLocator) => throw new Ice.FixedProxyException();
 476
 477    public override Reference changeRouter(Ice.RouterPrx newRouter) => throw new Ice.FixedProxyException();
 478
 479    public override Reference changeCollocationOptimized(bool newCollocationOptimized) =>
 480        throw new Ice.FixedProxyException();
 481
 482    public override Reference changeCacheConnection(bool newCache) => throw new Ice.FixedProxyException();
 483
 484    public override Reference changeEndpointSelection(Ice.EndpointSelectionType newType) =>
 485        throw new Ice.FixedProxyException();
 486
 487    public override Reference changeLocatorCacheTimeout(TimeSpan newTimeout) => throw new Ice.FixedProxyException();
 488
 489    public override Reference changeConnectionId(string connectionId) => throw new Ice.FixedProxyException();
 490
 491    public override Reference changeConnection(Ice.ConnectionI connection)
 492    {
 493        if (_fixedConnection == connection)
 494        {
 495            return this;
 496        }
 497        var r = (FixedReference)getInstance().referenceFactory().copy(this);
 498        r._fixedConnection = connection;
 499        return r;
 500    }
 501
 502    public override bool isIndirect() => false;
 503
 504    public override bool isWellKnown() => false;
 505
 506    public override void streamWrite(Ice.OutputStream s) => throw new Ice.FixedProxyException();
 507
 508    public override Dictionary<string, string> toProperty(string prefix) => throw new Ice.FixedProxyException();
 509
 510    internal override RequestHandler getRequestHandler()
 511    {
 512        // We need to perform all these checks here and not in the constructor because changeConnection() clones then
 513        // sets the connection.
 514
 515        switch (getMode())
 516        {
 517            case Mode.ModeTwoway:
 518            case Mode.ModeOneway:
 519            case Mode.ModeBatchOneway:
 520            {
 521                if (_fixedConnection.endpoint().datagram())
 522                {
 523                    throw new NoEndpointException(new ObjectPrxHelper(this));
 524                }
 525                break;
 526            }
 527
 528            case Mode.ModeDatagram:
 529            case Mode.ModeBatchDatagram:
 530            {
 531                if (!_fixedConnection.endpoint().datagram())
 532                {
 533                    throw new NoEndpointException(new ObjectPrxHelper(this));
 534                }
 535                break;
 536            }
 537        }
 538
 539        _fixedConnection.throwException(); // Throw in case our connection is already destroyed.
 540
 541        DefaultsAndOverrides defaultsAndOverrides = getInstance().defaultsAndOverrides();
 542        bool compress = defaultsAndOverrides.overrideCompress ?? getCompress() ?? false;
 543        return new FixedRequestHandler(this, _fixedConnection, compress);
 544    }
 545
 546    public override bool Equals(Reference other)
 547    {
 548        if (ReferenceEquals(this, other))
 549        {
 550            return true;
 551        }
 552        var rhs = other as FixedReference;
 553        return rhs is not null && base.Equals(rhs) && _fixedConnection.Equals(rhs._fixedConnection);
 554    }
 555
 556    private static readonly EndpointI[] _emptyEndpoints = [];
 557    private Ice.ConnectionI _fixedConnection;
 558}
 559
 560public class RoutableReference : Reference
 561{
 1562    internal override BatchRequestQueue batchRequestQueue => _batchRequestQueue;
 563
 1564    public override EndpointI[] getEndpoints() => _endpoints;
 565
 1566    public override string getAdapterId() => _adapterId;
 567
 1568    public override LocatorInfo getLocatorInfo() => _locatorInfo;
 569
 1570    public override RouterInfo getRouterInfo() => _routerInfo;
 571
 1572    public override bool getCollocationOptimized() => _collocationOptimized;
 573
 1574    public override bool getCacheConnection() => _cacheConnection;
 575
 1576    public override Ice.EndpointSelectionType getEndpointSelection() => _endpointSelection;
 577
 1578    public override TimeSpan getLocatorCacheTimeout() => _locatorCacheTimeout;
 579
 1580    public override string getConnectionId() => _connectionId;
 581
 582    public override Reference changeMode(Mode newMode)
 583    {
 1584        Reference r = base.changeMode(newMode);
 1585        ((RoutableReference)r).setBatchRequestQueue();
 1586        return r;
 587    }
 588
 1589    public override ThreadPool getThreadPool() => getInstance().clientThreadPool();
 590
 1591    public override Connection getConnection() => null;
 592
 593    public override Reference changeEncoding(Ice.EncodingVersion newEncoding)
 594    {
 1595        var r = (RoutableReference)base.changeEncoding(newEncoding);
 1596        if (r != this)
 597        {
 1598            LocatorInfo locInfo = r._locatorInfo;
 1599            if (locInfo != null && !locInfo.getLocator().ice_getEncodingVersion().Equals(newEncoding))
 600            {
 1601                r._locatorInfo = getInstance().locatorManager().get(
 1602                    (Ice.LocatorPrx)locInfo.getLocator().ice_encodingVersion(newEncoding));
 603            }
 604        }
 1605        return r;
 606    }
 607
 608    public override Reference changeCompress(bool newCompress)
 609    {
 1610        var r = (RoutableReference)base.changeCompress(newCompress);
 1611        if (r != this && _endpoints.Length > 0) // Also override the compress flag on the endpoints if it was updated
 612        {
 1613            var newEndpoints = new EndpointI[_endpoints.Length];
 1614            for (int i = 0; i < _endpoints.Length; i++)
 615            {
 1616                newEndpoints[i] = _endpoints[i].compress(newCompress);
 617            }
 1618            r._endpoints = newEndpoints;
 619        }
 1620        return r;
 621    }
 622
 623    public override Reference changeEndpoints(EndpointI[] newEndpoints)
 624    {
 1625        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1626        r._endpoints = newEndpoints;
 1627        r._adapterId = "";
 1628        r.applyOverrides(ref r._endpoints);
 1629        return r;
 630    }
 631
 632    public override Reference changeAdapterId(string newAdapterId)
 633    {
 1634        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1635        r._adapterId = newAdapterId;
 1636        r._endpoints = _emptyEndpoints;
 1637        return r;
 638    }
 639
 640    public override Reference changeLocator(Ice.LocatorPrx newLocator)
 641    {
 1642        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1643        r._locatorInfo = getInstance().locatorManager().get(newLocator);
 1644        return r;
 645    }
 646
 647    public override Reference changeRouter(Ice.RouterPrx newRouter)
 648    {
 1649        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1650        r._routerInfo = getInstance().routerManager().get(newRouter);
 1651        return r;
 652    }
 653
 654    public override Reference changeCollocationOptimized(bool newCollocationOptimized)
 655    {
 1656        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1657        r._collocationOptimized = newCollocationOptimized;
 1658        return r;
 659    }
 660
 661    public override Reference changeCacheConnection(bool newCache)
 662    {
 1663        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1664        r._cacheConnection = newCache;
 1665        return r;
 666    }
 667
 668    public override Reference changeEndpointSelection(Ice.EndpointSelectionType newType)
 669    {
 1670        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1671        r._endpointSelection = newType;
 1672        return r;
 673    }
 674
 675    public override Reference changeLocatorCacheTimeout(TimeSpan newTimeout)
 676    {
 1677        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1678        r._locatorCacheTimeout = newTimeout;
 1679        return r;
 680    }
 681
 682    public override Reference changeConnectionId(string connectionId)
 683    {
 1684        var r = (RoutableReference)getInstance().referenceFactory().copy(this);
 1685        r._connectionId = connectionId;
 1686        if (_endpoints.Length > 0)
 687        {
 1688            var newEndpoints = new EndpointI[_endpoints.Length];
 1689            for (int i = 0; i < _endpoints.Length; i++)
 690            {
 1691                newEndpoints[i] = _endpoints[i].connectionId(connectionId);
 692            }
 1693            r._endpoints = newEndpoints;
 694        }
 1695        return r;
 696    }
 697
 698    public override Reference changeConnection(Ice.ConnectionI connection)
 699    {
 1700        return new FixedReference(
 1701            getInstance(),
 1702            getCommunicator(),
 1703            getIdentity(),
 1704            getFacet(),
 1705            getMode(),
 1706            getCompress(),
 1707            getProtocol(),
 1708            getEncoding(),
 1709            connection,
 1710            getInvocationTimeout(),
 1711            getContext());
 712    }
 713
 1714    public override bool isIndirect() => _endpoints.Length == 0;
 715
 1716    public override bool isWellKnown() => _endpoints.Length == 0 && _adapterId.Length == 0;
 717
 718    public override void streamWrite(Ice.OutputStream s)
 719    {
 1720        base.streamWrite(s);
 721
 1722        s.writeSize(_endpoints.Length);
 1723        if (_endpoints.Length > 0)
 724        {
 725            Debug.Assert(_adapterId.Length == 0);
 1726            foreach (EndpointI endpoint in _endpoints)
 727            {
 1728                s.writeShort(endpoint.type());
 1729                endpoint.streamWrite(s);
 730            }
 731        }
 732        else
 733        {
 1734            s.writeString(_adapterId); // Adapter id.
 735        }
 1736    }
 737
 738    public override string ToString()
 739    {
 740        //
 741        // WARNING: Certain features, such as proxy validation in Glacier2,
 742        // depend on the format of proxy strings. Changes to toString() and
 743        // methods called to generate parts of the reference string could break
 744        // these features. Please review for all features that depend on the
 745        // format of proxyToString() before changing this and related code.
 746        //
 1747        var s = new StringBuilder();
 1748        s.Append(base.ToString());
 749
 1750        if (_endpoints.Length > 0)
 751        {
 1752            for (int i = 0; i < _endpoints.Length; i++)
 753            {
 1754                string endp = _endpoints[i].ToString();
 1755                if (endp != null && endp.Length > 0)
 756                {
 1757                    s.Append(':');
 1758                    s.Append(endp);
 759                }
 760            }
 761        }
 1762        else if (_adapterId.Length > 0)
 763        {
 1764            s.Append(" @ ");
 765
 766            //
 767            // If the encoded adapter id string contains characters which
 768            // the reference parser uses as separators, then we enclose
 769            // the adapter id string in quotes.
 770            //
 1771            string a = Ice.UtilInternal.StringUtil.escapeString(_adapterId, null, getInstance().toStringMode());
 1772            if (Ice.UtilInternal.StringUtil.findFirstOf(a, " :@") != -1)
 773            {
 0774                s.Append('"');
 0775                s.Append(a);
 0776                s.Append('"');
 777            }
 778            else
 779            {
 1780                s.Append(a);
 781            }
 782        }
 1783        return s.ToString();
 784    }
 785
 786    public override Dictionary<string, string> toProperty(string prefix)
 787    {
 1788        var properties = new Dictionary<string, string>
 1789        {
 1790            [prefix] = ToString(),
 1791            [prefix + ".CollocationOptimized"] = _collocationOptimized ? "1" : "0",
 1792            [prefix + ".ConnectionCached"] = _cacheConnection ? "1" : "0",
 1793            [prefix + ".EndpointSelection"] =
 1794                   _endpointSelection == Ice.EndpointSelectionType.Random ? "Random" : "Ordered",
 1795            [prefix + ".LocatorCacheTimeout"] =
 1796                _locatorCacheTimeout.TotalSeconds.ToString(CultureInfo.InvariantCulture),
 1797            [prefix + ".InvocationTimeout"] =
 1798                getInvocationTimeout().TotalMilliseconds.ToString(CultureInfo.InvariantCulture)
 1799        };
 800
 1801        if (_routerInfo != null)
 802        {
 1803            var h = (Ice.ObjectPrxHelperBase)_routerInfo.getRouter();
 1804            Dictionary<string, string> routerProperties = h.iceReference().toProperty(prefix + ".Router");
 1805            foreach (KeyValuePair<string, string> entry in routerProperties)
 806            {
 1807                properties[entry.Key] = entry.Value;
 808            }
 809        }
 810
 1811        if (_locatorInfo != null)
 812        {
 1813            var h = (Ice.ObjectPrxHelperBase)_locatorInfo.getLocator();
 1814            Dictionary<string, string> locatorProperties = h.iceReference().toProperty(prefix + ".Locator");
 1815            foreach (KeyValuePair<string, string> entry in locatorProperties)
 816            {
 1817                properties[entry.Key] = entry.Value;
 818            }
 819        }
 820
 1821        return properties;
 822    }
 823
 824    public override int GetHashCode()
 825    {
 1826        var hash = new HashCode();
 1827        hash.Add(base.GetHashCode());
 1828        hash.Add(_adapterId);
 1829        foreach (EndpointI endpoint in _endpoints)
 830        {
 1831            hash.Add(endpoint);
 832        }
 1833        return hash.ToHashCode();
 834    }
 835
 836    public override bool Equals(Reference other)
 837    {
 1838        if (ReferenceEquals(this, other))
 839        {
 1840            return true;
 841        }
 1842        var rhs = other as RoutableReference;
 843
 1844        return rhs is not null &&
 1845            base.Equals(rhs) &&
 1846            _locatorInfo == rhs._locatorInfo &&
 1847            _routerInfo == rhs._routerInfo &&
 1848            _collocationOptimized == rhs._collocationOptimized &&
 1849            _cacheConnection == rhs._cacheConnection &&
 1850            _endpointSelection == rhs._endpointSelection &&
 1851            _locatorCacheTimeout == rhs._locatorCacheTimeout &&
 1852            _connectionId == rhs._connectionId &&
 1853            _adapterId == rhs._adapterId &&
 1854            _endpoints.SequenceEqual(rhs._endpoints);
 855    }
 856
 857    public override Reference Clone()
 858    {
 1859        var clone = (RoutableReference)MemberwiseClone();
 860        // Each reference gets its own batch request queue.
 1861        clone.setBatchRequestQueue();
 1862        return clone;
 863    }
 864
 865    private sealed class RouterEndpointsCallback : RouterInfo.GetClientEndpointsCallback
 866    {
 1867        internal RouterEndpointsCallback(RoutableReference ir, GetConnectionCallback cb)
 868        {
 1869            _ir = ir;
 1870            _cb = cb;
 1871        }
 872
 873        public void setEndpoints(EndpointI[] endpoints)
 874        {
 1875            if (endpoints.Length > 0)
 876            {
 1877                _ir.applyOverrides(ref endpoints);
 1878                _ir.createConnection(endpoints, _cb);
 879            }
 880            else
 881            {
 0882                _ir.getConnectionNoRouterInfo(_cb);
 883            }
 0884        }
 885
 1886        public void setException(Ice.LocalException ex) => _cb.setException(ex);
 887
 888        private readonly RoutableReference _ir;
 889        private readonly GetConnectionCallback _cb;
 890    }
 891
 892    internal override RequestHandler getRequestHandler()
 893    {
 1894        if (_collocationOptimized)
 895        {
 1896            if (_instance.objectAdapterFactory().findObjectAdapter(this) is ObjectAdapter adapter)
 897            {
 1898                return new CollocatedRequestHandler(this, adapter);
 899            }
 900        }
 901
 1902        var handler = new ConnectRequestHandler(this);
 1903        getConnection(handler);
 1904        return handler;
 905    }
 906
 907    public void getConnection(GetConnectionCallback callback)
 908    {
 1909        if (_routerInfo != null)
 910        {
 911            //
 912            // If we route, we send everything to the router's client
 913            // proxy endpoints.
 914            //
 1915            _routerInfo.getClientEndpoints(new RouterEndpointsCallback(this, callback));
 916        }
 917        else
 918        {
 1919            getConnectionNoRouterInfo(callback);
 920        }
 1921    }
 922
 923    private sealed class LocatorEndpointsCallback : LocatorInfo.GetEndpointsCallback
 924    {
 1925        internal LocatorEndpointsCallback(RoutableReference ir, GetConnectionCallback cb)
 926        {
 1927            _ir = ir;
 1928            _cb = cb;
 1929        }
 930
 931        public void setEndpoints(EndpointI[] endpoints, bool cached)
 932        {
 1933            if (endpoints.Length == 0)
 934            {
 1935                _cb.setException(new NoEndpointException(new ObjectPrxHelper(_ir)));
 1936                return;
 937            }
 938
 1939            _ir.applyOverrides(ref endpoints);
 1940            _ir.createConnection(endpoints, new ConnectionCallback(_ir, _cb, cached));
 1941        }
 942
 1943        public void setException(Ice.LocalException ex) => _cb.setException(ex);
 944
 945        private readonly RoutableReference _ir;
 946        private readonly GetConnectionCallback _cb;
 947    }
 948
 949    private sealed class ConnectionCallback : GetConnectionCallback
 950    {
 1951        internal ConnectionCallback(RoutableReference ir, GetConnectionCallback cb, bool cached)
 952        {
 1953            _ir = ir;
 1954            _cb = cb;
 1955            _cached = cached;
 1956        }
 957
 958        public void setConnection(Ice.ConnectionI connection, bool compress) =>
 1959            _cb.setConnection(connection, compress);
 960
 961        public void setException(Ice.LocalException exc)
 962        {
 963            try
 964            {
 1965                throw exc;
 966            }
 0967            catch (NoEndpointException ex)
 968            {
 0969                _cb.setException(ex); // No need to retry if there's no endpoints.
 0970            }
 1971            catch (Ice.LocalException ex)
 972            {
 973                Debug.Assert(_ir._locatorInfo != null);
 1974                _ir._locatorInfo.clearCache(_ir);
 1975                if (_cached)
 976                {
 1977                    TraceLevels traceLevels = _ir.getInstance().traceLevels();
 1978                    if (traceLevels.retry >= 2)
 979                    {
 0980                        string s = "connection to cached endpoints failed\n" +
 0981                                   "removing endpoints from cache and trying again\n" + ex;
 0982                        _ir.getInstance().initializationData().logger.trace(traceLevels.retryCat, s);
 983                    }
 1984                    _ir.getConnectionNoRouterInfo(_cb); // Retry.
 1985                    return;
 986                }
 1987                _cb.setException(ex);
 1988            }
 1989        }
 990
 991        private readonly RoutableReference _ir;
 992        private readonly GetConnectionCallback _cb;
 993        private readonly bool _cached;
 994    }
 995
 996    private void getConnectionNoRouterInfo(GetConnectionCallback callback)
 997    {
 1998        if (_endpoints.Length > 0)
 999        {
 11000            createConnection(_endpoints, callback);
 11001            return;
 1002        }
 1003
 11004        if (_locatorInfo != null)
 1005        {
 11006            _locatorInfo.getEndpoints(this, _locatorCacheTimeout, new LocatorEndpointsCallback(this, callback));
 1007        }
 1008        else
 1009        {
 11010            callback.setException(new NoEndpointException(new ObjectPrxHelper(this)));
 1011        }
 11012    }
 1013
 1014    public RoutableReference(
 1015        Instance instance,
 1016        Ice.Communicator communicator,
 1017        Ice.Identity identity,
 1018        string facet,
 1019        Mode mode,
 1020        bool? compress,
 1021        Ice.ProtocolVersion protocol,
 1022        Ice.EncodingVersion encoding,
 1023        EndpointI[] endpoints,
 1024        string adapterId,
 1025        LocatorInfo locatorInfo,
 1026        RouterInfo routerInfo,
 1027        bool collocationOptimized,
 1028        bool cacheConnection,
 1029        Ice.EndpointSelectionType endpointSelection,
 1030        TimeSpan locatorCacheTimeout,
 1031        TimeSpan invocationTimeout,
 1032        Dictionary<string, string> context)
 11033    : base(
 11034        instance,
 11035        communicator,
 11036        identity,
 11037        facet,
 11038        mode,
 11039        compress,
 11040        protocol,
 11041        encoding,
 11042        invocationTimeout,
 11043        context)
 1044    {
 11045        _endpoints = endpoints;
 11046        _adapterId = adapterId;
 11047        _locatorInfo = locatorInfo;
 11048        _routerInfo = routerInfo;
 11049        _collocationOptimized = collocationOptimized;
 11050        _cacheConnection = cacheConnection;
 11051        _endpointSelection = endpointSelection;
 11052        _locatorCacheTimeout = locatorCacheTimeout;
 1053
 11054        _endpoints ??= _emptyEndpoints;
 1055
 11056        _adapterId ??= "";
 11057        setBatchRequestQueue();
 1058
 1059        Debug.Assert(_adapterId.Length == 0 || _endpoints.Length == 0);
 11060    }
 1061
 1062    protected void applyOverrides(ref EndpointI[] endpoints)
 1063    {
 11064        for (int i = 0; i < endpoints.Length; ++i)
 1065        {
 11066            endpoints[i] = endpoints[i].connectionId(_connectionId);
 11067            bool? compress = getCompress();
 11068            if (compress is not null)
 1069            {
 01070                endpoints[i] = endpoints[i].compress(compress.Value);
 1071            }
 1072        }
 11073    }
 1074
 1075    private EndpointI[] filterEndpoints(EndpointI[] allEndpoints)
 1076    {
 11077        var endpoints = new List<EndpointI>();
 1078
 1079        //
 1080        // Filter out unknown endpoints.
 1081        //
 11082        for (int i = 0; i < allEndpoints.Length; i++)
 1083        {
 11084            if (!(allEndpoints[i] is OpaqueEndpointI))
 1085            {
 11086                endpoints.Add(allEndpoints[i]);
 1087            }
 1088        }
 1089
 1090        //
 1091        // Filter out endpoints according to the mode of the reference.
 1092        //
 11093        switch (getMode())
 1094        {
 1095            case Mode.ModeTwoway:
 1096            case Mode.ModeOneway:
 1097            case Mode.ModeBatchOneway:
 1098            {
 1099                //
 1100                // Filter out datagram endpoints.
 1101                //
 11102                var tmp = new List<EndpointI>();
 11103                foreach (EndpointI endpoint in endpoints)
 1104                {
 11105                    if (!endpoint.datagram())
 1106                    {
 11107                        tmp.Add(endpoint);
 1108                    }
 1109                }
 11110                endpoints = tmp;
 11111                break;
 1112            }
 1113
 1114            case Mode.ModeDatagram:
 1115            case Mode.ModeBatchDatagram:
 1116            {
 1117                //
 1118                // Filter out non-datagram endpoints.
 1119                //
 11120                var tmp = new List<EndpointI>();
 11121                foreach (EndpointI endpoint in endpoints)
 1122                {
 11123                    if (endpoint.datagram())
 1124                    {
 11125                        tmp.Add(endpoint);
 1126                    }
 1127                }
 11128                endpoints = tmp;
 1129                break;
 1130            }
 1131        }
 1132
 1133        //
 1134        // Sort the endpoints according to the endpoint selection type.
 1135        //
 11136        switch (getEndpointSelection())
 1137        {
 1138            case Ice.EndpointSelectionType.Random:
 1139            {
 11140                lock (rand_)
 1141                {
 11142                    for (int i = 0; i < endpoints.Count - 1; ++i)
 1143                    {
 11144                        int r = rand_.Next(endpoints.Count - i) + i;
 1145                        Debug.Assert(r >= i && r < endpoints.Count);
 11146                        if (r != i)
 1147                        {
 11148                            EndpointI tmp = endpoints[i];
 11149                            endpoints[i] = endpoints[r];
 11150                            endpoints[r] = tmp;
 1151                        }
 1152                    }
 11153                }
 1154                break;
 1155            }
 1156            case Ice.EndpointSelectionType.Ordered:
 1157            {
 1158                // Nothing to do.
 1159                break;
 1160            }
 1161            default:
 1162            {
 1163                Debug.Assert(false);
 1164                break;
 1165            }
 1166        }
 1167
 11168        var arr = new EndpointI[endpoints.Count];
 11169        endpoints.CopyTo(arr);
 11170        return arr;
 1171    }
 1172
 1173    private sealed class CreateConnectionCallback : OutgoingConnectionFactory.CreateConnectionCallback
 1174    {
 11175        internal CreateConnectionCallback(RoutableReference rr, EndpointI[] endpoints, GetConnectionCallback cb)
 1176        {
 11177            _rr = rr;
 11178            _endpoints = endpoints;
 11179            _callback = cb;
 11180        }
 1181
 1182        public void setConnection(Ice.ConnectionI connection, bool compress)
 1183        {
 1184            //
 1185            // If we have a router, set the object adapter for this router
 1186            // (if any) to the new connection, so that callbacks from the
 1187            // router can be received over this new connection.
 1188            //
 11189            if (_rr._routerInfo != null && _rr._routerInfo.getAdapter() != null)
 1190            {
 11191                connection.setAdapter(_rr._routerInfo.getAdapter());
 1192            }
 11193            _callback.setConnection(connection, compress);
 11194        }
 1195
 1196        public void setException(Ice.LocalException ex)
 1197        {
 11198            _exception ??= ex;
 1199
 11200            if (_endpoints == null || ++_i == _endpoints.Length)
 1201            {
 11202                _callback.setException(_exception);
 11203                return;
 1204            }
 1205
 11206            bool more = _i != _endpoints.Length - 1;
 11207            var endpointList = new List<EndpointI> { _endpoints[_i] };
 11208            _rr.getInstance().outgoingConnectionFactory().create(endpointList, more, this);
 11209        }
 1210
 1211        private readonly RoutableReference _rr;
 1212        private readonly EndpointI[] _endpoints;
 1213        private readonly GetConnectionCallback _callback;
 1214        private int _i;
 1215        private Ice.LocalException _exception;
 1216    }
 1217
 1218    protected void createConnection(EndpointI[] allEndpoints, GetConnectionCallback callback)
 1219    {
 11220        EndpointI[] endpoints = filterEndpoints(allEndpoints);
 11221        if (endpoints.Length == 0)
 1222        {
 01223            callback.setException(new NoEndpointException(new ObjectPrxHelper(this)));
 01224            return;
 1225        }
 1226
 1227        //
 1228        // Finally, create the connection.
 1229        //
 11230        OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory();
 11231        if (getCacheConnection() || endpoints.Length == 1)
 1232        {
 1233            //
 1234            // Get an existing connection or create one if there's no
 1235            // existing connection to one of the given endpoints.
 1236            //
 11237            factory.create(endpoints.ToList(), false, new CreateConnectionCallback(this, null, callback));
 1238        }
 1239        else
 1240        {
 1241            //
 1242            // Go through the list of endpoints and try to create the
 1243            // connection until it succeeds. This is different from just
 1244            // calling create() with the given endpoints since this might
 1245            // create a new connection even if there's an existing
 1246            // connection for one of the endpoints.
 1247            //
 1248
 11249            factory.create(
 11250                new List<EndpointI> { endpoints[0] },
 11251                true,
 11252                new CreateConnectionCallback(this, endpoints, callback));
 1253        }
 11254    }
 1255
 1256    // Sets or resets _batchRequestQueue based on _mode.
 1257    private void setBatchRequestQueue()
 1258    {
 11259        _batchRequestQueue =
 11260            isBatch ? new BatchRequestQueue(getInstance(), getMode() == Mode.ModeBatchDatagram) : null;
 11261    }
 1262
 11263    private static readonly EndpointI[] _emptyEndpoints = [];
 1264
 1265    private BatchRequestQueue _batchRequestQueue;
 1266
 1267    private EndpointI[] _endpoints;
 1268    private string _adapterId;
 1269    private LocatorInfo _locatorInfo; // Null if no locator is used.
 1270    private RouterInfo _routerInfo; // Null if no router is used.
 1271    private bool _collocationOptimized;
 1272    private bool _cacheConnection;
 1273    private Ice.EndpointSelectionType _endpointSelection;
 1274    private TimeSpan _locatorCacheTimeout;
 1275
 11276    private string _connectionId = "";
 1277}

Methods/Properties

get_batchRequestQueue()
getEndpoints()
getAdapterId()
getLocatorInfo()
getRouterInfo()
getCollocationOptimized()
getCacheConnection()
getEndpointSelection()
getLocatorCacheTimeout()
getConnectionId()
changeMode(Ice.Internal.Reference.Mode)
getThreadPool()
getConnection()
changeEncoding(Ice.EncodingVersion)
changeCompress(bool)
changeEndpoints(Ice.Internal.EndpointI[])
changeAdapterId(string)
changeLocator(Ice.LocatorPrx)
changeRouter(Ice.RouterPrx)
changeCollocationOptimized(bool)
changeCacheConnection(bool)
changeEndpointSelection(Ice.EndpointSelectionType)
changeLocatorCacheTimeout(System.TimeSpan)
changeConnectionId(string)
changeConnection(Ice.ConnectionI)
isIndirect()
isWellKnown()
streamWrite(Ice.OutputStream)
ToString()
toProperty(string)
GetHashCode()
Equals(Ice.Internal.Reference)
Clone()
.ctor(Ice.Internal.RoutableReference, Ice.Internal.Reference.GetConnectionCallback)
setEndpoints(Ice.Internal.EndpointI[])
setException(Ice.LocalException)
getRequestHandler()
getConnection(Ice.Internal.Reference.GetConnectionCallback)
.ctor(Ice.Internal.RoutableReference, Ice.Internal.Reference.GetConnectionCallback)
setEndpoints(Ice.Internal.EndpointI[], bool)
setException(Ice.LocalException)
.ctor(Ice.Internal.RoutableReference, Ice.Internal.Reference.GetConnectionCallback, bool)
setConnection(Ice.ConnectionI, bool)
setException(Ice.LocalException)
getConnectionNoRouterInfo(Ice.Internal.Reference.GetConnectionCallback)
.ctor(Ice.Internal.Instance, Ice.Communicator, Ice.Identity, string, Ice.Internal.Reference.Mode, System.Nullable<bool>, Ice.ProtocolVersion, Ice.EncodingVersion, Ice.Internal.EndpointI[], string, Ice.Internal.LocatorInfo, Ice.Internal.RouterInfo, bool, bool, Ice.EndpointSelectionType, System.TimeSpan, System.TimeSpan, System.Collections.Generic.Dictionary<string, string>)
applyOverrides(ref Ice.Internal.EndpointI[])
filterEndpoints(Ice.Internal.EndpointI[])
.ctor(Ice.Internal.RoutableReference, Ice.Internal.EndpointI[], Ice.Internal.Reference.GetConnectionCallback)
setConnection(Ice.ConnectionI, bool)
setException(Ice.LocalException)
createConnection(Ice.Internal.EndpointI[], Ice.Internal.Reference.GetConnectionCallback)
setBatchRequestQueue()
.cctor()