< Summary

Information
Class: Ice.Internal.RoutableReference
Assembly: Ice
File(s): /_/csharp/src/Ice/Internal/Reference.cs
Tag: 125_37167941578
Line coverage
95%
Covered lines: 289
Uncovered lines: 14
Coverable lines: 303
Total lines: 1279
Line coverage: 95.3%
Branch coverage
93%
Covered branches: 133
Total branches: 142
Branch coverage: 93.6%
Method coverage
100%
Covered methods: 54
Fully covered methods: 48
Total methods: 54
Method coverage: 100%
Full method coverage: 88.8%

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%131282.35%
toProperty(...)100%1414100%
GetHashCode()100%22100%
Equals(...)100%2222100%
Clone()100%11100%
.ctor(...)100%11100%
setEndpoints(...)50%2260%
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%8664.71%
getConnectionNoRouterInfo(...)100%44100%
.ctor(...)100%44100%
applyOverrides(...)75%4483.33%
filterEndpoints(...)91.67%2424100%
.ctor(...)100%11100%
setConnection(...)100%44100%
setException(...)100%66100%
createConnection(...)83.33%6683.33%
setBatchRequestQueue()100%22100%
.cctor()100%11100%

File(s)

/_/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 != Protocol.Protocol_1_0)
 317        {
 318            // We print the protocol unless it's 1.0.
 319            s.Append(" -p ");
 320            s.Append(Protocol.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(Protocol.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            // The timeouts are always normalized: infinite is -1 and a positive timeout is a whole number of the
 1796            // property's unit.
 1797            [prefix + ".LocatorCacheTimeout"] =
 1798                ((long)_locatorCacheTimeout.TotalSeconds).ToString(CultureInfo.InvariantCulture),
 1799            [prefix + ".InvocationTimeout"] =
 1800                ((long)getInvocationTimeout().TotalMilliseconds).ToString(CultureInfo.InvariantCulture)
 1801        };
 802
 1803        if (_routerInfo != null)
 804        {
 1805            var h = (Ice.ObjectPrxHelperBase)_routerInfo.getRouter();
 1806            Dictionary<string, string> routerProperties = h.iceReference().toProperty(prefix + ".Router");
 1807            foreach (KeyValuePair<string, string> entry in routerProperties)
 808            {
 1809                properties[entry.Key] = entry.Value;
 810            }
 811        }
 812
 1813        if (_locatorInfo != null)
 814        {
 1815            var h = (Ice.ObjectPrxHelperBase)_locatorInfo.getLocator();
 1816            Dictionary<string, string> locatorProperties = h.iceReference().toProperty(prefix + ".Locator");
 1817            foreach (KeyValuePair<string, string> entry in locatorProperties)
 818            {
 1819                properties[entry.Key] = entry.Value;
 820            }
 821        }
 822
 1823        return properties;
 824    }
 825
 826    public override int GetHashCode()
 827    {
 1828        var hash = new HashCode();
 1829        hash.Add(base.GetHashCode());
 1830        hash.Add(_adapterId);
 1831        foreach (EndpointI endpoint in _endpoints)
 832        {
 1833            hash.Add(endpoint);
 834        }
 1835        return hash.ToHashCode();
 836    }
 837
 838    public override bool Equals(Reference other)
 839    {
 1840        if (ReferenceEquals(this, other))
 841        {
 1842            return true;
 843        }
 1844        var rhs = other as RoutableReference;
 845
 1846        return rhs is not null &&
 1847            base.Equals(rhs) &&
 1848            _locatorInfo == rhs._locatorInfo &&
 1849            _routerInfo == rhs._routerInfo &&
 1850            _collocationOptimized == rhs._collocationOptimized &&
 1851            _cacheConnection == rhs._cacheConnection &&
 1852            _endpointSelection == rhs._endpointSelection &&
 1853            _locatorCacheTimeout == rhs._locatorCacheTimeout &&
 1854            _connectionId == rhs._connectionId &&
 1855            _adapterId == rhs._adapterId &&
 1856            _endpoints.SequenceEqual(rhs._endpoints);
 857    }
 858
 859    public override Reference Clone()
 860    {
 1861        var clone = (RoutableReference)MemberwiseClone();
 862        // Each reference gets its own batch request queue.
 1863        clone.setBatchRequestQueue();
 1864        return clone;
 865    }
 866
 867    private sealed class RouterEndpointsCallback : RouterInfo.GetClientEndpointsCallback
 868    {
 1869        internal RouterEndpointsCallback(RoutableReference ir, GetConnectionCallback cb)
 870        {
 1871            _ir = ir;
 1872            _cb = cb;
 1873        }
 874
 875        public void setEndpoints(EndpointI[] endpoints)
 876        {
 1877            if (endpoints.Length > 0)
 878            {
 1879                _ir.applyOverrides(ref endpoints);
 1880                _ir.createConnection(endpoints, _cb);
 881            }
 882            else
 883            {
 0884                _ir.getConnectionNoRouterInfo(_cb);
 885            }
 0886        }
 887
 1888        public void setException(Ice.LocalException ex) => _cb.setException(ex);
 889
 890        private readonly RoutableReference _ir;
 891        private readonly GetConnectionCallback _cb;
 892    }
 893
 894    internal override RequestHandler getRequestHandler()
 895    {
 1896        if (_collocationOptimized)
 897        {
 1898            if (_instance.objectAdapterFactory().findObjectAdapter(this) is ObjectAdapter adapter)
 899            {
 1900                return new CollocatedRequestHandler(this, adapter);
 901            }
 902        }
 903
 1904        var handler = new ConnectRequestHandler(this);
 1905        getConnection(handler);
 1906        return handler;
 907    }
 908
 909    public void getConnection(GetConnectionCallback callback)
 910    {
 1911        if (_routerInfo != null)
 912        {
 913            //
 914            // If we route, we send everything to the router's client
 915            // proxy endpoints.
 916            //
 1917            _routerInfo.getClientEndpoints(new RouterEndpointsCallback(this, callback));
 918        }
 919        else
 920        {
 1921            getConnectionNoRouterInfo(callback);
 922        }
 1923    }
 924
 925    private sealed class LocatorEndpointsCallback : LocatorInfo.GetEndpointsCallback
 926    {
 1927        internal LocatorEndpointsCallback(RoutableReference ir, GetConnectionCallback cb)
 928        {
 1929            _ir = ir;
 1930            _cb = cb;
 1931        }
 932
 933        public void setEndpoints(EndpointI[] endpoints, bool cached)
 934        {
 1935            if (endpoints.Length == 0)
 936            {
 1937                _cb.setException(new NoEndpointException(new ObjectPrxHelper(_ir)));
 1938                return;
 939            }
 940
 1941            _ir.applyOverrides(ref endpoints);
 1942            _ir.createConnection(endpoints, new ConnectionCallback(_ir, _cb, cached));
 1943        }
 944
 1945        public void setException(Ice.LocalException ex) => _cb.setException(ex);
 946
 947        private readonly RoutableReference _ir;
 948        private readonly GetConnectionCallback _cb;
 949    }
 950
 951    private sealed class ConnectionCallback : GetConnectionCallback
 952    {
 1953        internal ConnectionCallback(RoutableReference ir, GetConnectionCallback cb, bool cached)
 954        {
 1955            _ir = ir;
 1956            _cb = cb;
 1957            _cached = cached;
 1958        }
 959
 960        public void setConnection(Ice.ConnectionI connection, bool compress) =>
 1961            _cb.setConnection(connection, compress);
 962
 963        public void setException(Ice.LocalException exc)
 964        {
 965            try
 966            {
 1967                throw exc;
 968            }
 0969            catch (NoEndpointException ex)
 970            {
 0971                _cb.setException(ex); // No need to retry if there's no endpoints.
 0972            }
 1973            catch (Ice.LocalException ex)
 974            {
 975                Debug.Assert(_ir._locatorInfo != null);
 1976                _ir._locatorInfo.clearCache(_ir);
 1977                if (_cached)
 978                {
 1979                    TraceLevels traceLevels = _ir.getInstance().traceLevels();
 1980                    if (traceLevels.retry >= 2)
 981                    {
 0982                        string s = "connection to cached endpoints failed\n" +
 0983                                   "removing endpoints from cache and trying again\n" + ex;
 0984                        _ir.getInstance().initializationData().logger.trace(traceLevels.retryCat, s);
 985                    }
 1986                    _ir.getConnectionNoRouterInfo(_cb); // Retry.
 1987                    return;
 988                }
 1989                _cb.setException(ex);
 1990            }
 1991        }
 992
 993        private readonly RoutableReference _ir;
 994        private readonly GetConnectionCallback _cb;
 995        private readonly bool _cached;
 996    }
 997
 998    private void getConnectionNoRouterInfo(GetConnectionCallback callback)
 999    {
 11000        if (_endpoints.Length > 0)
 1001        {
 11002            createConnection(_endpoints, callback);
 11003            return;
 1004        }
 1005
 11006        if (_locatorInfo != null)
 1007        {
 11008            _locatorInfo.getEndpoints(this, _locatorCacheTimeout, new LocatorEndpointsCallback(this, callback));
 1009        }
 1010        else
 1011        {
 11012            callback.setException(new NoEndpointException(new ObjectPrxHelper(this)));
 1013        }
 11014    }
 1015
 1016    public RoutableReference(
 1017        Instance instance,
 1018        Ice.Communicator communicator,
 1019        Ice.Identity identity,
 1020        string facet,
 1021        Mode mode,
 1022        bool? compress,
 1023        Ice.ProtocolVersion protocol,
 1024        Ice.EncodingVersion encoding,
 1025        EndpointI[] endpoints,
 1026        string adapterId,
 1027        LocatorInfo locatorInfo,
 1028        RouterInfo routerInfo,
 1029        bool collocationOptimized,
 1030        bool cacheConnection,
 1031        Ice.EndpointSelectionType endpointSelection,
 1032        TimeSpan locatorCacheTimeout,
 1033        TimeSpan invocationTimeout,
 1034        Dictionary<string, string> context)
 11035    : base(
 11036        instance,
 11037        communicator,
 11038        identity,
 11039        facet,
 11040        mode,
 11041        compress,
 11042        protocol,
 11043        encoding,
 11044        invocationTimeout,
 11045        context)
 1046    {
 11047        _endpoints = endpoints;
 11048        _adapterId = adapterId;
 11049        _locatorInfo = locatorInfo;
 11050        _routerInfo = routerInfo;
 11051        _collocationOptimized = collocationOptimized;
 11052        _cacheConnection = cacheConnection;
 11053        _endpointSelection = endpointSelection;
 11054        _locatorCacheTimeout = locatorCacheTimeout;
 1055
 11056        _endpoints ??= _emptyEndpoints;
 1057
 11058        _adapterId ??= "";
 11059        setBatchRequestQueue();
 1060
 1061        Debug.Assert(_adapterId.Length == 0 || _endpoints.Length == 0);
 11062    }
 1063
 1064    protected void applyOverrides(ref EndpointI[] endpoints)
 1065    {
 11066        for (int i = 0; i < endpoints.Length; ++i)
 1067        {
 11068            endpoints[i] = endpoints[i].connectionId(_connectionId);
 11069            bool? compress = getCompress();
 11070            if (compress is not null)
 1071            {
 01072                endpoints[i] = endpoints[i].compress(compress.Value);
 1073            }
 1074        }
 11075    }
 1076
 1077    private EndpointI[] filterEndpoints(EndpointI[] allEndpoints)
 1078    {
 11079        var endpoints = new List<EndpointI>();
 1080
 1081        //
 1082        // Filter out unknown endpoints.
 1083        //
 11084        for (int i = 0; i < allEndpoints.Length; i++)
 1085        {
 11086            if (!(allEndpoints[i] is OpaqueEndpointI))
 1087            {
 11088                endpoints.Add(allEndpoints[i]);
 1089            }
 1090        }
 1091
 1092        //
 1093        // Filter out endpoints according to the mode of the reference.
 1094        //
 11095        switch (getMode())
 1096        {
 1097            case Mode.ModeTwoway:
 1098            case Mode.ModeOneway:
 1099            case Mode.ModeBatchOneway:
 1100            {
 1101                //
 1102                // Filter out datagram endpoints.
 1103                //
 11104                var tmp = new List<EndpointI>();
 11105                foreach (EndpointI endpoint in endpoints)
 1106                {
 11107                    if (!endpoint.datagram())
 1108                    {
 11109                        tmp.Add(endpoint);
 1110                    }
 1111                }
 11112                endpoints = tmp;
 11113                break;
 1114            }
 1115
 1116            case Mode.ModeDatagram:
 1117            case Mode.ModeBatchDatagram:
 1118            {
 1119                //
 1120                // Filter out non-datagram endpoints.
 1121                //
 11122                var tmp = new List<EndpointI>();
 11123                foreach (EndpointI endpoint in endpoints)
 1124                {
 11125                    if (endpoint.datagram())
 1126                    {
 11127                        tmp.Add(endpoint);
 1128                    }
 1129                }
 11130                endpoints = tmp;
 1131                break;
 1132            }
 1133        }
 1134
 1135        //
 1136        // Sort the endpoints according to the endpoint selection type.
 1137        //
 11138        switch (getEndpointSelection())
 1139        {
 1140            case Ice.EndpointSelectionType.Random:
 1141            {
 11142                lock (rand_)
 1143                {
 11144                    for (int i = 0; i < endpoints.Count - 1; ++i)
 1145                    {
 11146                        int r = rand_.Next(endpoints.Count - i) + i;
 1147                        Debug.Assert(r >= i && r < endpoints.Count);
 11148                        if (r != i)
 1149                        {
 11150                            EndpointI tmp = endpoints[i];
 11151                            endpoints[i] = endpoints[r];
 11152                            endpoints[r] = tmp;
 1153                        }
 1154                    }
 11155                }
 1156                break;
 1157            }
 1158            case Ice.EndpointSelectionType.Ordered:
 1159            {
 1160                // Nothing to do.
 1161                break;
 1162            }
 1163            default:
 1164            {
 1165                Debug.Assert(false);
 1166                break;
 1167            }
 1168        }
 1169
 11170        var arr = new EndpointI[endpoints.Count];
 11171        endpoints.CopyTo(arr);
 11172        return arr;
 1173    }
 1174
 1175    private sealed class CreateConnectionCallback : OutgoingConnectionFactory.CreateConnectionCallback
 1176    {
 11177        internal CreateConnectionCallback(RoutableReference rr, EndpointI[] endpoints, GetConnectionCallback cb)
 1178        {
 11179            _rr = rr;
 11180            _endpoints = endpoints;
 11181            _callback = cb;
 11182        }
 1183
 1184        public void setConnection(Ice.ConnectionI connection, bool compress)
 1185        {
 1186            //
 1187            // If we have a router, set the object adapter for this router
 1188            // (if any) to the new connection, so that callbacks from the
 1189            // router can be received over this new connection.
 1190            //
 11191            if (_rr._routerInfo != null && _rr._routerInfo.getAdapter() != null)
 1192            {
 11193                connection.setAdapter(_rr._routerInfo.getAdapter());
 1194            }
 11195            _callback.setConnection(connection, compress);
 11196        }
 1197
 1198        public void setException(Ice.LocalException ex)
 1199        {
 11200            _exception ??= ex;
 1201
 11202            if (_endpoints == null || ++_i == _endpoints.Length)
 1203            {
 11204                _callback.setException(_exception);
 11205                return;
 1206            }
 1207
 11208            bool more = _i != _endpoints.Length - 1;
 11209            var endpointList = new List<EndpointI> { _endpoints[_i] };
 11210            _rr.getInstance().outgoingConnectionFactory().create(endpointList, more, this);
 11211        }
 1212
 1213        private readonly RoutableReference _rr;
 1214        private readonly EndpointI[] _endpoints;
 1215        private readonly GetConnectionCallback _callback;
 1216        private int _i;
 1217        private Ice.LocalException _exception;
 1218    }
 1219
 1220    protected void createConnection(EndpointI[] allEndpoints, GetConnectionCallback callback)
 1221    {
 11222        EndpointI[] endpoints = filterEndpoints(allEndpoints);
 11223        if (endpoints.Length == 0)
 1224        {
 01225            callback.setException(new NoEndpointException(new ObjectPrxHelper(this)));
 01226            return;
 1227        }
 1228
 1229        //
 1230        // Finally, create the connection.
 1231        //
 11232        OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory();
 11233        if (getCacheConnection() || endpoints.Length == 1)
 1234        {
 1235            //
 1236            // Get an existing connection or create one if there's no
 1237            // existing connection to one of the given endpoints.
 1238            //
 11239            factory.create(endpoints.ToList(), false, new CreateConnectionCallback(this, null, callback));
 1240        }
 1241        else
 1242        {
 1243            //
 1244            // Go through the list of endpoints and try to create the
 1245            // connection until it succeeds. This is different from just
 1246            // calling create() with the given endpoints since this might
 1247            // create a new connection even if there's an existing
 1248            // connection for one of the endpoints.
 1249            //
 1250
 11251            factory.create(
 11252                new List<EndpointI> { endpoints[0] },
 11253                true,
 11254                new CreateConnectionCallback(this, endpoints, callback));
 1255        }
 11256    }
 1257
 1258    // Sets or resets _batchRequestQueue based on _mode.
 1259    private void setBatchRequestQueue()
 1260    {
 11261        _batchRequestQueue =
 11262            isBatch ? new BatchRequestQueue(getInstance(), getMode() == Mode.ModeBatchDatagram) : null;
 11263    }
 1264
 11265    private static readonly EndpointI[] _emptyEndpoints = [];
 1266
 1267    private BatchRequestQueue _batchRequestQueue;
 1268
 1269    private EndpointI[] _endpoints;
 1270    private string _adapterId;
 1271    private LocatorInfo _locatorInfo; // Null if no locator is used.
 1272    private RouterInfo _routerInfo; // Null if no router is used.
 1273    private bool _collocationOptimized;
 1274    private bool _cacheConnection;
 1275    private Ice.EndpointSelectionType _endpointSelection;
 1276    private TimeSpan _locatorCacheTimeout;
 1277
 11278    private string _connectionId = "";
 1279}

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()