1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 using System; 6 using System.Collections.Generic; 7 using System.Diagnostics; 8 using System.Text; 9 using System.Globalization; 10 11 namespace IceInternal 12 { 13 public abstract class Reference : ICloneable 14 { 15 public enum Mode { 16 ModeTwoway, 17 ModeOneway, 18 ModeBatchOneway, 19 ModeDatagram, 20 ModeBatchDatagram, 21 ModeLast=ModeBatchDatagram 22 }; 23 24 public interface GetConnectionCallback 25 { setConnection(Ice.ConnectionI connection, bool compress)26 void setConnection(Ice.ConnectionI connection, bool compress); setException(Ice.LocalException ex)27 void setException(Ice.LocalException ex); 28 } 29 getMode()30 public Mode getMode() 31 { 32 return _mode; 33 } 34 getSecure()35 public bool getSecure() 36 { 37 return secure_; 38 } 39 getProtocol()40 public Ice.ProtocolVersion getProtocol() 41 { 42 return _protocol; 43 } 44 getEncoding()45 public Ice.EncodingVersion getEncoding() 46 { 47 return _encoding; 48 } 49 getIdentity()50 public Ice.Identity getIdentity() 51 { 52 return _identity; 53 } 54 getFacet()55 public string getFacet() 56 { 57 return _facet; 58 } 59 getInstance()60 public Instance getInstance() 61 { 62 return _instance; 63 } 64 getContext()65 public Dictionary<string, string> getContext() 66 { 67 return _context; 68 } 69 70 public int getInvocationTimeout()71 getInvocationTimeout() 72 { 73 return _invocationTimeout; 74 } 75 76 public Ice.Optional<bool> getCompress()77 getCompress() 78 { 79 return overrideCompress_ ? compress_ : new Ice.Optional<bool>(); 80 } 81 getCommunicator()82 public Ice.Communicator getCommunicator() 83 { 84 return _communicator; 85 } 86 getEndpoints()87 public abstract EndpointI[] getEndpoints(); getAdapterId()88 public abstract string getAdapterId(); getLocatorInfo()89 public abstract LocatorInfo getLocatorInfo(); getRouterInfo()90 public abstract RouterInfo getRouterInfo(); getCollocationOptimized()91 public abstract bool getCollocationOptimized(); getCacheConnection()92 public abstract bool getCacheConnection(); getPreferSecure()93 public abstract bool getPreferSecure(); getEndpointSelection()94 public abstract Ice.EndpointSelectionType getEndpointSelection(); getLocatorCacheTimeout()95 public abstract int getLocatorCacheTimeout(); getConnectionId()96 public abstract string getConnectionId(); getTimeout()97 public abstract Ice.Optional<int> getTimeout(); getThreadPool()98 public abstract ThreadPool getThreadPool(); 99 100 // 101 // The change* methods (here and in derived classes) create 102 // a new reference based on the existing one, with the 103 // corresponding value changed. 104 // changeContext(Dictionary<string, string> newContext)105 public Reference changeContext(Dictionary<string, string> newContext) 106 { 107 if(newContext == null) 108 { 109 newContext = _emptyContext; 110 } 111 Reference r = _instance.referenceFactory().copy(this); 112 if(newContext.Count == 0) 113 { 114 r._context = _emptyContext; 115 } 116 else 117 { 118 r._context = new Dictionary<string, string>(newContext); 119 } 120 return r; 121 } 122 changeMode(Mode newMode)123 public Reference changeMode(Mode newMode) 124 { 125 if(newMode == _mode) 126 { 127 return this; 128 } 129 Reference r = _instance.referenceFactory().copy(this); 130 r._mode = newMode; 131 return r; 132 } 133 changeSecure(bool newSecure)134 public Reference changeSecure(bool newSecure) 135 { 136 if(newSecure == secure_) 137 { 138 return this; 139 } 140 Reference r = _instance.referenceFactory().copy(this); 141 r.secure_ = newSecure; 142 return r; 143 } 144 changeIdentity(Ice.Identity newIdentity)145 public Reference changeIdentity(Ice.Identity newIdentity) 146 { 147 if(newIdentity.Equals(_identity)) 148 { 149 return this; 150 } 151 Reference r = _instance.referenceFactory().copy(this); 152 r._identity = newIdentity; // Identity is a value type, therefore a copy of newIdentity is made. 153 return r; 154 } 155 changeFacet(string newFacet)156 public Reference changeFacet(string newFacet) 157 { 158 if(newFacet.Equals(_facet)) 159 { 160 return this; 161 } 162 Reference r = _instance.referenceFactory().copy(this); 163 r._facet = newFacet; 164 return r; 165 } 166 changeInvocationTimeout(int newTimeout)167 public Reference changeInvocationTimeout(int newTimeout) 168 { 169 if(newTimeout == _invocationTimeout) 170 { 171 return this; 172 } 173 Reference r = _instance.referenceFactory().copy(this); 174 r._invocationTimeout = newTimeout; 175 return r; 176 } 177 changeEncoding(Ice.EncodingVersion newEncoding)178 public virtual Reference changeEncoding(Ice.EncodingVersion newEncoding) 179 { 180 if(newEncoding.Equals(_encoding)) 181 { 182 return this; 183 } 184 Reference r = _instance.referenceFactory().copy(this); 185 r._encoding = newEncoding; 186 return r; 187 } 188 changeCompress(bool newCompress)189 public virtual Reference changeCompress(bool newCompress) 190 { 191 if(overrideCompress_ && compress_ == newCompress) 192 { 193 return this; 194 } 195 196 Reference r = _instance.referenceFactory().copy(this); 197 r.compress_ = newCompress; 198 r.overrideCompress_ = true; 199 return r; 200 } 201 changeEndpoints(EndpointI[] newEndpoints)202 public abstract Reference changeEndpoints(EndpointI[] newEndpoints); changeAdapterId(string newAdapterId)203 public abstract Reference changeAdapterId(string newAdapterId); changeLocator(Ice.LocatorPrx newLocator)204 public abstract Reference changeLocator(Ice.LocatorPrx newLocator); changeRouter(Ice.RouterPrx newRouter)205 public abstract Reference changeRouter(Ice.RouterPrx newRouter); changeCollocationOptimized(bool newCollocationOptimized)206 public abstract Reference changeCollocationOptimized(bool newCollocationOptimized); changeCacheConnection(bool newCache)207 public abstract Reference changeCacheConnection(bool newCache); changePreferSecure(bool newPreferSecure)208 public abstract Reference changePreferSecure(bool newPreferSecure); changeEndpointSelection(Ice.EndpointSelectionType newType)209 public abstract Reference changeEndpointSelection(Ice.EndpointSelectionType newType); changeLocatorCacheTimeout(int newTimeout)210 public abstract Reference changeLocatorCacheTimeout(int newTimeout); 211 changeTimeout(int newTimeout)212 public abstract Reference changeTimeout(int newTimeout); changeConnectionId(string connectionId)213 public abstract Reference changeConnectionId(string connectionId); changeConnection(Ice.ConnectionI connection)214 public abstract Reference changeConnection(Ice.ConnectionI connection); 215 GetHashCode()216 public override int GetHashCode() 217 { 218 lock(this) 219 { 220 if(hashInitialized_) 221 { 222 return hashValue_; 223 } 224 int h = 5381; 225 HashUtil.hashAdd(ref h, _mode); 226 HashUtil.hashAdd(ref h, secure_); 227 HashUtil.hashAdd(ref h, _identity); 228 HashUtil.hashAdd(ref h, _context); 229 HashUtil.hashAdd(ref h, _facet); 230 HashUtil.hashAdd(ref h, overrideCompress_); 231 if(overrideCompress_) 232 { 233 HashUtil.hashAdd(ref h, compress_); 234 } 235 HashUtil.hashAdd(ref h, _protocol); 236 HashUtil.hashAdd(ref h, _encoding); 237 HashUtil.hashAdd(ref h, _invocationTimeout); 238 hashValue_ = h; 239 hashInitialized_ = true; 240 return hashValue_; 241 } 242 } 243 getCompressOverride(out bool compress)244 public bool getCompressOverride(out bool compress) 245 { 246 DefaultsAndOverrides defaultsAndOverrides = getInstance().defaultsAndOverrides(); 247 if(defaultsAndOverrides.overrideCompress) 248 { 249 compress = defaultsAndOverrides.overrideCompressValue; 250 } 251 else if(overrideCompress_) 252 { 253 compress = compress_; 254 } 255 else 256 { 257 compress = false; 258 return false; 259 } 260 return true; 261 } 262 isIndirect()263 public abstract bool isIndirect(); isWellKnown()264 public abstract bool isWellKnown(); 265 266 // 267 // Marshal the reference. 268 // streamWrite(Ice.OutputStream s)269 public virtual void streamWrite(Ice.OutputStream s) 270 { 271 // 272 // Don't write the identity here. Operations calling streamWrite 273 // write the identity. 274 // 275 276 // 277 // For compatibility with the old FacetPath. 278 // 279 if(_facet.Length == 0) 280 { 281 s.writeStringSeq(null); 282 } 283 else 284 { 285 string[] facetPath = { _facet }; 286 s.writeStringSeq(facetPath); 287 } 288 289 s.writeByte((byte)_mode); 290 291 s.writeBool(secure_); 292 293 if(!s.getEncoding().Equals(Ice.Util.Encoding_1_0)) 294 { 295 _protocol.ice_writeMembers(s); 296 _encoding.ice_writeMembers(s); 297 } 298 299 // Derived class writes the remainder of the reference. 300 } 301 302 // 303 // Convert the reference to its string form. 304 // ToString()305 public override string ToString() 306 { 307 // 308 // WARNING: Certain features, such as proxy validation in Glacier2, 309 // depend on the format of proxy strings. Changes to toString() and 310 // methods called to generate parts of the reference string could break 311 // these features. Please review for all features that depend on the 312 // format of proxyToString() before changing this and related code. 313 // 314 StringBuilder s = new StringBuilder(); 315 316 Ice.ToStringMode toStringMode = _instance.toStringMode(); 317 318 // 319 // If the encoded identity string contains characters which 320 // the reference parser uses as separators, then we enclose 321 // the identity string in quotes. 322 // 323 string id = Ice.Util.identityToString(_identity, toStringMode); 324 if(IceUtilInternal.StringUtil.findFirstOf(id, " :@") != -1) 325 { 326 s.Append('"'); 327 s.Append(id); 328 s.Append('"'); 329 } 330 else 331 { 332 s.Append(id); 333 } 334 335 if(_facet.Length > 0) 336 { 337 // 338 // If the encoded facet string contains characters which 339 // the reference parser uses as separators, then we enclose 340 // the facet string in quotes. 341 // 342 s.Append(" -f "); 343 string fs = IceUtilInternal.StringUtil.escapeString(_facet, "", toStringMode); 344 if(IceUtilInternal.StringUtil.findFirstOf(fs, " :@") != -1) 345 { 346 s.Append('"'); 347 s.Append(fs); 348 s.Append('"'); 349 } 350 else 351 { 352 s.Append(fs); 353 } 354 } 355 356 switch(_mode) 357 { 358 case Mode.ModeTwoway: 359 { 360 s.Append(" -t"); 361 break; 362 } 363 364 case Mode.ModeOneway: 365 { 366 s.Append(" -o"); 367 break; 368 } 369 370 case Mode.ModeBatchOneway: 371 { 372 s.Append(" -O"); 373 break; 374 } 375 376 case Mode.ModeDatagram: 377 { 378 s.Append(" -d"); 379 break; 380 } 381 382 case Mode.ModeBatchDatagram: 383 { 384 s.Append(" -D"); 385 break; 386 } 387 } 388 389 if(secure_) 390 { 391 s.Append(" -s"); 392 } 393 394 if(!_protocol.Equals(Ice.Util.Protocol_1_0)) 395 { 396 // 397 // We only print the protocol if it's not 1.0. It's fine as 398 // long as we don't add Ice.Default.ProtocolVersion, a 399 // stringified proxy will convert back to the same proxy with 400 // stringToProxy. 401 // 402 s.Append(" -p "); 403 s.Append(Ice.Util.protocolVersionToString(_protocol)); 404 } 405 406 // 407 // Always print the encoding version to ensure a stringified proxy 408 // will convert back to a proxy with the same encoding with 409 // stringToProxy (and won't use Ice.Default.EncodingVersion). 410 // 411 s.Append(" -e "); 412 s.Append(Ice.Util.encodingVersionToString(_encoding)); 413 414 return s.ToString(); 415 416 // Derived class writes the remainder of the string. 417 } 418 toProperty(string prefix)419 public abstract Dictionary<string, string> toProperty(string prefix); 420 getRequestHandler(Ice.ObjectPrxHelperBase proxy)421 public abstract RequestHandler getRequestHandler(Ice.ObjectPrxHelperBase proxy); 422 getBatchRequestQueue()423 public abstract BatchRequestQueue getBatchRequestQueue(); 424 Equals(object obj)425 public override bool Equals(object obj) 426 { 427 // 428 // Note: if(this == obj) and type test are performed by each non-abstract derived class. 429 // 430 431 Reference r = (Reference)obj; // Guaranteed to succeed. 432 433 if(_mode != r._mode) 434 { 435 return false; 436 } 437 438 if(secure_ != r.secure_) 439 { 440 return false; 441 } 442 443 if(!_identity.Equals(r._identity)) 444 { 445 return false; 446 } 447 448 if(!Ice.CollectionComparer.Equals(_context, r._context)) 449 { 450 return false; 451 } 452 453 if(!_facet.Equals(r._facet)) 454 { 455 return false; 456 } 457 458 if(overrideCompress_ != r.overrideCompress_) 459 { 460 return false; 461 } 462 if(overrideCompress_ && compress_ != r.compress_) 463 { 464 return false; 465 } 466 467 if(!_protocol.Equals(r._protocol)) 468 { 469 return false; 470 } 471 472 if(!_encoding.Equals(r._encoding)) 473 { 474 return false; 475 } 476 477 if(_invocationTimeout != r._invocationTimeout) 478 { 479 return false; 480 } 481 482 return true; 483 } 484 Clone()485 public object Clone() 486 { 487 // 488 // A member-wise copy is safe because the members are immutable. 489 // 490 return MemberwiseClone(); 491 } 492 493 protected int hashValue_; 494 protected bool hashInitialized_; 495 private static Dictionary<string, string> _emptyContext = new Dictionary<string, string>(); 496 497 private Instance _instance; 498 private Ice.Communicator _communicator; 499 500 private Mode _mode; 501 private Ice.Identity _identity; 502 private Dictionary<string, string> _context; 503 private string _facet; 504 protected bool secure_; 505 private Ice.ProtocolVersion _protocol; 506 private Ice.EncodingVersion _encoding; 507 private int _invocationTimeout; 508 509 protected bool overrideCompress_; 510 protected bool compress_; // Only used if _overrideCompress == true 511 Reference(Instance instance, Ice.Communicator communicator, Ice.Identity identity, string facet, Mode mode, bool secure, Ice.ProtocolVersion protocol, Ice.EncodingVersion encoding, int invocationTimeout, Dictionary<string, string> context)512 protected Reference(Instance instance, 513 Ice.Communicator communicator, 514 Ice.Identity identity, 515 string facet, 516 Mode mode, 517 bool secure, 518 Ice.ProtocolVersion protocol, 519 Ice.EncodingVersion encoding, 520 int invocationTimeout, 521 Dictionary<string, string> context) 522 { 523 // 524 // Validate string arguments. 525 // 526 Debug.Assert(identity.name != null); 527 Debug.Assert(identity.category != null); 528 Debug.Assert(facet != null); 529 530 _instance = instance; 531 _communicator = communicator; 532 _mode = mode; 533 _identity = identity; 534 _context = context != null ? new Dictionary<string, string>(context) : _emptyContext; 535 _facet = facet; 536 _protocol = protocol; 537 _encoding = encoding; 538 _invocationTimeout = invocationTimeout; 539 secure_ = secure; 540 hashInitialized_ = false; 541 overrideCompress_ = false; 542 compress_ = false; 543 } 544 545 protected static Random rand_ = new Random(unchecked((int)DateTime.Now.Ticks)); 546 } 547 548 public class FixedReference : Reference 549 { FixedReference(Instance instance, Ice.Communicator communicator, Ice.Identity identity, string facet, Mode mode, bool secure, Ice.ProtocolVersion protocol, Ice.EncodingVersion encoding, Ice.ConnectionI connection, int invocationTimeout, Dictionary<string, string> context, Ice.Optional<bool> compress)550 public FixedReference(Instance instance, 551 Ice.Communicator communicator, 552 Ice.Identity identity, 553 string facet, 554 Mode mode, 555 bool secure, 556 Ice.ProtocolVersion protocol, 557 Ice.EncodingVersion encoding, 558 Ice.ConnectionI connection, 559 int invocationTimeout, 560 Dictionary<string, string> context, 561 Ice.Optional<bool> compress) 562 : base(instance, communicator, identity, facet, mode, secure, protocol, encoding, invocationTimeout, context) 563 { 564 _fixedConnection = connection; 565 if(compress.HasValue) 566 { 567 overrideCompress_ = true; 568 compress_ = compress.Value; 569 } 570 } 571 getEndpoints()572 public override EndpointI[] getEndpoints() 573 { 574 return _emptyEndpoints; 575 } 576 getAdapterId()577 public override string getAdapterId() 578 { 579 return ""; 580 } 581 getLocatorInfo()582 public override LocatorInfo getLocatorInfo() 583 { 584 return null; 585 } 586 getRouterInfo()587 public override RouterInfo getRouterInfo() 588 { 589 return null; 590 } 591 getCollocationOptimized()592 public override bool getCollocationOptimized() 593 { 594 return false; 595 } 596 getCacheConnection()597 public override bool getCacheConnection() 598 { 599 return true; 600 } 601 getPreferSecure()602 public override bool getPreferSecure() 603 { 604 return false; 605 } 606 getEndpointSelection()607 public override Ice.EndpointSelectionType getEndpointSelection() 608 { 609 return Ice.EndpointSelectionType.Random; 610 } 611 getLocatorCacheTimeout()612 public override int getLocatorCacheTimeout() 613 { 614 return 0; 615 } 616 getConnectionId()617 public override string getConnectionId() 618 { 619 return ""; 620 } 621 getTimeout()622 public override Ice.Optional<int> getTimeout() 623 { 624 return new Ice.Optional<int>(); 625 } 626 getThreadPool()627 public override ThreadPool getThreadPool() 628 { 629 return _fixedConnection.getThreadPool(); 630 } 631 changeEndpoints(EndpointI[] newEndpoints)632 public override Reference changeEndpoints(EndpointI[] newEndpoints) 633 { 634 throw new Ice.FixedProxyException(); 635 } 636 changeAdapterId(string newAdapterId)637 public override Reference changeAdapterId(string newAdapterId) 638 { 639 throw new Ice.FixedProxyException(); 640 } 641 changeLocator(Ice.LocatorPrx newLocator)642 public override Reference changeLocator(Ice.LocatorPrx newLocator) 643 { 644 throw new Ice.FixedProxyException(); 645 } 646 changeRouter(Ice.RouterPrx newRouter)647 public override Reference changeRouter(Ice.RouterPrx newRouter) 648 { 649 throw new Ice.FixedProxyException(); 650 } 651 changeCollocationOptimized(bool newCollocationOptimized)652 public override Reference changeCollocationOptimized(bool newCollocationOptimized) 653 { 654 throw new Ice.FixedProxyException(); 655 } 656 changeCacheConnection(bool newCache)657 public override Reference changeCacheConnection(bool newCache) 658 { 659 throw new Ice.FixedProxyException(); 660 } 661 changePreferSecure(bool prefSec)662 public override Reference changePreferSecure(bool prefSec) 663 { 664 throw new Ice.FixedProxyException(); 665 } 666 changeEndpointSelection(Ice.EndpointSelectionType newType)667 public override Reference changeEndpointSelection(Ice.EndpointSelectionType newType) 668 { 669 throw new Ice.FixedProxyException(); 670 } 671 changeLocatorCacheTimeout(int newTimeout)672 public override Reference changeLocatorCacheTimeout(int newTimeout) 673 { 674 throw new Ice.FixedProxyException(); 675 } 676 changeTimeout(int newTimeout)677 public override Reference changeTimeout(int newTimeout) 678 { 679 throw new Ice.FixedProxyException(); 680 } 681 changeConnectionId(string connectionId)682 public override Reference changeConnectionId(string connectionId) 683 { 684 throw new Ice.FixedProxyException(); 685 } 686 changeConnection(Ice.ConnectionI connection)687 public override Reference changeConnection(Ice.ConnectionI connection) 688 { 689 if(_fixedConnection == connection) 690 { 691 return this; 692 } 693 FixedReference r = (FixedReference)getInstance().referenceFactory().copy(this); 694 r._fixedConnection = connection; 695 return r; 696 } 697 isIndirect()698 public override bool isIndirect() 699 { 700 return false; 701 } 702 isWellKnown()703 public override bool isWellKnown() 704 { 705 return false; 706 } 707 streamWrite(Ice.OutputStream s)708 public override void streamWrite(Ice.OutputStream s) 709 { 710 throw new Ice.FixedProxyException(); 711 } 712 toProperty(string prefix)713 public override Dictionary<string, string> toProperty(string prefix) 714 { 715 throw new Ice.FixedProxyException(); 716 } 717 getRequestHandler(Ice.ObjectPrxHelperBase proxy)718 public override RequestHandler getRequestHandler(Ice.ObjectPrxHelperBase proxy) 719 { 720 switch(getMode()) 721 { 722 case Mode.ModeTwoway: 723 case Mode.ModeOneway: 724 case Mode.ModeBatchOneway: 725 { 726 if(_fixedConnection.endpoint().datagram()) 727 { 728 throw new Ice.NoEndpointException(ToString()); 729 } 730 break; 731 } 732 733 case Mode.ModeDatagram: 734 case Mode.ModeBatchDatagram: 735 { 736 if(!_fixedConnection.endpoint().datagram()) 737 { 738 throw new Ice.NoEndpointException(ToString()); 739 } 740 break; 741 } 742 } 743 744 // 745 // If a secure connection is requested or secure overrides is set, 746 // check if the connection is secure. 747 // 748 bool secure; 749 DefaultsAndOverrides defaultsAndOverrides = getInstance().defaultsAndOverrides(); 750 if(defaultsAndOverrides.overrideSecure) 751 { 752 secure = defaultsAndOverrides.overrideSecureValue; 753 } 754 else 755 { 756 secure = getSecure(); 757 } 758 if(secure && !_fixedConnection.endpoint().secure()) 759 { 760 throw new Ice.NoEndpointException(ToString()); 761 } 762 763 _fixedConnection.throwException(); // Throw in case our connection is already destroyed. 764 765 bool compress = false; 766 if(defaultsAndOverrides.overrideCompress) 767 { 768 compress = defaultsAndOverrides.overrideCompressValue; 769 } 770 else if(overrideCompress_) 771 { 772 compress = compress_; 773 } 774 775 return proxy.iceSetRequestHandler(new ConnectionRequestHandler(this, _fixedConnection, compress)); 776 } 777 getBatchRequestQueue()778 public override BatchRequestQueue getBatchRequestQueue() 779 { 780 return _fixedConnection.getBatchRequestQueue(); 781 } 782 Equals(object obj)783 public override bool Equals(object obj) 784 { 785 if(ReferenceEquals(this, obj)) 786 { 787 return true; 788 } 789 FixedReference rhs = obj as FixedReference; 790 if(rhs == null) 791 { 792 return false; 793 } 794 if(!base.Equals(rhs)) 795 { 796 return false; 797 } 798 return _fixedConnection.Equals(rhs._fixedConnection); 799 } 800 801 // 802 // If we override Equals, we must also override GetHashCode. 803 // GetHashCode()804 public override int GetHashCode() 805 { 806 return base.GetHashCode(); 807 } 808 809 private Ice.ConnectionI _fixedConnection; 810 private static EndpointI[] _emptyEndpoints = new EndpointI[0]; 811 } 812 813 public class RoutableReference : Reference 814 { getEndpoints()815 public override EndpointI[] getEndpoints() 816 { 817 return _endpoints; 818 } 819 getAdapterId()820 public override string getAdapterId() 821 { 822 return _adapterId; 823 } 824 getLocatorInfo()825 public override LocatorInfo getLocatorInfo() 826 { 827 return _locatorInfo; 828 } 829 getRouterInfo()830 public override RouterInfo getRouterInfo() 831 { 832 return _routerInfo; 833 } 834 getCollocationOptimized()835 public override bool getCollocationOptimized() 836 { 837 return _collocationOptimized; 838 } 839 getCacheConnection()840 public override bool getCacheConnection() 841 { 842 return _cacheConnection; 843 } 844 getPreferSecure()845 public override bool getPreferSecure() 846 { 847 return _preferSecure; 848 } 849 getEndpointSelection()850 public override Ice.EndpointSelectionType getEndpointSelection() 851 { 852 return _endpointSelection; 853 } 854 getLocatorCacheTimeout()855 public override int getLocatorCacheTimeout() 856 { 857 return _locatorCacheTimeout; 858 } 859 getConnectionId()860 public override string getConnectionId() 861 { 862 return _connectionId; 863 } 864 getTimeout()865 public override Ice.Optional<int> getTimeout() 866 { 867 return _overrideTimeout ? _timeout : new Ice.Optional<int>(); 868 } 869 getThreadPool()870 public override ThreadPool getThreadPool() 871 { 872 return getInstance().clientThreadPool(); 873 } 874 changeEncoding(Ice.EncodingVersion newEncoding)875 public override Reference changeEncoding(Ice.EncodingVersion newEncoding) 876 { 877 RoutableReference r = (RoutableReference)base.changeEncoding(newEncoding); 878 if(r != this) 879 { 880 LocatorInfo locInfo = r._locatorInfo; 881 if(locInfo != null && !locInfo.getLocator().ice_getEncodingVersion().Equals(newEncoding)) 882 { 883 r._locatorInfo = getInstance().locatorManager().get( 884 (Ice.LocatorPrx)locInfo.getLocator().ice_encodingVersion(newEncoding)); 885 } 886 } 887 return r; 888 } 889 changeCompress(bool newCompress)890 public override Reference changeCompress(bool newCompress) 891 { 892 RoutableReference r = (RoutableReference)base.changeCompress(newCompress); 893 if(r != this && _endpoints.Length > 0) // Also override the compress flag on the endpoints if it was updated 894 { 895 EndpointI[] newEndpoints = new EndpointI[_endpoints.Length]; 896 for(int i = 0; i < _endpoints.Length; i++) 897 { 898 newEndpoints[i] = _endpoints[i].compress(newCompress); 899 } 900 r._endpoints = newEndpoints; 901 } 902 return r; 903 } 904 changeEndpoints(EndpointI[] newEndpoints)905 public override Reference changeEndpoints(EndpointI[] newEndpoints) 906 { 907 if(Equals(newEndpoints, _endpoints)) 908 { 909 return this; 910 } 911 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 912 r._endpoints = newEndpoints; 913 r._adapterId = ""; 914 r.applyOverrides(ref r._endpoints); 915 return r; 916 } 917 changeAdapterId(string newAdapterId)918 public override Reference changeAdapterId(string newAdapterId) 919 { 920 if(_adapterId.Equals(newAdapterId)) 921 { 922 return this; 923 } 924 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 925 r._adapterId = newAdapterId; 926 r._endpoints = _emptyEndpoints; 927 return r; 928 } 929 changeLocator(Ice.LocatorPrx newLocator)930 public override Reference changeLocator(Ice.LocatorPrx newLocator) 931 { 932 LocatorInfo newLocatorInfo = getInstance().locatorManager().get(newLocator); 933 if(newLocatorInfo != null && _locatorInfo != null && newLocatorInfo.Equals(_locatorInfo)) 934 { 935 return this; 936 } 937 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 938 r._locatorInfo = newLocatorInfo; 939 return r; 940 } 941 changeRouter(Ice.RouterPrx newRouter)942 public override Reference changeRouter(Ice.RouterPrx newRouter) 943 { 944 RouterInfo newRouterInfo = getInstance().routerManager().get(newRouter); 945 if(newRouterInfo != null && _routerInfo != null && newRouterInfo.Equals(_routerInfo)) 946 { 947 return this; 948 } 949 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 950 r._routerInfo = newRouterInfo; 951 return r; 952 } 953 changeCollocationOptimized(bool newCollocationOptimized)954 public override Reference changeCollocationOptimized(bool newCollocationOptimized) 955 { 956 if(newCollocationOptimized == _collocationOptimized) 957 { 958 return this; 959 } 960 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 961 r._collocationOptimized = newCollocationOptimized; 962 return r; 963 } 964 changeCacheConnection(bool newCache)965 public override Reference changeCacheConnection(bool newCache) 966 { 967 if(newCache == _cacheConnection) 968 { 969 return this; 970 } 971 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 972 r._cacheConnection = newCache; 973 return r; 974 } 975 changePreferSecure(bool newPreferSecure)976 public override Reference changePreferSecure(bool newPreferSecure) 977 { 978 if(newPreferSecure == _preferSecure) 979 { 980 return this; 981 } 982 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 983 r._preferSecure = newPreferSecure; 984 return r; 985 } 986 changeEndpointSelection(Ice.EndpointSelectionType newType)987 public override Reference changeEndpointSelection(Ice.EndpointSelectionType newType) 988 { 989 if(newType == _endpointSelection) 990 { 991 return this; 992 } 993 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 994 r._endpointSelection = newType; 995 return r; 996 } 997 changeLocatorCacheTimeout(int newTimeout)998 public override Reference changeLocatorCacheTimeout(int newTimeout) 999 { 1000 if(newTimeout == _locatorCacheTimeout) 1001 { 1002 return this; 1003 } 1004 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 1005 r._locatorCacheTimeout = newTimeout; 1006 return r; 1007 } 1008 changeTimeout(int newTimeout)1009 public override Reference changeTimeout(int newTimeout) 1010 { 1011 if(_overrideTimeout && _timeout == newTimeout) 1012 { 1013 return this; 1014 } 1015 1016 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 1017 r._timeout = newTimeout; 1018 r._overrideTimeout = true; 1019 if(_endpoints.Length > 0) 1020 { 1021 EndpointI[] newEndpoints = new EndpointI[_endpoints.Length]; 1022 for(int i = 0; i < _endpoints.Length; i++) 1023 { 1024 newEndpoints[i] = _endpoints[i].timeout(newTimeout); 1025 } 1026 r._endpoints = newEndpoints; 1027 } 1028 return r; 1029 } 1030 changeConnectionId(string id)1031 public override Reference changeConnectionId(string id) 1032 { 1033 if(_connectionId.Equals(id)) 1034 { 1035 return this; 1036 } 1037 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this); 1038 r._connectionId = id; 1039 if(_endpoints.Length > 0) 1040 { 1041 EndpointI[] newEndpoints = new EndpointI[_endpoints.Length]; 1042 for(int i = 0; i < _endpoints.Length; i++) 1043 { 1044 newEndpoints[i] = _endpoints[i].connectionId(id); 1045 } 1046 r._endpoints = newEndpoints; 1047 } 1048 return r; 1049 } 1050 changeConnection(Ice.ConnectionI connection)1051 public override Reference changeConnection(Ice.ConnectionI connection) 1052 { 1053 return new FixedReference(getInstance(), 1054 getCommunicator(), 1055 getIdentity(), 1056 getFacet(), 1057 getMode(), 1058 getSecure(), 1059 getProtocol(), 1060 getEncoding(), 1061 connection, 1062 getInvocationTimeout(), 1063 getContext(), 1064 getCompress()); 1065 } 1066 isIndirect()1067 public override bool isIndirect() 1068 { 1069 return _endpoints.Length == 0; 1070 } 1071 isWellKnown()1072 public override bool isWellKnown() 1073 { 1074 return _endpoints.Length == 0 && _adapterId.Length == 0; 1075 } 1076 streamWrite(Ice.OutputStream s)1077 public override void streamWrite(Ice.OutputStream s) 1078 { 1079 base.streamWrite(s); 1080 1081 s.writeSize(_endpoints.Length); 1082 if(_endpoints.Length > 0) 1083 { 1084 Debug.Assert(_adapterId.Length == 0); 1085 foreach(EndpointI endpoint in _endpoints) 1086 { 1087 s.writeShort(endpoint.type()); 1088 endpoint.streamWrite(s); 1089 } 1090 } 1091 else 1092 { 1093 s.writeString(_adapterId); // Adapter id. 1094 } 1095 } 1096 ToString()1097 public override string ToString() 1098 { 1099 // 1100 // WARNING: Certain features, such as proxy validation in Glacier2, 1101 // depend on the format of proxy strings. Changes to toString() and 1102 // methods called to generate parts of the reference string could break 1103 // these features. Please review for all features that depend on the 1104 // format of proxyToString() before changing this and related code. 1105 // 1106 StringBuilder s = new StringBuilder(); 1107 s.Append(base.ToString()); 1108 1109 if(_endpoints.Length > 0) 1110 { 1111 for(int i = 0; i < _endpoints.Length; i++) 1112 { 1113 string endp = _endpoints[i].ToString(); 1114 if(endp != null && endp.Length > 0) 1115 { 1116 s.Append(':'); 1117 s.Append(endp); 1118 } 1119 } 1120 } 1121 else if(_adapterId.Length > 0) 1122 { 1123 s.Append(" @ "); 1124 1125 // 1126 // If the encoded adapter id string contains characters which 1127 // the reference parser uses as separators, then we enclose 1128 // the adapter id string in quotes. 1129 // 1130 string a = IceUtilInternal.StringUtil.escapeString(_adapterId, null, getInstance().toStringMode()); 1131 if(IceUtilInternal.StringUtil.findFirstOf(a, " :@") != -1) 1132 { 1133 s.Append('"'); 1134 s.Append(a); 1135 s.Append('"'); 1136 } 1137 else 1138 { 1139 s.Append(a); 1140 } 1141 } 1142 return s.ToString(); 1143 } 1144 toProperty(string prefix)1145 public override Dictionary<string, string> toProperty(string prefix) 1146 { 1147 Dictionary<string, string> properties = new Dictionary<string, string>(); 1148 1149 properties[prefix] = ToString(); 1150 properties[prefix + ".CollocationOptimized"] = _collocationOptimized ? "1" : "0"; 1151 properties[prefix + ".ConnectionCached"] = _cacheConnection ? "1" : "0"; 1152 properties[prefix + ".PreferSecure"] = _preferSecure ? "1" : "0"; 1153 properties[prefix + ".EndpointSelection"] = 1154 _endpointSelection == Ice.EndpointSelectionType.Random ? "Random" : "Ordered"; 1155 properties[prefix + ".LocatorCacheTimeout"] = _locatorCacheTimeout.ToString(CultureInfo.InvariantCulture); 1156 properties[prefix + ".InvocationTimeout"] = getInvocationTimeout().ToString(CultureInfo.InvariantCulture); 1157 1158 if(_routerInfo != null) 1159 { 1160 Ice.ObjectPrxHelperBase h = (Ice.ObjectPrxHelperBase)_routerInfo.getRouter(); 1161 Dictionary<string, string> routerProperties = h.iceReference().toProperty(prefix + ".Router"); 1162 foreach(KeyValuePair<string, string> entry in routerProperties) 1163 { 1164 properties[entry.Key] = entry.Value; 1165 } 1166 } 1167 1168 if(_locatorInfo != null) 1169 { 1170 Ice.ObjectPrxHelperBase h = (Ice.ObjectPrxHelperBase)_locatorInfo.getLocator(); 1171 Dictionary<string, string> locatorProperties = h.iceReference().toProperty(prefix + ".Locator"); 1172 foreach(KeyValuePair<string, string> entry in locatorProperties) 1173 { 1174 properties[entry.Key] = entry.Value; 1175 } 1176 } 1177 1178 return properties; 1179 } 1180 1181 // 1182 // If we override Equals, we must also override GetHashCode. 1183 // GetHashCode()1184 public override int GetHashCode() 1185 { 1186 lock(this) 1187 { 1188 if(!hashInitialized_) 1189 { 1190 int h = base.GetHashCode(); // Initializes hashValue_. 1191 HashUtil.hashAdd(ref h, _adapterId); 1192 hashValue_ = h; 1193 } 1194 return hashValue_; 1195 } 1196 } 1197 Equals(object obj)1198 public override bool Equals(object obj) 1199 { 1200 if(ReferenceEquals(this, obj)) 1201 { 1202 return true; 1203 } 1204 1205 RoutableReference rhs = obj as RoutableReference; 1206 if(rhs == null) 1207 { 1208 return false; 1209 } 1210 1211 if(!base.Equals(obj)) 1212 { 1213 return false; 1214 } 1215 1216 if(_locatorInfo == null ? rhs._locatorInfo != null : !_locatorInfo.Equals(rhs._locatorInfo)) 1217 { 1218 return false; 1219 } 1220 if(_routerInfo == null ? rhs._routerInfo != null : !_routerInfo.Equals(rhs._routerInfo)) 1221 { 1222 return false; 1223 } 1224 if(_collocationOptimized != rhs._collocationOptimized) 1225 { 1226 return false; 1227 } 1228 if(_cacheConnection != rhs._cacheConnection) 1229 { 1230 return false; 1231 } 1232 if(_preferSecure != rhs._preferSecure) 1233 { 1234 return false; 1235 } 1236 if(_endpointSelection != rhs._endpointSelection) 1237 { 1238 return false; 1239 } 1240 if(_locatorCacheTimeout != rhs._locatorCacheTimeout) 1241 { 1242 return false; 1243 } 1244 if(_overrideTimeout != rhs._overrideTimeout) 1245 { 1246 return false; 1247 } 1248 if(_overrideTimeout && _timeout != rhs._timeout) 1249 { 1250 return false; 1251 } 1252 if(!_connectionId.Equals(rhs._connectionId)) 1253 { 1254 return false; 1255 } 1256 if(!_adapterId.Equals(rhs._adapterId)) 1257 { 1258 return false; 1259 } 1260 if(!IceUtilInternal.Arrays.Equals(_endpoints, rhs._endpoints)) 1261 { 1262 return false; 1263 } 1264 return true; 1265 } 1266 1267 private sealed class RouterEndpointsCallback : RouterInfo.GetClientEndpointsCallback 1268 { RouterEndpointsCallback(RoutableReference ir, GetConnectionCallback cb)1269 internal RouterEndpointsCallback(RoutableReference ir, GetConnectionCallback cb) 1270 { 1271 _ir = ir; 1272 _cb = cb; 1273 } 1274 setEndpoints(EndpointI[] endpts)1275 public void setEndpoints(EndpointI[] endpts) 1276 { 1277 if(endpts.Length > 0) 1278 { 1279 _ir.applyOverrides(ref endpts); 1280 _ir.createConnection(endpts, _cb); 1281 } 1282 else 1283 { 1284 _ir.getConnectionNoRouterInfo(_cb); 1285 } 1286 } 1287 setException(Ice.LocalException ex)1288 public void setException(Ice.LocalException ex) 1289 { 1290 _cb.setException(ex); 1291 } 1292 1293 private RoutableReference _ir; 1294 private GetConnectionCallback _cb; 1295 } 1296 getRequestHandler(Ice.ObjectPrxHelperBase proxy)1297 public override RequestHandler getRequestHandler(Ice.ObjectPrxHelperBase proxy) 1298 { 1299 return getInstance().requestHandlerFactory().getRequestHandler(this, proxy); 1300 } 1301 getBatchRequestQueue()1302 public override BatchRequestQueue getBatchRequestQueue() 1303 { 1304 return new BatchRequestQueue(getInstance(), getMode() == Reference.Mode.ModeBatchDatagram); 1305 } 1306 getConnection(GetConnectionCallback callback)1307 public void getConnection(GetConnectionCallback callback) 1308 { 1309 if(_routerInfo != null) 1310 { 1311 // 1312 // If we route, we send everything to the router's client 1313 // proxy endpoints. 1314 // 1315 _routerInfo.getClientEndpoints(new RouterEndpointsCallback(this, callback)); 1316 } 1317 else 1318 { 1319 getConnectionNoRouterInfo(callback); 1320 } 1321 } 1322 1323 private sealed class LocatorEndpointsCallback : LocatorInfo.GetEndpointsCallback 1324 { LocatorEndpointsCallback(RoutableReference ir, GetConnectionCallback cb)1325 internal LocatorEndpointsCallback(RoutableReference ir, GetConnectionCallback cb) 1326 { 1327 _ir = ir; 1328 _cb = cb; 1329 } 1330 setEndpoints(EndpointI[] endpoints, bool cached)1331 public void setEndpoints(EndpointI[] endpoints, bool cached) 1332 { 1333 if(endpoints.Length == 0) 1334 { 1335 _cb.setException(new Ice.NoEndpointException(_ir.ToString())); 1336 return; 1337 } 1338 1339 _ir.applyOverrides(ref endpoints); 1340 _ir.createConnection(endpoints, new ConnectionCallback(_ir, _cb, cached)); 1341 } 1342 setException(Ice.LocalException ex)1343 public void setException(Ice.LocalException ex) 1344 { 1345 _cb.setException(ex); 1346 } 1347 1348 private RoutableReference _ir; 1349 private GetConnectionCallback _cb; 1350 } 1351 1352 private sealed class ConnectionCallback : GetConnectionCallback 1353 { ConnectionCallback(RoutableReference ir, GetConnectionCallback cb, bool cached)1354 internal ConnectionCallback(RoutableReference ir, GetConnectionCallback cb, bool cached) 1355 { 1356 _ir = ir; 1357 _cb = cb; 1358 _cached = cached; 1359 } 1360 setConnection(Ice.ConnectionI connection, bool compress)1361 public void setConnection(Ice.ConnectionI connection, bool compress) 1362 { 1363 _cb.setConnection(connection, compress); 1364 } 1365 setException(Ice.LocalException exc)1366 public void setException(Ice.LocalException exc) 1367 { 1368 try 1369 { 1370 throw exc; 1371 } 1372 catch(Ice.NoEndpointException ex) 1373 { 1374 _cb.setException(ex); // No need to retry if there's no endpoints. 1375 } 1376 catch(Ice.LocalException ex) 1377 { 1378 Debug.Assert(_ir._locatorInfo != null); 1379 _ir._locatorInfo.clearCache(_ir); 1380 if(_cached) 1381 { 1382 TraceLevels traceLevels = _ir.getInstance().traceLevels(); 1383 if(traceLevels.retry >= 2) 1384 { 1385 String s = "connection to cached endpoints failed\n" + 1386 "removing endpoints from cache and trying again\n" + ex; 1387 _ir.getInstance().initializationData().logger.trace(traceLevels.retryCat, s); 1388 } 1389 _ir.getConnectionNoRouterInfo(_cb); // Retry. 1390 return; 1391 } 1392 _cb.setException(ex); 1393 } 1394 } 1395 1396 private RoutableReference _ir; 1397 private GetConnectionCallback _cb; 1398 private bool _cached; 1399 } 1400 getConnectionNoRouterInfo(GetConnectionCallback callback)1401 private void getConnectionNoRouterInfo(GetConnectionCallback callback) 1402 { 1403 if(_endpoints.Length > 0) 1404 { 1405 createConnection(_endpoints, callback); 1406 return; 1407 } 1408 1409 if(_locatorInfo != null) 1410 { 1411 _locatorInfo.getEndpoints(this, _locatorCacheTimeout, new LocatorEndpointsCallback(this, callback)); 1412 } 1413 else 1414 { 1415 callback.setException(new Ice.NoEndpointException(ToString())); 1416 } 1417 } 1418 RoutableReference(Instance instance, Ice.Communicator communicator, Ice.Identity identity, string facet, Mode mode, bool secure, Ice.ProtocolVersion protocol, Ice.EncodingVersion encoding, EndpointI[] endpoints, string adapterId, LocatorInfo locatorInfo, RouterInfo routerInfo, bool collocationOptimized, bool cacheConnection, bool preferSecure, Ice.EndpointSelectionType endpointSelection, int locatorCacheTimeout, int invocationTimeout, Dictionary<string, string> context)1419 public RoutableReference(Instance instance, 1420 Ice.Communicator communicator, 1421 Ice.Identity identity, 1422 string facet, 1423 Mode mode, 1424 bool secure, 1425 Ice.ProtocolVersion protocol, 1426 Ice.EncodingVersion encoding, 1427 EndpointI[] endpoints, 1428 string adapterId, 1429 LocatorInfo locatorInfo, 1430 RouterInfo routerInfo, 1431 bool collocationOptimized, 1432 bool cacheConnection, 1433 bool preferSecure, 1434 Ice.EndpointSelectionType endpointSelection, 1435 int locatorCacheTimeout, 1436 int invocationTimeout, 1437 Dictionary<string, string> context) 1438 : base(instance, communicator, identity, facet, mode, secure, protocol, encoding, invocationTimeout, context) 1439 { 1440 _endpoints = endpoints; 1441 _adapterId = adapterId; 1442 _locatorInfo = locatorInfo; 1443 _routerInfo = routerInfo; 1444 _collocationOptimized = collocationOptimized; 1445 _cacheConnection = cacheConnection; 1446 _preferSecure = preferSecure; 1447 _endpointSelection = endpointSelection; 1448 _locatorCacheTimeout = locatorCacheTimeout; 1449 _overrideTimeout = false; 1450 _timeout = -1; 1451 1452 if(_endpoints == null) 1453 { 1454 _endpoints = _emptyEndpoints; 1455 } 1456 1457 if(_adapterId == null) 1458 { 1459 _adapterId = ""; 1460 } 1461 1462 Debug.Assert(_adapterId.Length == 0 || _endpoints.Length == 0); 1463 } 1464 applyOverrides(ref EndpointI[] endpts)1465 protected void applyOverrides(ref EndpointI[] endpts) 1466 { 1467 for(int i = 0; i < endpts.Length; ++i) 1468 { 1469 endpts[i] = endpts[i].connectionId(_connectionId); 1470 if(overrideCompress_) 1471 { 1472 endpts[i] = endpts[i].compress(compress_); 1473 } 1474 if(_overrideTimeout) 1475 { 1476 endpts[i] = endpts[i].timeout(_timeout); 1477 } 1478 } 1479 } 1480 filterEndpoints(EndpointI[] allEndpoints)1481 private EndpointI[] filterEndpoints(EndpointI[] allEndpoints) 1482 { 1483 List<EndpointI> endpoints = new List<EndpointI>(); 1484 1485 // 1486 // Filter out unknown endpoints. 1487 // 1488 for(int i = 0; i < allEndpoints.Length; i++) 1489 { 1490 if(!(allEndpoints[i] is OpaqueEndpointI)) 1491 { 1492 endpoints.Add(allEndpoints[i]); 1493 } 1494 } 1495 1496 // 1497 // Filter out endpoints according to the mode of the reference. 1498 // 1499 switch(getMode()) 1500 { 1501 case Mode.ModeTwoway: 1502 case Mode.ModeOneway: 1503 case Mode.ModeBatchOneway: 1504 { 1505 // 1506 // Filter out datagram endpoints. 1507 // 1508 List<EndpointI> tmp = new List<EndpointI>(); 1509 foreach(EndpointI endpoint in endpoints) 1510 { 1511 if(!endpoint.datagram()) 1512 { 1513 tmp.Add(endpoint); 1514 } 1515 } 1516 endpoints = tmp; 1517 break; 1518 } 1519 1520 case Mode.ModeDatagram: 1521 case Mode.ModeBatchDatagram: 1522 { 1523 // 1524 // Filter out non-datagram endpoints. 1525 // 1526 List<EndpointI> tmp = new List<EndpointI>(); 1527 foreach(EndpointI endpoint in endpoints) 1528 { 1529 if(endpoint.datagram()) 1530 { 1531 tmp.Add(endpoint); 1532 } 1533 } 1534 endpoints = tmp; 1535 break; 1536 } 1537 } 1538 1539 // 1540 // Sort the endpoints according to the endpoint selection type. 1541 // 1542 switch(getEndpointSelection()) 1543 { 1544 case Ice.EndpointSelectionType.Random: 1545 { 1546 lock(rand_) 1547 { 1548 for(int i = 0; i < endpoints.Count - 1; ++i) 1549 { 1550 int r = rand_.Next(endpoints.Count - i) + i; 1551 Debug.Assert(r >= i && r < endpoints.Count); 1552 if(r != i) 1553 { 1554 EndpointI tmp = endpoints[i]; 1555 endpoints[i] = endpoints[r]; 1556 endpoints[r] = tmp; 1557 } 1558 } 1559 } 1560 break; 1561 } 1562 case Ice.EndpointSelectionType.Ordered: 1563 { 1564 // Nothing to do. 1565 break; 1566 } 1567 default: 1568 { 1569 Debug.Assert(false); 1570 break; 1571 } 1572 } 1573 1574 // 1575 // If a secure connection is requested or secure overrides 1576 // is set, remove all non-secure endpoints. Otherwise make 1577 // non-secure endpoints preferred over secure endpoints by 1578 // partitioning the endpoint vector, so that non-secure 1579 // endpoints come first. 1580 // 1581 DefaultsAndOverrides overrides = getInstance().defaultsAndOverrides(); 1582 if(overrides.overrideSecure ? overrides.overrideSecureValue : getSecure()) 1583 { 1584 List<EndpointI> tmp = new List<EndpointI>(); 1585 foreach(EndpointI endpoint in endpoints) 1586 { 1587 if(endpoint.secure()) 1588 { 1589 tmp.Add(endpoint); 1590 } 1591 } 1592 endpoints = tmp; 1593 } 1594 else if(getPreferSecure()) 1595 { 1596 IceUtilInternal.Collections.Sort(ref endpoints, _preferSecureEndpointComparator); 1597 } 1598 else 1599 { 1600 IceUtilInternal.Collections.Sort(ref endpoints, _preferNonSecureEndpointComparator); 1601 } 1602 1603 EndpointI[] arr = new EndpointI[endpoints.Count]; 1604 endpoints.CopyTo(arr); 1605 return arr; 1606 } 1607 1608 private sealed class CreateConnectionCallback : OutgoingConnectionFactory.CreateConnectionCallback 1609 { CreateConnectionCallback(RoutableReference rr, EndpointI[] endpoints, GetConnectionCallback cb)1610 internal CreateConnectionCallback(RoutableReference rr, EndpointI[] endpoints, GetConnectionCallback cb) 1611 { 1612 _rr = rr; 1613 _endpoints = endpoints; 1614 _callback = cb; 1615 } 1616 setConnection(Ice.ConnectionI connection, bool compress)1617 public void setConnection(Ice.ConnectionI connection, bool compress) 1618 { 1619 // 1620 // If we have a router, set the object adapter for this router 1621 // (if any) to the new connection, so that callbacks from the 1622 // router can be received over this new connection. 1623 // 1624 if(_rr._routerInfo != null && _rr._routerInfo.getAdapter() != null) 1625 { 1626 connection.setAdapter(_rr._routerInfo.getAdapter()); 1627 } 1628 _callback.setConnection(connection, compress); 1629 } 1630 setException(Ice.LocalException ex)1631 public void setException(Ice.LocalException ex) 1632 { 1633 if(_exception == null) 1634 { 1635 _exception = ex; 1636 } 1637 1638 if(_endpoints == null || ++_i == _endpoints.Length) 1639 { 1640 _callback.setException(_exception); 1641 return; 1642 } 1643 1644 bool more = _i != _endpoints.Length - 1; 1645 EndpointI[] endpoint = new EndpointI[]{ _endpoints[_i] }; 1646 _rr.getInstance().outgoingConnectionFactory().create(endpoint, more, _rr.getEndpointSelection(), this); 1647 } 1648 1649 private RoutableReference _rr; 1650 private EndpointI[] _endpoints; 1651 private GetConnectionCallback _callback; 1652 private int _i = 0; 1653 private Ice.LocalException _exception = null; 1654 } 1655 createConnection(EndpointI[] allEndpoints, GetConnectionCallback callback)1656 protected void createConnection(EndpointI[] allEndpoints, GetConnectionCallback callback) 1657 { 1658 EndpointI[] endpoints = filterEndpoints(allEndpoints); 1659 if(endpoints.Length == 0) 1660 { 1661 callback.setException(new Ice.NoEndpointException(ToString())); 1662 return; 1663 } 1664 1665 // 1666 // Finally, create the connection. 1667 // 1668 OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory(); 1669 if(getCacheConnection() || endpoints.Length == 1) 1670 { 1671 // 1672 // Get an existing connection or create one if there's no 1673 // existing connection to one of the given endpoints. 1674 // 1675 factory.create(endpoints, false, getEndpointSelection(), 1676 new CreateConnectionCallback(this, null, callback)); 1677 } 1678 else 1679 { 1680 // 1681 // Go through the list of endpoints and try to create the 1682 // connection until it succeeds. This is different from just 1683 // calling create() with the given endpoints since this might 1684 // create a new connection even if there's an existing 1685 // connection for one of the endpoints. 1686 // 1687 1688 factory.create(new EndpointI[]{ endpoints[0] }, true, getEndpointSelection(), 1689 new CreateConnectionCallback(this, endpoints, callback)); 1690 } 1691 } 1692 1693 private class EndpointComparator : IComparer<EndpointI> 1694 { EndpointComparator(bool preferSecure)1695 public EndpointComparator(bool preferSecure) 1696 { 1697 _preferSecure = preferSecure; 1698 } 1699 Compare(EndpointI le, EndpointI re)1700 public int Compare(EndpointI le, EndpointI re) 1701 { 1702 bool ls = le.secure(); 1703 bool rs = re.secure(); 1704 if((ls && rs) || (!ls && !rs)) 1705 { 1706 return 0; 1707 } 1708 else if(!ls && rs) 1709 { 1710 if(_preferSecure) 1711 { 1712 return 1; 1713 } 1714 else 1715 { 1716 return -1; 1717 } 1718 } 1719 else 1720 { 1721 if(_preferSecure) 1722 { 1723 return -1; 1724 } 1725 else 1726 { 1727 return 1; 1728 } 1729 } 1730 } 1731 1732 private bool _preferSecure; 1733 } 1734 1735 private static EndpointComparator _preferNonSecureEndpointComparator = new EndpointComparator(false); 1736 private static EndpointComparator _preferSecureEndpointComparator = new EndpointComparator(true); 1737 private static EndpointI[] _emptyEndpoints = new EndpointI[0]; 1738 1739 private EndpointI[] _endpoints; 1740 private string _adapterId; 1741 private LocatorInfo _locatorInfo; // Null if no locator is used. 1742 private RouterInfo _routerInfo; // Null if no router is used. 1743 private bool _collocationOptimized; 1744 private bool _cacheConnection; 1745 private bool _preferSecure; 1746 private Ice.EndpointSelectionType _endpointSelection; 1747 private int _locatorCacheTimeout; 1748 1749 private bool _overrideTimeout; 1750 private int _timeout; // Only used if _overrideTimeout == true 1751 private string _connectionId = ""; 1752 } 1753 } 1754