1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 package IceInternal; 6 7 public final class LocatorInfo 8 { 9 interface GetEndpointsCallback 10 { setEndpoints(EndpointI[] endpoints, boolean cached)11 void setEndpoints(EndpointI[] endpoints, boolean cached); setException(Ice.LocalException ex)12 void setException(Ice.LocalException ex); 13 } 14 15 private static class RequestCallback 16 { 17 public void response(LocatorInfo locatorInfo, Ice.ObjectPrx proxy)18 response(LocatorInfo locatorInfo, Ice.ObjectPrx proxy) 19 { 20 EndpointI[] endpoints = null; 21 if(proxy != null) 22 { 23 Reference r = ((Ice.ObjectPrxHelperBase)proxy)._getReference(); 24 if(_ref.isWellKnown() && !Protocol.isSupported(_ref.getEncoding(), r.getEncoding())) 25 { 26 // 27 // If a well-known proxy and the returned proxy 28 // encoding isn't supported, we're done: there's 29 // no compatible endpoint we can use. 30 // 31 } 32 else if(!r.isIndirect()) 33 { 34 endpoints = r.getEndpoints(); 35 } 36 else if(_ref.isWellKnown() && !r.isWellKnown()) 37 { 38 // 39 // We're resolving the endpoints of a well-known object and the proxy returned 40 // by the locator is an indirect proxy. We now need to resolve the endpoints 41 // of this indirect proxy. 42 // 43 if(_ref.getInstance().traceLevels().location >= 1) 44 { 45 locatorInfo.trace("retrieved adapter for well-known object from locator, " + 46 "adding to locator cache", _ref, r); 47 } 48 locatorInfo.getEndpoints(r, _ref, _ttl, _callback); 49 return; 50 } 51 } 52 53 if(_ref.getInstance().traceLevels().location >= 1) 54 { 55 locatorInfo.getEndpointsTrace(_ref, endpoints, false); 56 } 57 if(_callback != null) 58 { 59 _callback.setEndpoints(endpoints == null ? new EndpointI[0] : endpoints, false); 60 } 61 } 62 63 public void exception(LocatorInfo locatorInfo, Exception exc)64 exception(LocatorInfo locatorInfo, Exception exc) 65 { 66 try 67 { 68 locatorInfo.getEndpointsException(_ref, exc); // This throws. 69 } 70 catch(Ice.LocalException ex) 71 { 72 if(_callback != null) 73 { 74 _callback.setException(ex); 75 } 76 } 77 } 78 RequestCallback(Reference ref, int ttl, GetEndpointsCallback cb)79 RequestCallback(Reference ref, int ttl, GetEndpointsCallback cb) 80 { 81 _ref = ref; 82 _ttl = ttl; 83 _callback = cb; 84 } 85 86 final Reference _ref; 87 final int _ttl; 88 final GetEndpointsCallback _callback; 89 } 90 91 private abstract class Request 92 { 93 public void addCallback(Reference ref, Reference wellKnownRef, int ttl, GetEndpointsCallback cb)94 addCallback(Reference ref, Reference wellKnownRef, int ttl, GetEndpointsCallback cb) 95 { 96 RequestCallback callback = new RequestCallback(ref, ttl, cb); 97 synchronized(this) 98 { 99 if(!_response && _exception == null) 100 { 101 _callbacks.add(callback); 102 if(wellKnownRef != null) // This request is to resolve the endpoints of a cached well-known object ref 103 { 104 _wellKnownRefs.add(wellKnownRef); 105 } 106 if(!_sent) 107 { 108 _sent = true; 109 send(); 110 } 111 return; 112 } 113 } 114 115 if(_response) 116 { 117 callback.response(_locatorInfo, _proxy); 118 } 119 else 120 { 121 assert(_exception != null); 122 callback.exception(_locatorInfo, _exception); 123 } 124 } 125 Request(LocatorInfo locatorInfo, Reference ref)126 Request(LocatorInfo locatorInfo, Reference ref) 127 { 128 _locatorInfo = locatorInfo; 129 _ref = ref; 130 _sent = false; 131 _response = false; 132 } 133 134 protected void response(Ice.ObjectPrx proxy)135 response(Ice.ObjectPrx proxy) 136 { 137 synchronized(this) 138 { 139 _locatorInfo.finishRequest(_ref, _wellKnownRefs, proxy, false); 140 _response = true; 141 _proxy = proxy; 142 notifyAll(); 143 } 144 for(RequestCallback callback : _callbacks) 145 { 146 callback.response(_locatorInfo, proxy); 147 } 148 } 149 150 protected void exception(Exception ex)151 exception(Exception ex) 152 { 153 synchronized(this) 154 { 155 _locatorInfo.finishRequest(_ref, _wellKnownRefs, null, ex instanceof Ice.UserException); 156 _exception = ex; 157 notifyAll(); 158 } 159 for(RequestCallback callback : _callbacks) 160 { 161 callback.exception(_locatorInfo, ex); 162 } 163 } 164 send()165 protected abstract void send(); 166 167 final protected LocatorInfo _locatorInfo; 168 final protected Reference _ref; 169 170 private java.util.List<RequestCallback> _callbacks = new java.util.ArrayList<RequestCallback>(); 171 private java.util.List<Reference> _wellKnownRefs = new java.util.ArrayList<Reference>(); 172 private boolean _sent; 173 private boolean _response; 174 private Ice.ObjectPrx _proxy; 175 private Exception _exception; 176 } 177 178 private class ObjectRequest extends Request 179 { ObjectRequest(LocatorInfo locatorInfo, Reference reference)180 public ObjectRequest(LocatorInfo locatorInfo, Reference reference) 181 { 182 super(locatorInfo, reference); 183 assert(reference.isWellKnown()); 184 } 185 186 @Override 187 protected void send()188 send() 189 { 190 try 191 { 192 _locatorInfo.getLocator().begin_findObjectById( 193 _ref.getIdentity(), 194 new Ice.Callback_Locator_findObjectById() 195 { 196 @Override 197 public void 198 response(Ice.ObjectPrx proxy) 199 { 200 ObjectRequest.this.response(proxy); 201 } 202 203 @Override 204 public void 205 exception(Ice.UserException ex) 206 { 207 ObjectRequest.this.exception(ex); 208 } 209 210 @Override 211 public void 212 exception(Ice.LocalException ex) 213 { 214 ObjectRequest.this.exception(ex); 215 } 216 }); 217 } 218 catch(Exception ex) 219 { 220 exception(ex); 221 } 222 } 223 } 224 225 private class AdapterRequest extends Request 226 { AdapterRequest(LocatorInfo locatorInfo, Reference reference)227 public AdapterRequest(LocatorInfo locatorInfo, Reference reference) 228 { 229 super(locatorInfo, reference); 230 assert(reference.isIndirect()); 231 } 232 233 @Override 234 protected void send()235 send() 236 { 237 try 238 { 239 _locatorInfo.getLocator().begin_findAdapterById( 240 _ref.getAdapterId(), 241 new Ice.Callback_Locator_findAdapterById() 242 { 243 @Override 244 public void 245 response(Ice.ObjectPrx proxy) 246 { 247 AdapterRequest.this.response(proxy); 248 } 249 250 @Override 251 public void 252 exception(Ice.UserException ex) 253 { 254 AdapterRequest.this.exception(ex); 255 } 256 257 @Override 258 public void 259 exception(Ice.LocalException ex) 260 { 261 AdapterRequest.this.exception(ex); 262 } 263 }); 264 } 265 catch(Exception ex) 266 { 267 exception(ex); 268 } 269 } 270 } 271 LocatorInfo(Ice.LocatorPrx locator, LocatorTable table, boolean background)272 LocatorInfo(Ice.LocatorPrx locator, LocatorTable table, boolean background) 273 { 274 _locator = locator; 275 _table = table; 276 _background = background; 277 } 278 279 synchronized public void destroy()280 destroy() 281 { 282 _locatorRegistry = null; 283 _table.clear(); 284 } 285 286 @Override 287 public boolean equals(java.lang.Object obj)288 equals(java.lang.Object obj) 289 { 290 if(this == obj) 291 { 292 return true; 293 } 294 295 if(obj instanceof LocatorInfo) 296 { 297 return _locator.equals(((LocatorInfo)obj)._locator); 298 } 299 300 return false; 301 } 302 303 @Override 304 public int hashCode()305 hashCode() 306 { 307 return _locator.hashCode(); 308 } 309 310 public Ice.LocatorPrx getLocator()311 getLocator() 312 { 313 // 314 // No synchronization necessary, _locator is immutable. 315 // 316 return _locator; 317 } 318 319 public Ice.LocatorRegistryPrx getLocatorRegistry()320 getLocatorRegistry() 321 { 322 synchronized(this) 323 { 324 if(_locatorRegistry != null) 325 { 326 return _locatorRegistry; 327 } 328 } 329 330 // 331 // Do not make locator calls from within sync. 332 // 333 Ice.LocatorRegistryPrx locatorRegistry = _locator.getRegistry(); 334 if(locatorRegistry == null) 335 { 336 return null; 337 } 338 339 synchronized(this) 340 { 341 // 342 // The locator registry can't be located. We use ordered 343 // endpoint selection in case the locator returned a proxy 344 // with some endpoints which are prefered to be tried first. 345 // 346 _locatorRegistry = (Ice.LocatorRegistryPrx)locatorRegistry.ice_locator(null).ice_endpointSelection( 347 Ice.EndpointSelectionType.Ordered); 348 return _locatorRegistry; 349 } 350 } 351 352 public void getEndpoints(Reference ref, int ttl, GetEndpointsCallback callback)353 getEndpoints(Reference ref, int ttl, GetEndpointsCallback callback) 354 { 355 getEndpoints(ref, null, ttl, callback); 356 } 357 358 public void getEndpoints(Reference ref, Reference wellKnownRef, int ttl, GetEndpointsCallback callback)359 getEndpoints(Reference ref, Reference wellKnownRef, int ttl, GetEndpointsCallback callback) 360 { 361 assert(ref.isIndirect()); 362 EndpointI[] endpoints = null; 363 Ice.Holder<Boolean> cached = new Ice.Holder<Boolean>(); 364 if(!ref.isWellKnown()) 365 { 366 endpoints = _table.getAdapterEndpoints(ref.getAdapterId(), ttl, cached); 367 if(!cached.value) 368 { 369 if(_background && endpoints != null) 370 { 371 getAdapterRequest(ref).addCallback(ref, wellKnownRef, ttl, null); 372 } 373 else 374 { 375 getAdapterRequest(ref).addCallback(ref, wellKnownRef, ttl, callback); 376 return; 377 } 378 } 379 } 380 else 381 { 382 Reference r = _table.getObjectReference(ref.getIdentity(), ttl, cached); 383 if(!cached.value) 384 { 385 if(_background && r != null) 386 { 387 getObjectRequest(ref).addCallback(ref, null, ttl, null); 388 } 389 else 390 { 391 getObjectRequest(ref).addCallback(ref, null, ttl, callback); 392 return; 393 } 394 } 395 396 if(!r.isIndirect()) 397 { 398 endpoints = r.getEndpoints(); 399 } 400 else if(!r.isWellKnown()) 401 { 402 if(ref.getInstance().traceLevels().location >= 1) 403 { 404 trace("found adapter for well-known object in locator cache", ref, r); 405 } 406 getEndpoints(r, ref, ttl, callback); 407 return; 408 } 409 } 410 411 assert(endpoints != null); 412 if(ref.getInstance().traceLevels().location >= 1) 413 { 414 getEndpointsTrace(ref, endpoints, true); 415 } 416 if(callback != null) 417 { 418 callback.setEndpoints(endpoints, true); 419 } 420 } 421 422 public void clearCache(Reference ref)423 clearCache(Reference ref) 424 { 425 assert(ref.isIndirect()); 426 427 if(!ref.isWellKnown()) 428 { 429 EndpointI[] endpoints = _table.removeAdapterEndpoints(ref.getAdapterId()); 430 431 if(endpoints != null && ref.getInstance().traceLevels().location >= 2) 432 { 433 trace("removed endpoints for adapter from locator cache", ref, endpoints); 434 } 435 } 436 else 437 { 438 Reference r = _table.removeObjectReference(ref.getIdentity()); 439 if(r != null) 440 { 441 if(!r.isIndirect()) 442 { 443 if(ref.getInstance().traceLevels().location >= 2) 444 { 445 trace("removed endpoints for well-known object from locator cache", ref, r.getEndpoints()); 446 } 447 } 448 else if(!r.isWellKnown()) 449 { 450 if(ref.getInstance().traceLevels().location >= 2) 451 { 452 trace("removed adapter for well-known object from locator cache", ref, r); 453 } 454 clearCache(r); 455 } 456 } 457 } 458 } 459 460 private void trace(String msg, Reference ref, EndpointI[] endpoints)461 trace(String msg, Reference ref, EndpointI[] endpoints) 462 { 463 assert(ref.isIndirect()); 464 465 StringBuilder s = new StringBuilder(128); 466 s.append(msg); 467 s.append("\n"); 468 if(!ref.isWellKnown()) 469 { 470 s.append("adapter = "); 471 s.append(ref.getAdapterId()); 472 s.append("\n"); 473 } 474 else 475 { 476 s.append("well-known proxy = "); 477 s.append(ref.toString()); 478 s.append("\n"); 479 } 480 481 s.append("endpoints = "); 482 final int sz = endpoints.length; 483 for(int i = 0; i < sz; i++) 484 { 485 s.append(endpoints[i].toString()); 486 if(i + 1 < sz) 487 { 488 s.append(":"); 489 } 490 } 491 492 ref.getInstance().initializationData().logger.trace(ref.getInstance().traceLevels().locationCat, s.toString()); 493 } 494 495 private void trace(String msg, Reference ref, Reference resolved)496 trace(String msg, Reference ref, Reference resolved) 497 { 498 assert(ref.isWellKnown()); 499 500 StringBuilder s = new StringBuilder(128); 501 s.append(msg); 502 s.append("\n"); 503 s.append("well-known proxy = "); 504 s.append(ref.toString()); 505 s.append("\n"); 506 s.append("adapter = "); 507 s.append(resolved.getAdapterId()); 508 509 ref.getInstance().initializationData().logger.trace(ref.getInstance().traceLevels().locationCat, s.toString()); 510 } 511 512 private void getEndpointsException(Reference ref, Exception exc)513 getEndpointsException(Reference ref, Exception exc) 514 { 515 assert(ref.isIndirect()); 516 517 try 518 { 519 throw exc; 520 } 521 catch(Ice.AdapterNotFoundException ex) 522 { 523 final Instance instance = ref.getInstance(); 524 if(instance.traceLevels().location >= 1) 525 { 526 StringBuilder s = new StringBuilder(128); 527 s.append("adapter not found\n"); 528 s.append("adapter = "); 529 s.append(ref.getAdapterId()); 530 instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); 531 } 532 533 Ice.NotRegisteredException e = new Ice.NotRegisteredException(); 534 e.kindOfObject = "object adapter"; 535 e.id = ref.getAdapterId(); 536 throw e; 537 } 538 catch(Ice.ObjectNotFoundException ex) 539 { 540 final Instance instance = ref.getInstance(); 541 if(instance.traceLevels().location >= 1) 542 { 543 StringBuilder s = new StringBuilder(128); 544 s.append("object not found\n"); 545 s.append("object = "); 546 s.append(Ice.Util.identityToString(ref.getIdentity(), instance.toStringMode())); 547 instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); 548 } 549 550 Ice.NotRegisteredException e = new Ice.NotRegisteredException(); 551 e.kindOfObject = "object"; 552 e.id = Ice.Util.identityToString(ref.getIdentity(), instance.toStringMode()); 553 throw e; 554 } 555 catch(Ice.NotRegisteredException ex) 556 { 557 throw ex; 558 } 559 catch(Ice.LocalException ex) 560 { 561 final Instance instance = ref.getInstance(); 562 if(instance.traceLevels().location >= 1) 563 { 564 StringBuilder s = new StringBuilder(128); 565 s.append("couldn't contact the locator to retrieve endpoints\n"); 566 if(ref.getAdapterId().length() > 0) 567 { 568 s.append("adapter = "); 569 s.append(ref.getAdapterId()); 570 s.append("\n"); 571 } 572 else 573 { 574 s.append("well-known proxy = "); 575 s.append(ref.toString()); 576 s.append("\n"); 577 } 578 s.append("reason = " + ex); 579 instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); 580 } 581 throw ex; 582 } 583 catch(Exception ex) 584 { 585 assert(false); 586 } 587 } 588 589 private void getEndpointsTrace(Reference ref, EndpointI[] endpoints, boolean cached)590 getEndpointsTrace(Reference ref, EndpointI[] endpoints, boolean cached) 591 { 592 if(endpoints != null && endpoints.length > 0) 593 { 594 if(cached) 595 { 596 if(ref.isWellKnown()) 597 { 598 trace("found endpoints for well-known proxy in locator cache", ref, endpoints); 599 } 600 else 601 { 602 trace("found endpoints for adapter in locator cache", ref, endpoints); 603 } 604 } 605 else 606 { 607 if(ref.isWellKnown()) 608 { 609 trace("retrieved endpoints for well-known proxy from locator, adding to locator cache", 610 ref, endpoints); 611 } 612 else 613 { 614 trace("retrieved endpoints for adapter from locator, adding to locator cache", 615 ref, endpoints); 616 } 617 } 618 } 619 else 620 { 621 final Instance instance = ref.getInstance(); 622 StringBuilder s = new StringBuilder(128); 623 s.append("no endpoints configured for "); 624 if(ref.getAdapterId().length() > 0) 625 { 626 s.append("adapter\n"); 627 s.append("adapter = "); 628 s.append(ref.getAdapterId()); 629 s.append("\n"); 630 } 631 else 632 { 633 s.append("well-known object\n"); 634 s.append("well-known proxy = "); 635 s.append(ref.toString()); 636 s.append("\n"); 637 } 638 instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); 639 } 640 } 641 642 synchronized private Request getAdapterRequest(Reference ref)643 getAdapterRequest(Reference ref) 644 { 645 if(ref.getInstance().traceLevels().location >= 1) 646 { 647 Instance instance = ref.getInstance(); 648 StringBuilder s = new StringBuilder(128); 649 s.append("searching for adapter by id\n"); 650 s.append("adapter = "); 651 s.append(ref.getAdapterId()); 652 instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); 653 } 654 655 Request request = _adapterRequests.get(ref.getAdapterId()); 656 if(request != null) 657 { 658 return request; 659 } 660 request = new AdapterRequest(this, ref); 661 _adapterRequests.put(ref.getAdapterId(), request); 662 return request; 663 } 664 665 synchronized private Request getObjectRequest(Reference ref)666 getObjectRequest(Reference ref) 667 { 668 if(ref.getInstance().traceLevels().location >= 1) 669 { 670 Instance instance = ref.getInstance(); 671 StringBuilder s = new StringBuilder(128); 672 s.append("searching for well-known object\n"); 673 s.append("well-known proxy = "); 674 s.append(ref.toString()); 675 instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); 676 } 677 678 Request request = _objectRequests.get(ref.getIdentity()); 679 if(request != null) 680 { 681 return request; 682 } 683 request = new ObjectRequest(this, ref); 684 _objectRequests.put(ref.getIdentity(), request); 685 return request; 686 } 687 688 private void finishRequest(Reference ref, java.util.List<Reference> wellKnownRefs, Ice.ObjectPrx proxy, boolean notRegistered)689 finishRequest(Reference ref, java.util.List<Reference> wellKnownRefs, Ice.ObjectPrx proxy, boolean notRegistered) 690 { 691 if(proxy == null || ((Ice.ObjectPrxHelperBase)proxy)._getReference().isIndirect()) 692 { 693 // 694 // Remove the cached references of well-known objects for which we tried 695 // to resolved the endpoints if these endpoints are empty. 696 // 697 for(Reference r : wellKnownRefs) 698 { 699 _table.removeObjectReference(r.getIdentity()); 700 } 701 } 702 703 if(!ref.isWellKnown()) 704 { 705 if(proxy != null && !((Ice.ObjectPrxHelperBase)proxy)._getReference().isIndirect()) 706 { 707 // Cache the adapter endpoints. 708 _table.addAdapterEndpoints(ref.getAdapterId(), 709 ((Ice.ObjectPrxHelperBase)proxy)._getReference().getEndpoints()); 710 } 711 else if(notRegistered) // If the adapter isn't registered anymore, remove it from the cache. 712 { 713 _table.removeAdapterEndpoints(ref.getAdapterId()); 714 } 715 716 synchronized(this) 717 { 718 assert(_adapterRequests.get(ref.getAdapterId()) != null); 719 _adapterRequests.remove(ref.getAdapterId()); 720 } 721 } 722 else 723 { 724 if(proxy != null && !((Ice.ObjectPrxHelperBase)proxy)._getReference().isWellKnown()) 725 { 726 // Cache the well-known object reference. 727 _table.addObjectReference(ref.getIdentity(), ((Ice.ObjectPrxHelperBase)proxy)._getReference()); 728 } 729 else if(notRegistered) // If the well-known object isn't registered anymore, remove it from the cache. 730 { 731 _table.removeObjectReference(ref.getIdentity()); 732 } 733 734 synchronized(this) 735 { 736 assert(_objectRequests.get(ref.getIdentity()) != null); 737 _objectRequests.remove(ref.getIdentity()); 738 } 739 } 740 } 741 742 private final Ice.LocatorPrx _locator; 743 private Ice.LocatorRegistryPrx _locatorRegistry; 744 private final LocatorTable _table; 745 private final boolean _background; 746 747 private java.util.Map<String, Request> _adapterRequests = new java.util.HashMap<String, Request>(); 748 private java.util.Map<Ice.Identity, Request> _objectRequests = new java.util.HashMap<Ice.Identity, Request>(); 749 } 750