1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 namespace Ice 6 { 7 using System; 8 using System.Collections.Generic; 9 using System.Diagnostics; 10 using System.Text; 11 12 using IceInternal; 13 14 public sealed class ObjectAdapterI : ObjectAdapter 15 { getName()16 public string getName() 17 { 18 // 19 // No mutex lock necessary, _name is immutable. 20 // 21 return _noConfig ? "" : _name; 22 } 23 getCommunicator()24 public Communicator getCommunicator() 25 { 26 return _communicator; 27 } 28 activate()29 public void activate() 30 { 31 LocatorInfo locatorInfo = null; 32 bool printAdapterReady = false; 33 34 lock(this) 35 { 36 checkForDeactivation(); 37 38 // 39 // If we've previously been initialized we just need to activate the 40 // incoming connection factories and we're done. 41 // 42 if(_state != StateUninitialized) 43 { 44 foreach(IncomingConnectionFactory icf in _incomingConnectionFactories) 45 { 46 icf.activate(); 47 } 48 return; 49 } 50 51 // 52 // One off initializations of the adapter: update the 53 // locator registry and print the "adapter ready" 54 // message. We set set state to StateActivating to prevent 55 // deactivation from other threads while these one off 56 // initializations are done. 57 // 58 _state = StateActivating; 59 60 locatorInfo = _locatorInfo; 61 if(!_noConfig) 62 { 63 Properties properties = _instance.initializationData().properties; 64 printAdapterReady = properties.getPropertyAsInt("Ice.PrintAdapterReady") > 0; 65 } 66 } 67 68 try 69 { 70 Identity dummy = new Identity(); 71 dummy.name = "dummy"; 72 updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); 73 } 74 catch(LocalException) 75 { 76 // 77 // If we couldn't update the locator registry, we let the 78 // exception go through and don't activate the adapter to 79 // allow to user code to retry activating the adapter 80 // later. 81 // 82 lock(this) 83 { 84 _state = StateUninitialized; 85 System.Threading.Monitor.PulseAll(this); 86 } 87 throw; 88 } 89 90 if(printAdapterReady) 91 { 92 Console.Out.WriteLine(_name + " ready"); 93 } 94 95 lock(this) 96 { 97 Debug.Assert(_state == StateActivating); 98 99 foreach(IncomingConnectionFactory icf in _incomingConnectionFactories) 100 { 101 icf.activate(); 102 } 103 104 _state = StateActive; 105 System.Threading.Monitor.PulseAll(this); 106 } 107 } 108 hold()109 public void hold() 110 { 111 lock(this) 112 { 113 checkForDeactivation(); 114 _state = StateHeld; 115 foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) 116 { 117 factory.hold(); 118 } 119 } 120 } 121 waitForHold()122 public void waitForHold() 123 { 124 List<IncomingConnectionFactory> incomingConnectionFactories; 125 lock(this) 126 { 127 checkForDeactivation(); 128 129 incomingConnectionFactories = new List<IncomingConnectionFactory>(_incomingConnectionFactories); 130 } 131 132 foreach(IncomingConnectionFactory factory in incomingConnectionFactories) 133 { 134 factory.waitUntilHolding(); 135 } 136 } 137 deactivate()138 public void deactivate() 139 { 140 lock(this) 141 { 142 // 143 // 144 // Wait for activation to complete. This is necessary to not 145 // get out of order locator updates. 146 // 147 while(_state == StateActivating || _state == StateDeactivating) 148 { 149 System.Threading.Monitor.Wait(this); 150 } 151 if(_state > StateDeactivating) 152 { 153 return; 154 } 155 _state = StateDeactivating; 156 } 157 158 // 159 // NOTE: the router/locator infos and incoming connection 160 // factory list are immutable at this point. 161 // 162 163 try 164 { 165 if(_routerInfo != null) 166 { 167 // 168 // Remove entry from the router manager. 169 // 170 _instance.routerManager().erase(_routerInfo.getRouter()); 171 172 // 173 // Clear this object adapter with the router. 174 // 175 _routerInfo.setAdapter(null); 176 } 177 178 updateLocatorRegistry(_locatorInfo, null); 179 } 180 catch(LocalException) 181 { 182 // 183 // We can't throw exceptions in deactivate so we ignore 184 // failures to update the locator registry. 185 // 186 } 187 188 foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) 189 { 190 factory.destroy(); 191 } 192 193 _instance.outgoingConnectionFactory().removeAdapter(this); 194 195 lock(this) 196 { 197 Debug.Assert(_state == StateDeactivating); 198 _state = StateDeactivated; 199 System.Threading.Monitor.PulseAll(this); 200 } 201 } 202 waitForDeactivate()203 public void waitForDeactivate() 204 { 205 IncomingConnectionFactory[] incomingConnectionFactories = null; 206 lock(this) 207 { 208 // 209 // Wait for deactivation of the adapter itself, and 210 // for the return of all direct method calls using this 211 // adapter. 212 // 213 while((_state < StateDeactivated) || _directCount > 0) 214 { 215 System.Threading.Monitor.Wait(this); 216 } 217 if(_state > StateDeactivated) 218 { 219 return; 220 } 221 222 incomingConnectionFactories = _incomingConnectionFactories.ToArray(); 223 } 224 225 // 226 // Now we wait for until all incoming connection factories are 227 // finished. 228 // 229 foreach(IncomingConnectionFactory factory in incomingConnectionFactories) 230 { 231 factory.waitUntilFinished(); 232 } 233 } 234 isDeactivated()235 public bool isDeactivated() 236 { 237 lock(this) 238 { 239 return _state >= StateDeactivated; 240 } 241 } 242 destroy()243 public void destroy() 244 { 245 // 246 // Deactivate and wait for completion. 247 // 248 deactivate(); 249 waitForDeactivate(); 250 251 lock(this) 252 { 253 // 254 // Only a single thread is allowed to destroy the object 255 // adapter. Other threads wait for the destruction to be 256 // completed. 257 // 258 while(_state == StateDestroying) 259 { 260 System.Threading.Monitor.Wait(this); 261 } 262 if(_state == StateDestroyed) 263 { 264 return; 265 } 266 _state = StateDestroying; 267 } 268 269 // 270 // Now it's also time to clean up our servants and servant 271 // locators. 272 // 273 _servantManager.destroy(); 274 275 // 276 // Destroy the thread pool. 277 // 278 if(_threadPool != null) 279 { 280 _threadPool.destroy(); 281 _threadPool.joinWithAllThreads(); 282 } 283 284 if(_objectAdapterFactory != null) 285 { 286 _objectAdapterFactory.removeObjectAdapter(this); 287 } 288 289 lock(this) 290 { 291 // 292 // We're done, now we can throw away all incoming connection 293 // factories. 294 // 295 _incomingConnectionFactories.Clear(); 296 297 // 298 // Remove object references (some of them cyclic). 299 // 300 _instance = null; 301 _threadPool = null; 302 _routerInfo = null; 303 _publishedEndpoints = new EndpointI[0]; 304 _locatorInfo = null; 305 _reference = null; 306 _objectAdapterFactory = null; 307 308 _state = StateDestroyed; 309 System.Threading.Monitor.PulseAll(this); 310 } 311 } 312 add(Object obj, Identity ident)313 public ObjectPrx add(Object obj, Identity ident) 314 { 315 return addFacet(obj, ident, ""); 316 } 317 addFacet(Object obj, Identity ident, string facet)318 public ObjectPrx addFacet(Object obj, Identity ident, string facet) 319 { 320 lock(this) 321 { 322 checkForDeactivation(); 323 checkIdentity(ident); 324 checkServant(obj); 325 326 // 327 // Create a copy of the Identity argument, in case the caller 328 // reuses it. 329 // 330 Identity id = new Identity(); 331 id.category = ident.category; 332 id.name = ident.name; 333 334 _servantManager.addServant(obj, id, facet); 335 336 return newProxy(id, facet); 337 } 338 } 339 addWithUUID(Object obj)340 public ObjectPrx addWithUUID(Object obj) 341 { 342 return addFacetWithUUID(obj, ""); 343 } 344 addFacetWithUUID(Object obj, string facet)345 public ObjectPrx addFacetWithUUID(Object obj, string facet) 346 { 347 Identity ident = new Identity(); 348 ident.category = ""; 349 ident.name = Guid.NewGuid().ToString(); 350 351 return addFacet(obj, ident, facet); 352 } 353 addDefaultServant(Ice.Object servant, string category)354 public void addDefaultServant(Ice.Object servant, string category) 355 { 356 checkServant(servant); 357 358 lock(this) 359 { 360 checkForDeactivation(); 361 362 _servantManager.addDefaultServant(servant, category); 363 } 364 } 365 remove(Identity ident)366 public Object remove(Identity ident) 367 { 368 return removeFacet(ident, ""); 369 } 370 removeFacet(Identity ident, string facet)371 public Object removeFacet(Identity ident, string facet) 372 { 373 lock(this) 374 { 375 checkForDeactivation(); 376 checkIdentity(ident); 377 378 return _servantManager.removeServant(ident, facet); 379 } 380 } 381 removeAllFacets(Identity ident)382 public Dictionary<string, Object> removeAllFacets(Identity ident) 383 { 384 lock(this) 385 { 386 checkForDeactivation(); 387 checkIdentity(ident); 388 389 return _servantManager.removeAllFacets(ident); 390 } 391 } 392 removeDefaultServant(string category)393 public Object removeDefaultServant(string category) 394 { 395 lock(this) 396 { 397 checkForDeactivation(); 398 399 return _servantManager.removeDefaultServant(category); 400 } 401 } 402 find(Identity ident)403 public Object find(Identity ident) 404 { 405 return findFacet(ident, ""); 406 } 407 findFacet(Identity ident, string facet)408 public Object findFacet(Identity ident, string facet) 409 { 410 lock(this) 411 { 412 checkForDeactivation(); 413 checkIdentity(ident); 414 415 return _servantManager.findServant(ident, facet); 416 } 417 } 418 findAllFacets(Identity ident)419 public Dictionary<string, Object> findAllFacets(Identity ident) 420 { 421 lock(this) 422 { 423 checkForDeactivation(); 424 checkIdentity(ident); 425 426 return _servantManager.findAllFacets(ident); 427 } 428 } 429 findByProxy(ObjectPrx proxy)430 public Object findByProxy(ObjectPrx proxy) 431 { 432 lock(this) 433 { 434 checkForDeactivation(); 435 436 Reference @ref = ((ObjectPrxHelperBase)proxy).iceReference(); 437 return findFacet(@ref.getIdentity(), @ref.getFacet()); 438 } 439 } 440 findDefaultServant(string category)441 public Object findDefaultServant(string category) 442 { 443 lock(this) 444 { 445 checkForDeactivation(); 446 447 return _servantManager.findDefaultServant(category); 448 } 449 } 450 addServantLocator(ServantLocator locator, string prefix)451 public void addServantLocator(ServantLocator locator, string prefix) 452 { 453 lock(this) 454 { 455 checkForDeactivation(); 456 457 _servantManager.addServantLocator(locator, prefix); 458 } 459 } 460 removeServantLocator(string prefix)461 public ServantLocator removeServantLocator(string prefix) 462 { 463 lock(this) 464 { 465 checkForDeactivation(); 466 467 return _servantManager.removeServantLocator(prefix); 468 } 469 } 470 findServantLocator(string prefix)471 public ServantLocator findServantLocator(string prefix) 472 { 473 lock(this) 474 { 475 checkForDeactivation(); 476 477 return _servantManager.findServantLocator(prefix); 478 } 479 } 480 createProxy(Identity ident)481 public ObjectPrx createProxy(Identity ident) 482 { 483 lock(this) 484 { 485 checkForDeactivation(); 486 checkIdentity(ident); 487 488 return newProxy(ident, ""); 489 } 490 } 491 createDirectProxy(Identity ident)492 public ObjectPrx createDirectProxy(Identity ident) 493 { 494 lock(this) 495 { 496 checkForDeactivation(); 497 checkIdentity(ident); 498 499 return newDirectProxy(ident, ""); 500 } 501 } 502 createIndirectProxy(Identity ident)503 public ObjectPrx createIndirectProxy(Identity ident) 504 { 505 lock(this) 506 { 507 checkForDeactivation(); 508 checkIdentity(ident); 509 510 return newIndirectProxy(ident, "", _id); 511 } 512 } 513 setLocator(LocatorPrx locator)514 public void setLocator(LocatorPrx locator) 515 { 516 lock(this) 517 { 518 checkForDeactivation(); 519 520 _locatorInfo = _instance.locatorManager().get(locator); 521 } 522 } 523 getLocator()524 public LocatorPrx getLocator() 525 { 526 lock(this) 527 { 528 checkForDeactivation(); 529 530 if(_locatorInfo == null) 531 { 532 return null; 533 } 534 else 535 { 536 return _locatorInfo.getLocator(); 537 } 538 } 539 } 540 getEndpoints()541 public Endpoint[] getEndpoints() 542 { 543 lock(this) 544 { 545 List<Endpoint> endpoints = new List<Endpoint>(); 546 foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) 547 { 548 endpoints.Add(factory.endpoint()); 549 } 550 return endpoints.ToArray(); 551 } 552 } 553 refreshPublishedEndpoints()554 public void refreshPublishedEndpoints() 555 { 556 LocatorInfo locatorInfo = null; 557 EndpointI[] oldPublishedEndpoints; 558 559 lock(this) 560 { 561 checkForDeactivation(); 562 563 oldPublishedEndpoints = _publishedEndpoints; 564 _publishedEndpoints = computePublishedEndpoints(); 565 566 locatorInfo = _locatorInfo; 567 } 568 569 try 570 { 571 Identity dummy = new Identity(); 572 dummy.name = "dummy"; 573 updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); 574 } 575 catch(LocalException) 576 { 577 lock(this) 578 { 579 // 580 // Restore the old published endpoints. 581 // 582 _publishedEndpoints = oldPublishedEndpoints; 583 throw; 584 } 585 } 586 } 587 getPublishedEndpoints()588 public Endpoint[] getPublishedEndpoints() 589 { 590 lock(this) 591 { 592 return (Endpoint[])_publishedEndpoints.Clone(); 593 } 594 } 595 setPublishedEndpoints(Endpoint[] newEndpoints)596 public void setPublishedEndpoints(Endpoint[] newEndpoints) 597 { 598 LocatorInfo locatorInfo = null; 599 EndpointI[] oldPublishedEndpoints; 600 601 lock(this) 602 { 603 checkForDeactivation(); 604 if(_routerInfo != null) 605 { 606 throw new ArgumentException( 607 "can't set published endpoints on object adapter associated with a router"); 608 } 609 610 oldPublishedEndpoints = _publishedEndpoints; 611 _publishedEndpoints = Array.ConvertAll(newEndpoints, endpt => (EndpointI)endpt); 612 locatorInfo = _locatorInfo; 613 } 614 615 try 616 { 617 Identity dummy = new Identity(); 618 dummy.name = "dummy"; 619 updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); 620 } 621 catch(LocalException) 622 { 623 lock(this) 624 { 625 // 626 // Restore the old published endpoints. 627 // 628 _publishedEndpoints = oldPublishedEndpoints; 629 throw; 630 } 631 } 632 } 633 isLocal(ObjectPrx proxy)634 public bool isLocal(ObjectPrx proxy) 635 { 636 // 637 // NOTE: it's important that isLocal() doesn't perform any blocking operations as 638 // it can be called for AMI invocations if the proxy has no delegate set yet. 639 // 640 641 Reference r = ((ObjectPrxHelperBase)proxy).iceReference(); 642 if(r.isWellKnown()) 643 { 644 // 645 // Check the active servant map to see if the well-known 646 // proxy is for a local object. 647 // 648 return _servantManager.hasServant(r.getIdentity()); 649 } 650 else if(r.isIndirect()) 651 { 652 // 653 // Proxy is local if the reference adapter id matches this 654 // adapter id or replica group id. 655 // 656 return r.getAdapterId().Equals(_id) || r.getAdapterId().Equals(_replicaGroupId); 657 } 658 else 659 { 660 EndpointI[] endpoints = r.getEndpoints(); 661 662 lock(this) 663 { 664 checkForDeactivation(); 665 666 // 667 // Proxies which have at least one endpoint in common with the 668 // endpoints used by this object adapter's incoming connection 669 // factories are considered local. 670 // 671 for(int i = 0; i < endpoints.Length; ++i) 672 { 673 foreach(EndpointI endpoint in _publishedEndpoints) 674 { 675 if(endpoints[i].equivalent(endpoint)) 676 { 677 return true; 678 } 679 } 680 foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) 681 { 682 if(factory.isLocal(endpoints[i])) 683 { 684 return true; 685 } 686 } 687 } 688 return false; 689 } 690 } 691 } 692 flushAsyncBatchRequests(Ice.CompressBatch compressBatch, CommunicatorFlushBatchAsync outAsync)693 public void flushAsyncBatchRequests(Ice.CompressBatch compressBatch, CommunicatorFlushBatchAsync outAsync) 694 { 695 List<IncomingConnectionFactory> f; 696 lock(this) 697 { 698 f = new List<IncomingConnectionFactory>(_incomingConnectionFactories); 699 } 700 701 foreach(IncomingConnectionFactory factory in f) 702 { 703 factory.flushAsyncBatchRequests(compressBatch, outAsync); 704 } 705 } 706 updateConnectionObservers()707 public void updateConnectionObservers() 708 { 709 List<IncomingConnectionFactory> f; 710 lock(this) 711 { 712 f = new List<IncomingConnectionFactory>(_incomingConnectionFactories); 713 } 714 715 foreach(IncomingConnectionFactory p in f) 716 { 717 p.updateConnectionObservers(); 718 } 719 } 720 updateThreadObservers()721 public void updateThreadObservers() 722 { 723 ThreadPool threadPool = null; 724 lock(this) 725 { 726 threadPool = _threadPool; 727 } 728 729 if(threadPool != null) 730 { 731 threadPool.updateObservers(); 732 } 733 } 734 incDirectCount()735 public void incDirectCount() 736 { 737 lock(this) 738 { 739 checkForDeactivation(); 740 741 Debug.Assert(_directCount >= 0); 742 ++_directCount; 743 } 744 } 745 decDirectCount()746 public void decDirectCount() 747 { 748 lock(this) 749 { 750 // Not check for deactivation here! 751 752 Debug.Assert(_instance != null); // Must not be called after destroy(). 753 754 Debug.Assert(_directCount > 0); 755 if(--_directCount == 0) 756 { 757 System.Threading.Monitor.PulseAll(this); 758 } 759 } 760 } 761 getThreadPool()762 public ThreadPool getThreadPool() 763 { 764 // No mutex lock necessary, _threadPool and _instance are 765 // immutable after creation until they are removed in 766 // destroy(). 767 768 // Not check for deactivation here! 769 770 Debug.Assert(_instance != null); // Must not be called after destroy(). 771 772 if(_threadPool != null) 773 { 774 return _threadPool; 775 } 776 else 777 { 778 return _instance.serverThreadPool(); 779 } 780 781 } 782 getServantManager()783 public ServantManager getServantManager() 784 { 785 // 786 // No mutex lock necessary, _servantManager is immutable. 787 // 788 return _servantManager; 789 } 790 getACM()791 public ACMConfig getACM() 792 { 793 // Not check for deactivation here! 794 795 Debug.Assert(_instance != null); // Must not be called after destroy(). 796 return _acm; 797 } 798 setAdapterOnConnection(Ice.ConnectionI connection)799 public void setAdapterOnConnection(Ice.ConnectionI connection) 800 { 801 lock(this) 802 { 803 checkForDeactivation(); 804 connection.setAdapterAndServantManager(this, _servantManager); 805 } 806 } 807 messageSizeMax()808 public int messageSizeMax() 809 { 810 // No mutex lock, immutable. 811 return _messageSizeMax; 812 } 813 814 // 815 // Only for use by ObjectAdapterFactory 816 // ObjectAdapterI(Instance instance, Communicator communicator, ObjectAdapterFactory objectAdapterFactory, string name, RouterPrx router, bool noConfig)817 public ObjectAdapterI(Instance instance, Communicator communicator, 818 ObjectAdapterFactory objectAdapterFactory, string name, 819 RouterPrx router, bool noConfig) 820 { 821 _instance = instance; 822 _communicator = communicator; 823 _objectAdapterFactory = objectAdapterFactory; 824 _servantManager = new ServantManager(instance, name); 825 _name = name; 826 _incomingConnectionFactories = new List<IncomingConnectionFactory>(); 827 _publishedEndpoints = new EndpointI[0]; 828 _routerInfo = null; 829 _directCount = 0; 830 _noConfig = noConfig; 831 832 if(_noConfig) 833 { 834 _id = ""; 835 _replicaGroupId = ""; 836 _reference = _instance.referenceFactory().create("dummy -t", ""); 837 _acm = _instance.serverACM(); 838 return; 839 } 840 841 Properties properties = _instance.initializationData().properties; 842 List<string> unknownProps = new List<string>(); 843 bool noProps = filterProperties(unknownProps); 844 845 // 846 // Warn about unknown object adapter properties. 847 // 848 if(unknownProps.Count != 0 && properties.getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0) 849 { 850 StringBuilder message = new StringBuilder("found unknown properties for object adapter `"); 851 message.Append(_name); 852 message.Append("':"); 853 foreach(string s in unknownProps) 854 { 855 message.Append("\n "); 856 message.Append(s); 857 } 858 _instance.initializationData().logger.warning(message.ToString()); 859 } 860 861 // 862 // Make sure named adapter has configuration. 863 // 864 if(router == null && noProps) 865 { 866 // 867 // These need to be set to prevent warnings/asserts in the destructor. 868 // 869 _state = StateDestroyed; 870 _instance = null; 871 _incomingConnectionFactories = null; 872 873 InitializationException ex = new InitializationException(); 874 ex.reason = "object adapter `" + _name + "' requires configuration"; 875 throw ex; 876 } 877 878 _id = properties.getProperty(_name + ".AdapterId"); 879 _replicaGroupId = properties.getProperty(_name + ".ReplicaGroupId"); 880 881 // 882 // Setup a reference to be used to get the default proxy options 883 // when creating new proxies. By default, create twoway proxies. 884 // 885 string proxyOptions = properties.getPropertyWithDefault(_name + ".ProxyOptions", "-t"); 886 try 887 { 888 _reference = _instance.referenceFactory().create("dummy " + proxyOptions, ""); 889 } 890 catch(ProxyParseException) 891 { 892 InitializationException ex = new InitializationException(); 893 ex.reason = "invalid proxy options `" + proxyOptions + "' for object adapter `" + _name + "'"; 894 throw ex; 895 } 896 897 _acm = new ACMConfig(properties, communicator.getLogger(), _name + ".ACM", _instance.serverACM()); 898 899 { 900 int defaultMessageSizeMax = instance.messageSizeMax() / 1024; 901 int num = properties.getPropertyAsIntWithDefault(_name + ".MessageSizeMax", defaultMessageSizeMax); 902 if(num < 1 || num > 0x7fffffff / 1024) 903 { 904 _messageSizeMax = 0x7fffffff; 905 } 906 else 907 { 908 _messageSizeMax = num * 1024; // Property is in kilobytes, _messageSizeMax in bytes 909 } 910 } 911 912 try 913 { 914 int threadPoolSize = properties.getPropertyAsInt(_name + ".ThreadPool.Size"); 915 int threadPoolSizeMax = properties.getPropertyAsInt(_name + ".ThreadPool.SizeMax"); 916 if(threadPoolSize > 0 || threadPoolSizeMax > 0) 917 { 918 _threadPool = new ThreadPool(_instance, _name + ".ThreadPool", 0); 919 } 920 921 if(router == null) 922 { 923 router = RouterPrxHelper.uncheckedCast(_instance.proxyFactory().propertyToProxy(_name + ".Router")); 924 } 925 if(router != null) 926 { 927 _routerInfo = _instance.routerManager().get(router); 928 Debug.Assert(_routerInfo != null); 929 930 // 931 // Make sure this router is not already registered with another adapter. 932 // 933 if(_routerInfo.getAdapter() != null) 934 { 935 AlreadyRegisteredException ex = new AlreadyRegisteredException(); 936 ex.kindOfObject = "object adapter with router"; 937 ex.id = Util.identityToString(router.ice_getIdentity(), _instance.toStringMode()); 938 throw ex; 939 } 940 941 // 942 // Associate this object adapter with the router. This way, 943 // new outgoing connections to the router's client proxy will 944 // use this object adapter for callbacks. 945 // 946 _routerInfo.setAdapter(this); 947 948 // 949 // Also modify all existing outgoing connections to the 950 // router's client proxy to use this object adapter for 951 // callbacks. 952 // 953 _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo); 954 } 955 else 956 { 957 // 958 // Parse the endpoints, but don't store them in the adapter. The connection 959 // factory might change it, for example, to fill in the real port number. 960 // 961 List<EndpointI> endpoints = parseEndpoints(properties.getProperty(_name + ".Endpoints"), true); 962 foreach(EndpointI endp in endpoints) 963 { 964 EndpointI publishedEndpoint; 965 foreach(IceInternal.EndpointI expanded in endp.expandHost(out publishedEndpoint)) 966 { 967 IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, 968 expanded, 969 publishedEndpoint, 970 this); 971 _incomingConnectionFactories.Add(factory); 972 } 973 } 974 if(endpoints.Count == 0) 975 { 976 TraceLevels tl = _instance.traceLevels(); 977 if(tl.network >= 2) 978 { 979 _instance.initializationData().logger.trace(tl.networkCat, "created adapter `" + _name + 980 "' without endpoints"); 981 } 982 } 983 } 984 985 // 986 // Parse published endpoints. 987 // 988 _publishedEndpoints = computePublishedEndpoints(); 989 990 if(properties.getProperty(_name + ".Locator").Length > 0) 991 { 992 setLocator(LocatorPrxHelper.uncheckedCast( 993 _instance.proxyFactory().propertyToProxy(_name + ".Locator"))); 994 } 995 else 996 { 997 setLocator(_instance.referenceFactory().getDefaultLocator()); 998 } 999 } 1000 catch(LocalException) 1001 { 1002 destroy(); 1003 throw; 1004 } 1005 } 1006 newProxy(Identity ident, string facet)1007 private ObjectPrx newProxy(Identity ident, string facet) 1008 { 1009 if(_id.Length == 0) 1010 { 1011 return newDirectProxy(ident, facet); 1012 } 1013 else if(_replicaGroupId.Length == 0) 1014 { 1015 return newIndirectProxy(ident, facet, _id); 1016 } 1017 else 1018 { 1019 return newIndirectProxy(ident, facet, _replicaGroupId); 1020 } 1021 } 1022 newDirectProxy(Identity ident, string facet)1023 private ObjectPrx newDirectProxy(Identity ident, string facet) 1024 { 1025 // 1026 // Create a reference and return a proxy for this reference. 1027 // 1028 Reference reference = _instance.referenceFactory().create(ident, facet, _reference, _publishedEndpoints); 1029 return _instance.proxyFactory().referenceToProxy(reference); 1030 } 1031 newIndirectProxy(Identity ident, string facet, string id)1032 private ObjectPrx newIndirectProxy(Identity ident, string facet, string id) 1033 { 1034 // 1035 // Create a reference with the adapter id and return a 1036 // proxy for the reference. 1037 // 1038 Reference reference = _instance.referenceFactory().create(ident, facet, _reference, id); 1039 return _instance.proxyFactory().referenceToProxy(reference); 1040 } 1041 checkForDeactivation()1042 private void checkForDeactivation() 1043 { 1044 if(_state >= StateDeactivating) 1045 { 1046 ObjectAdapterDeactivatedException ex = new ObjectAdapterDeactivatedException(); 1047 ex.name = getName(); 1048 throw ex; 1049 } 1050 } 1051 checkIdentity(Identity ident)1052 private static void checkIdentity(Identity ident) 1053 { 1054 if(ident.name == null || ident.name.Length == 0) 1055 { 1056 throw new IllegalIdentityException(ident); 1057 } 1058 if(ident.category == null) 1059 { 1060 ident.category = ""; 1061 } 1062 } 1063 checkServant(Object servant)1064 private static void checkServant(Object servant) 1065 { 1066 if(servant == null) 1067 { 1068 throw new IllegalServantException("cannot add null servant to Object Adapter"); 1069 } 1070 } 1071 parseEndpoints(string endpts, bool oaEndpoints)1072 private List<EndpointI> parseEndpoints(string endpts, bool oaEndpoints) 1073 { 1074 int beg; 1075 int end = 0; 1076 1077 string delim = " \t\n\r"; 1078 1079 List<EndpointI> endpoints = new List<EndpointI>(); 1080 while(end < endpts.Length) 1081 { 1082 beg = IceUtilInternal.StringUtil.findFirstNotOf(endpts, delim, end); 1083 if(beg == -1) 1084 { 1085 if(endpoints.Count != 0) 1086 { 1087 throw new EndpointParseException("invalid empty object adapter endpoint"); 1088 } 1089 break; 1090 } 1091 1092 end = beg; 1093 while(true) 1094 { 1095 end = endpts.IndexOf(':', end); 1096 if(end == -1) 1097 { 1098 end = endpts.Length; 1099 break; 1100 } 1101 else 1102 { 1103 bool quoted = false; 1104 int quote = beg; 1105 while(true) 1106 { 1107 quote = endpts.IndexOf('\"', quote); 1108 if(quote == -1 || end < quote) 1109 { 1110 break; 1111 } 1112 else 1113 { 1114 quote = endpts.IndexOf('\"', ++quote); 1115 if(quote == -1) 1116 { 1117 break; 1118 } 1119 else if(end < quote) 1120 { 1121 quoted = true; 1122 break; 1123 } 1124 ++quote; 1125 } 1126 } 1127 if(!quoted) 1128 { 1129 break; 1130 } 1131 ++end; 1132 } 1133 } 1134 1135 if(end == beg) 1136 { 1137 throw new EndpointParseException("invalid empty object adapter endpoint"); 1138 } 1139 1140 string s = endpts.Substring(beg, (end) - (beg)); 1141 EndpointI endp = _instance.endpointFactoryManager().create(s, oaEndpoints); 1142 if(endp == null) 1143 { 1144 throw new EndpointParseException("invalid object adapter endpoint `" + s + "'"); 1145 } 1146 endpoints.Add(endp); 1147 1148 ++end; 1149 } 1150 1151 return endpoints; 1152 } 1153 computePublishedEndpoints()1154 private EndpointI[] computePublishedEndpoints() 1155 { 1156 List<EndpointI> endpoints; 1157 if(_routerInfo != null) 1158 { 1159 // 1160 // Get the router's server proxy endpoints and use them as the published endpoints. 1161 // 1162 endpoints = new List<EndpointI>(); 1163 foreach(EndpointI endpt in _routerInfo.getServerEndpoints()) 1164 { 1165 if(!endpoints.Contains(endpt)) 1166 { 1167 endpoints.Add(endpt); 1168 } 1169 } 1170 } 1171 else 1172 { 1173 // 1174 // Parse published endpoints. If set, these are used in proxies 1175 // instead of the connection factory endpoints. 1176 // 1177 string endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints"); 1178 endpoints = parseEndpoints(endpts, false); 1179 if(endpoints.Count == 0) 1180 { 1181 // 1182 // If the PublishedEndpoints property isn't set, we compute the published enpdoints 1183 // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY 1184 // to include actual addresses in the published endpoints. 1185 // 1186 foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) 1187 { 1188 foreach(EndpointI endpt in factory.endpoint().expandIfWildcard()) 1189 { 1190 // 1191 // Check for duplicate endpoints, this might occur if an endpoint with a DNS name 1192 // expands to multiple addresses. In this case, multiple incoming connection 1193 // factories can point to the same published endpoint. 1194 // 1195 if(!endpoints.Contains(endpt)) 1196 { 1197 endpoints.Add(endpt); 1198 } 1199 } 1200 } 1201 } 1202 } 1203 1204 if(_instance.traceLevels().network >= 1 && endpoints.Count > 0) 1205 { 1206 StringBuilder s = new StringBuilder("published endpoints for object adapter `"); 1207 s.Append(_name); 1208 s.Append("':\n"); 1209 bool first = true; 1210 foreach(EndpointI endpoint in endpoints) 1211 { 1212 if(!first) 1213 { 1214 s.Append(":"); 1215 } 1216 s.Append(endpoint.ToString()); 1217 first = false; 1218 } 1219 _instance.initializationData().logger.trace(_instance.traceLevels().networkCat, s.ToString()); 1220 } 1221 1222 return endpoints.ToArray(); 1223 } 1224 updateLocatorRegistry(LocatorInfo locatorInfo, ObjectPrx proxy)1225 private void updateLocatorRegistry(LocatorInfo locatorInfo, ObjectPrx proxy) 1226 { 1227 if(_id.Length == 0 || locatorInfo == null) 1228 { 1229 return; // Nothing to update. 1230 } 1231 1232 // 1233 // Call on the locator registry outside the synchronization to 1234 // blocking other threads that need to lock this OA. 1235 // 1236 LocatorRegistryPrx locatorRegistry = locatorInfo.getLocatorRegistry(); 1237 if(locatorRegistry == null) 1238 { 1239 return; 1240 } 1241 1242 try 1243 { 1244 if(_replicaGroupId.Length == 0) 1245 { 1246 locatorRegistry.setAdapterDirectProxy(_id, proxy); 1247 } 1248 else 1249 { 1250 locatorRegistry.setReplicatedAdapterDirectProxy(_id, _replicaGroupId, proxy); 1251 } 1252 } 1253 catch(AdapterNotFoundException) 1254 { 1255 if(_instance.traceLevels().location >= 1) 1256 { 1257 StringBuilder s = new StringBuilder(); 1258 s.Append("couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"); 1259 s.Append("the object adapter is not known to the locator registry"); 1260 _instance.initializationData().logger.trace(_instance.traceLevels().locationCat, s.ToString()); 1261 } 1262 1263 NotRegisteredException ex1 = new NotRegisteredException(); 1264 ex1.kindOfObject = "object adapter"; 1265 ex1.id = _id; 1266 throw ex1; 1267 } 1268 catch(InvalidReplicaGroupIdException) 1269 { 1270 if(_instance.traceLevels().location >= 1) 1271 { 1272 StringBuilder s = new StringBuilder(); 1273 s.Append("couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"); 1274 s.Append("the replica group `" + _replicaGroupId + "' is not known to the locator registry"); 1275 _instance.initializationData().logger.trace(_instance.traceLevels().locationCat, s.ToString()); 1276 } 1277 1278 NotRegisteredException ex1 = new NotRegisteredException(); 1279 ex1.kindOfObject = "replica group"; 1280 ex1.id = _replicaGroupId; 1281 throw ex1; 1282 } 1283 catch(AdapterAlreadyActiveException) 1284 { 1285 if(_instance.traceLevels().location >= 1) 1286 { 1287 StringBuilder s = new StringBuilder(); 1288 s.Append("couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"); 1289 s.Append("the object adapter endpoints are already set"); 1290 _instance.initializationData().logger.trace(_instance.traceLevels().locationCat, s.ToString()); 1291 } 1292 1293 ObjectAdapterIdInUseException ex1 = new ObjectAdapterIdInUseException(); 1294 ex1.id = _id; 1295 throw; 1296 } 1297 catch(ObjectAdapterDeactivatedException) 1298 { 1299 // Expected if collocated call and OA is deactivated, ignore. 1300 } 1301 catch(CommunicatorDestroyedException) 1302 { 1303 // Ignore 1304 } 1305 catch(LocalException e) 1306 { 1307 if(_instance.traceLevels().location >= 1) 1308 { 1309 StringBuilder s = new StringBuilder(); 1310 s.Append("couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"); 1311 s.Append(e.ToString()); 1312 _instance.initializationData().logger.trace(_instance.traceLevels().locationCat, s.ToString()); 1313 } 1314 throw; // TODO: Shall we raise a special exception instead of a non obvious local exception? 1315 } 1316 1317 if(_instance.traceLevels().location >= 1) 1318 { 1319 StringBuilder s = new StringBuilder(); 1320 s.Append("updated object adapter `" + _id + "' endpoints with the locator registry\n"); 1321 s.Append("endpoints = "); 1322 if(proxy != null) 1323 { 1324 Endpoint[] endpoints = proxy.ice_getEndpoints(); 1325 for(int i = 0; i < endpoints.Length; i++) 1326 { 1327 s.Append(endpoints[i].ToString()); 1328 if(i + 1 < endpoints.Length) 1329 { 1330 s.Append(":"); 1331 } 1332 } 1333 } 1334 _instance.initializationData().logger.trace(_instance.traceLevels().locationCat, s.ToString()); 1335 } 1336 } 1337 1338 static private readonly string[] _suffixes = 1339 { 1340 "ACM", 1341 "ACM.Timeout", 1342 "ACM.Heartbeat", 1343 "ACM.Close", 1344 "AdapterId", 1345 "Endpoints", 1346 "Locator", 1347 "Locator.EncodingVersion", 1348 "Locator.EndpointSelection", 1349 "Locator.ConnectionCached", 1350 "Locator.PreferSecure", 1351 "Locator.CollocationOptimized", 1352 "Locator.Router", 1353 "MessageSizeMax", 1354 "PublishedEndpoints", 1355 "ReplicaGroupId", 1356 "Router", 1357 "Router.EncodingVersion", 1358 "Router.EndpointSelection", 1359 "Router.ConnectionCached", 1360 "Router.PreferSecure", 1361 "Router.CollocationOptimized", 1362 "Router.Locator", 1363 "Router.Locator.EndpointSelection", 1364 "Router.Locator.ConnectionCached", 1365 "Router.Locator.PreferSecure", 1366 "Router.Locator.CollocationOptimized", 1367 "Router.Locator.LocatorCacheTimeout", 1368 "Router.Locator.InvocationTimeout", 1369 "Router.LocatorCacheTimeout", 1370 "Router.InvocationTimeout", 1371 "ProxyOptions", 1372 "ThreadPool.Size", 1373 "ThreadPool.SizeMax", 1374 "ThreadPool.SizeWarn", 1375 "ThreadPool.StackSize", 1376 "ThreadPool.Serialize" 1377 }; 1378 filterProperties(List<string> unknownProps)1379 private bool filterProperties(List<string> unknownProps) 1380 { 1381 // 1382 // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc 1383 // 1384 bool addUnknown = true; 1385 string prefix = _name + "."; 1386 for(int i = 0; PropertyNames.clPropNames[i] != null; ++i) 1387 { 1388 if(prefix.StartsWith(PropertyNames.clPropNames[i] + ".", StringComparison.Ordinal)) 1389 { 1390 addUnknown = false; 1391 break; 1392 } 1393 } 1394 1395 bool noProps = true; 1396 Dictionary<string, string> props = 1397 _instance.initializationData().properties.getPropertiesForPrefix(prefix); 1398 foreach(string prop in props.Keys) 1399 { 1400 bool valid = false; 1401 for(int i = 0; i < _suffixes.Length; ++i) 1402 { 1403 if(prop.Equals(prefix + _suffixes[i])) 1404 { 1405 noProps = false; 1406 valid = true; 1407 break; 1408 } 1409 } 1410 1411 if(!valid && addUnknown) 1412 { 1413 unknownProps.Add(prop); 1414 } 1415 } 1416 1417 return noProps; 1418 } 1419 1420 private const int StateUninitialized = 0; // Just constructed. 1421 private const int StateHeld = 1; 1422 private const int StateActivating = 2; 1423 private const int StateActive = 3; 1424 private const int StateDeactivating = 4; 1425 private const int StateDeactivated = 5; 1426 private const int StateDestroying = 6; 1427 private const int StateDestroyed = 7; 1428 1429 private int _state = StateUninitialized; 1430 private Instance _instance; 1431 private Communicator _communicator; 1432 private ObjectAdapterFactory _objectAdapterFactory; 1433 private ThreadPool _threadPool; 1434 private ACMConfig _acm; 1435 private ServantManager _servantManager; 1436 private readonly string _name; 1437 private readonly string _id; 1438 private readonly string _replicaGroupId; 1439 private Reference _reference; 1440 private List<IncomingConnectionFactory> _incomingConnectionFactories; 1441 private RouterInfo _routerInfo; 1442 private EndpointI[] _publishedEndpoints; 1443 private LocatorInfo _locatorInfo; 1444 private int _directCount; // The number of direct proxies dispatching on this object adapter. 1445 private bool _noConfig; 1446 private int _messageSizeMax; 1447 } 1448 } 1449