| 1 22 package org.jnp.interfaces; 23 24 import java.io.BufferedInputStream ; 25 import java.io.IOException ; 26 import java.io.ObjectInputStream ; 27 import java.lang.ref.WeakReference ; 28 import java.lang.reflect.Constructor ; 29 import java.lang.reflect.InvocationTargetException ; 30 import java.net.DatagramPacket ; 31 import java.net.InetAddress ; 32 import java.net.MulticastSocket ; 33 import java.net.Socket ; 34 import java.net.InetSocketAddress ; 35 import java.rmi.ConnectException ; 36 import java.rmi.MarshalledObject ; 37 import java.util.ArrayList ; 38 import java.util.Arrays ; 39 import java.util.Collection ; 40 import java.util.Enumeration ; 41 import java.util.HashMap ; 42 import java.util.Hashtable ; 43 import java.util.Iterator ; 44 import java.util.StringTokenizer ; 45 import javax.naming.Binding ; 46 import javax.naming.CannotProceedException ; 47 import javax.naming.CommunicationException ; 48 import javax.naming.ConfigurationException ; 49 import javax.naming.Context ; 50 import javax.naming.InitialContext ; 51 import javax.naming.InvalidNameException ; 52 import javax.naming.LinkRef ; 53 import javax.naming.Name ; 54 import javax.naming.NameParser ; 55 import javax.naming.NamingEnumeration ; 56 import javax.naming.NamingException ; 57 import javax.naming.NotContextException ; 58 import javax.naming.ContextNotEmptyException ; 59 import javax.naming.OperationNotSupportedException ; 60 import javax.naming.Reference ; 61 import javax.naming.Referenceable ; 62 import javax.naming.ServiceUnavailableException ; 63 import javax.naming.event.EventContext ; 64 import javax.naming.event.NamingListener ; 65 import javax.naming.spi.NamingManager ; 66 import javax.naming.spi.ResolveResult ; 67 import javax.net.SocketFactory; 68 69 import org.jboss.logging.Logger; 70 71 83 public class NamingContext 84 implements EventContext , java.io.Serializable  85 { 86 90 static final long serialVersionUID = 8906455608484282128L; 91 94 public static final String JNP_SOCKET_FACTORY = "jnp.socketFactory"; 95 98 public static final String JNP_LOCAL_ADDRESS = "jnp.localAddress"; 99 102 public static final String JNP_LOCAL_PORT = "jnp.localPort"; 103 106 public static final String JNP_DISABLE_DISCOVERY = "jnp.disableDiscovery"; 107 110 public static final String JNP_PARTITION_NAME = "jnp.partitionName"; 111 114 public static final String JNP_DISCOVERY_GROUP = "jnp.discoveryGroup"; 115 118 public static final String JNP_DISCOVERY_PORT = "jnp.discoveryPort"; 119 120 121 public static final String JNP_DISCOVERY_TTL = "jnp.discoveryTTL"; 122 123 126 public static final String JNP_DISCOVERY_TIMEOUT = "jnp.discoveryTimeout"; 127 132 public static final String JNP_PARSED_NAME = "jnp.parsedName"; 133 138 public static final String JNP_USE_RELATIVE_NAME = "jnp.useRelativeName"; 139 145 public static final String JNP_MAX_RETRIES = "jnp.maxRetries"; 146 147 150 public final static String DEFAULT_DISCOVERY_GROUP_ADDRESS = "230.0.0.4"; 151 public final static int DEFAULT_DISCOVERY_GROUP_PORT = 1102; 152 public final static int DEFAULT_DISCOVERY_TIMEOUT = 5000; 153 154 157 public static int MAX_RETRIES = 1; 158 161 private static Logger log = Logger.getLogger(NamingContext.class); 162 163 165 public static Hashtable haServers = new Hashtable (); 166 167 public static void setHANamingServerForPartition(String partitionName, Naming haServer) 168 { 169 haServers.put(partitionName, haServer); 170 } 171 172 public static void removeHANamingServerForPartition(String partitionName) 173 { 174 haServers.remove(partitionName); 175 } 176 177 public static Naming getHANamingServerForPartition(String partitionName) 178 { 179 return (Naming) haServers.get(partitionName); 180 } 181 182 public static Naming localServer; 183 184 Naming naming; 186 Hashtable env; 187 Name prefix; 188 189 NameParser parser = new NamingParser(); 190 191 193 static HashMap cachedServers = new HashMap (); 200 201 static void addServer(String name, Naming server) 202 { 203 synchronized (NamingContext.class) 205 { 206 cachedServers.put(name, new WeakReference (server)); 207 } 208 } 209 210 static Naming getServer(String host, int port, Hashtable serverEnv) 211 throws NamingException  212 { 213 String hostKey = host + ":" + port; 215 WeakReference ref = (WeakReference ) cachedServers.get(hostKey); 216 Naming server; 217 if (ref != null) 218 { 219 server = (Naming) ref.get(); 220 if (server != null) 221 { 222 return server; 223 } 224 } 225 226 try 228 { 229 SocketFactory factory = loadSocketFactory(serverEnv); 230 Socket s; 231 232 try 233 { 234 InetAddress localAddr = null; 235 int localPort = 0; 236 String localAddrStr = (String ) serverEnv.get(JNP_LOCAL_ADDRESS); 237 String localPortStr = (String ) serverEnv.get(JNP_LOCAL_PORT); 238 if (localAddrStr != null) 239 localAddr = InetAddress.getByName(localAddrStr); 240 if (localPortStr != null) 241 localPort = Integer.parseInt(localPortStr); 242 s = factory.createSocket(host, port, localAddr, localPort); 243 } 244 catch (IOException e) 245 { 246 NamingException ex = new ServiceUnavailableException ("Failed to connect to server " + hostKey); 247 ex.setRootCause(e); 248 throw ex; 249 } 250 251 BufferedInputStream bis = new BufferedInputStream (s.getInputStream()); 253 ObjectInputStream in = new ObjectInputStream (bis); 254 MarshalledObject stub = (MarshalledObject ) in.readObject(); 255 server = (Naming) stub.get(); 256 s.close(); 257 258 addServer(hostKey, server); 260 serverEnv.put("hostKey", hostKey); 261 262 return server; 263 } 264 catch (IOException e) 265 { 266 NamingException ex = new CommunicationException ("Failed to retrieve stub from server " + hostKey); 267 ex.setRootCause(e); 268 throw ex; 269 } 270 catch (Exception e) 271 { 272 NamingException ex = new CommunicationException ("Failed to connect to server " + hostKey); 273 ex.setRootCause(e); 274 throw ex; 275 } 276 } 277 278 283 static SocketFactory loadSocketFactory(Hashtable serverEnv) 284 throws ClassNotFoundException , IllegalAccessException , 285 InstantiationException , InvocationTargetException  286 { 287 SocketFactory factory = null; 288 289 String socketFactoryName = (String ) serverEnv.get(JNP_SOCKET_FACTORY); 291 if (socketFactoryName == null || 292 socketFactoryName.equals(TimedSocketFactory.class.getName())) 293 { 294 factory = new TimedSocketFactory(serverEnv); 295 return factory; 296 } 297 298 301 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 302 Class factoryClass = loader.loadClass(socketFactoryName); 303 try 304 { 305 Class [] ctorSig = {Hashtable .class}; 306 Constructor ctor = factoryClass.getConstructor(ctorSig); 307 Object [] ctorArgs = {serverEnv}; 308 factory = (SocketFactory) ctor.newInstance(ctorArgs); 309 } 310 catch (NoSuchMethodException e) 311 { 312 factory = (SocketFactory) factoryClass.newInstance(); 314 } 315 return factory; 316 } 317 318 static void removeServer(Hashtable serverEnv) 319 { 320 String host = "localhost"; 321 int port = 1099; 322 323 if (serverEnv.get(Context.PROVIDER_URL) != null) 325 { 326 String providerURL = (String ) serverEnv.get(Context.PROVIDER_URL); 327 328 StringTokenizer tokenizer = new StringTokenizer (providerURL, ", "); 329 while (tokenizer.hasMoreElements()) 330 { 331 String url = tokenizer.nextToken(); 332 333 try 334 { 335 Name urlAsName = new NamingParser().parse(url); 337 String server = parseNameForScheme(urlAsName, null); 338 if (server != null) 339 url = server; 340 int colon = url.indexOf(':'); 341 if (colon < 0) 342 { 343 host = url.trim(); 344 } 345 else 346 { 347 host = url.substring(0, colon).trim(); 348 try 349 { 350 port = Integer.parseInt(url.substring(colon + 1).trim()); 351 } 352 catch (Exception ex) 353 { 354 } 356 } 357 358 synchronized (NamingContext.class) 360 { 361 cachedServers.remove(host + ":" + port); 362 } 363 } 364 catch (NamingException ignored) 365 { 366 } 367 } 368 Object hostKey = serverEnv.remove("hostKey"); 369 if (hostKey != null) 370 { 371 synchronized (NamingContext.class) 372 { 373 cachedServers.remove(hostKey); 374 } 375 } 376 } 377 else 378 { 379 } 381 } 382 383 391 static String parseNameForScheme(Name n, Hashtable nameEnv) 392 throws InvalidNameException  393 { 394 String serverInfo = null; 395 if (n.size() > 0) 396 { 397 String scheme = n.get(0); 398 int schemeLength = 0; 399 if (scheme.startsWith("java:")) 400 schemeLength = 5; 401 else if (scheme.startsWith("jnp:")) 402 schemeLength = 4; 403 else if (scheme.startsWith("jnps:")) 404 schemeLength = 5; 405 else if (scheme.startsWith("jnp-http:")) 406 schemeLength = 9; 407 else if (scheme.startsWith("jnp-https:")) 408 schemeLength = 10; 409 if (schemeLength > 0) 410 { 411 n = (Name ) n.clone(); 413 String suffix = scheme.substring(schemeLength); 414 if (suffix.length() == 0) 415 { 416 n.remove(0); 418 if (n.size() > 1 && n.get(0).equals("")) 419 { 420 serverInfo = n.get(1); 423 n.remove(0); 424 n.remove(0); 425 if (n.size() == 1 && n.get(0).length() == 0) 427 n.remove(0); 428 } 429 } 430 else 431 { 432 n.remove(0); 434 n.add(0, suffix); 435 } 436 if (nameEnv != null) 437 nameEnv.put(JNP_PARSED_NAME, n); 438 } 439 } 440 return serverInfo; 441 } 442 443 public static void setLocal(Naming server) 444 { 445 localServer = server; 446 } 447 448 public NamingContext(Hashtable e, Name baseName, Naming server) 450 throws NamingException  451 { 452 if (baseName == null) 453 this.prefix = parser.parse(""); 454 else 455 this.prefix = baseName; 456 457 if (e != null) 458 this.env = (Hashtable ) e.clone(); 459 else 460 this.env = new Hashtable (); 461 462 this.naming = server; 463 } 464 465 public Naming getNaming() 467 { 468 return this.naming; 469 } 470 471 public void setNaming(Naming server) 472 { 473 this.naming = server; 474 } 475 476 public void rebind(String name, Object obj) 478 throws NamingException  479 { 480 rebind(getNameParser(name).parse(name), obj); 481 } 482 483 public void rebind(Name name, Object obj) 484 throws NamingException  485 { 486 Hashtable refEnv = getEnv(name); 487 checkRef(refEnv); 488 Name parsedName = (Name ) refEnv.get(JNP_PARSED_NAME); 489 if (parsedName != null) 490 name = parsedName; 491 492 obj = getStateToBind(obj, name, refEnv); 494 495 try 496 { 497 String className; 498 499 if (obj instanceof Referenceable ) 501 obj = ((Referenceable ) obj).getReference(); 502 503 if (!(obj instanceof Reference )) 504 { 505 className = obj.getClass().getName(); 506 obj = new MarshalledValuePair(obj); 508 } 509 else 510 { 511 className = ((Reference ) obj).getClassName(); 512 } 513 naming.rebind(getAbsoluteName(name), obj, className); 514 } 515 catch (CannotProceedException cpe) 516 { 517 cpe.setEnvironment(refEnv); 518 Context cctx = NamingManager.getContinuationContext(cpe); 519 cctx.rebind(cpe.getRemainingName(), obj); 520 } 521 catch (IOException e) 522 { 523 naming = null; 524 removeServer(refEnv); 525 NamingException ex = new CommunicationException (); 526 ex.setRootCause(e); 527 throw ex; 528 } 529 } 530 531 public void bind(String name, Object obj) 532 throws NamingException  533 { 534 bind(getNameParser(name).parse(name), obj); 535 } 536 537 public void bind(Name name, Object obj) 538 throws NamingException  539 { 540 Hashtable refEnv = getEnv(name); 541 checkRef(refEnv); 542 Name parsedName = (Name ) refEnv.get(JNP_PARSED_NAME); 543 if (parsedName != null) 544 name = parsedName; 545 546 obj = getStateToBind(obj, name, refEnv); 548 549 try 550 { 551 String className; 552 553 if (obj instanceof Referenceable ) 555 obj = ((Referenceable ) obj).getReference(); 556 557 if (!(obj instanceof Reference )) 558 { 559 className = obj.getClass().getName(); 560 561 obj = new MarshalledValuePair(obj); 563 } 564 else 565 { 566 className = ((Reference ) obj).getClassName(); 567 } 568 name = getAbsoluteName(name); 569 naming.bind(name, obj, className); 570 } 571 catch (CannotProceedException cpe) 572 { 573 cpe.setEnvironment(refEnv); 574 Context cctx = NamingManager.getContinuationContext(cpe); 575 cctx.bind(cpe.getRemainingName(), obj); 576 } 577 catch (IOException e) 578 { 579 naming = null; 580 removeServer(refEnv); 581 NamingException ex = new CommunicationException (); 582 ex.setRootCause(e); 583 throw ex; 584 } 585 } 586 587 public Object lookup(String name) 588 throws NamingException  589 { 590 return lookup(getNameParser(name).parse(name)); 591 } 592 593 public Object lookup(Name name) 594 throws NamingException  595 { 596 Hashtable refEnv = getEnv(name); 597 checkRef(refEnv); 598 Name parsedName = (Name ) refEnv.get(JNP_PARSED_NAME); 599 if (parsedName != null) 600 name = parsedName; 601 602 if (name.isEmpty()) 604 return new NamingContext(refEnv, prefix, naming); 605 606 try 607 { 608 int maxTries = 1; 609 try 610 { 611 String n = (String ) refEnv.get(JNP_MAX_RETRIES); 612 if( n != null ) 613 maxTries = Integer.parseInt(n); 614 if( maxTries <= 0 ) 615 maxTries = 1; 616 } 617 catch(Exception e) 618 { 619 log.debug("Failed to get JNP_MAX_RETRIES, using 1", e); 620 } 621 Name n = getAbsoluteName(name); 622 Object res = null; 623 boolean trace = log.isTraceEnabled(); 624 for (int i = 0; i < maxTries; i++) 625 { 626 try 627 { 628 res = naming.lookup(n); 629 break; 630 } 631 catch (ConnectException ce) 632 { 633 int retries = maxTries - i - 1; 634 if( trace ) 635 log.trace("Connect failed, retry count: "+retries, ce); 636 if (retries > 0) 638 { 639 try 640 { 641 Thread.sleep(1); 642 } 643 catch (InterruptedException ignored) 644 { 645 } 646 continue; 647 } 648 throw ce; 650 } 651 } 652 if (res instanceof MarshalledValuePair) 653 { 654 MarshalledValuePair mvp = (MarshalledValuePair) res; 655 Object storedObj = mvp.get(); 656 return getObjectInstanceWrapFailure(storedObj, name, refEnv); 657 } 658 else if (res instanceof MarshalledObject ) 659 { 660 MarshalledObject mo = (MarshalledObject ) res; 661 return mo.get(); 662 } 663 else if (res instanceof Context ) 664 { 665 Enumeration keys = refEnv.keys(); 667 while (keys.hasMoreElements()) 668 { 669 String key = (String ) keys.nextElement(); 670 ((Context ) res).addToEnvironment(key, refEnv.get(key)); 671 } 672 return res; 673 } 674 else if (res instanceof ResolveResult ) 675 { 676 ResolveResult rr = (ResolveResult ) res; 678 Object resolveRes = rr.getResolvedObj(); 679 Object context; 680 Object instanceID; 681 682 if (resolveRes instanceof LinkRef ) 683 { 684 context = resolveLink(resolveRes, null); 685 instanceID = ((LinkRef ) resolveRes).getLinkName(); 686 } 687 else 688 { 689 context = getObjectInstanceWrapFailure(resolveRes, name, refEnv); 690 instanceID = context; 691 } 692 693 if ((context instanceof Context ) == false) 694 { 695 throw new NotContextException (instanceID + " is not a Context"); 696 } 697 Context ncontext = (Context ) context; 698 return ncontext.lookup(rr.getRemainingName()); 699 } 700 else if (res instanceof LinkRef ) 701 { 702 res = resolveLink(res, refEnv); 704 } 705 else if (res instanceof Reference ) 706 { 707 res = getObjectInstanceWrapFailure(res, name, refEnv); 709 if (res instanceof LinkRef ) 710 res = resolveLink(res, refEnv); 711 } 712 713 return res; 714 } 715 catch (CannotProceedException cpe) 716 { 717 cpe.setEnvironment(refEnv); 718 Context cctx = NamingManager.getContinuationContext(cpe); 719 return cctx.lookup(cpe.getRemainingName()); 720 } 721 catch (IOException e) 722 { 723 naming = null; 724 removeServer(refEnv); 725 NamingException ex = new CommunicationException (); 726 ex.setRootCause(e); 727 throw ex; 728 } 729 &nbs
|