1 7 package org.jboss.remoting.detection.jndi; 8 9 import java.net.InetAddress ; 10 import java.util.Properties ; 11 import javax.naming.Binding ; 12 import javax.naming.Context ; 13 import javax.naming.InitialContext ; 14 import javax.naming.NameAlreadyBoundException ; 15 import javax.naming.NamingEnumeration ; 16 import javax.naming.NamingException ; 17 import org.jboss.logging.Logger; 18 import org.jboss.remoting.InvokerLocator; 19 import org.jboss.remoting.InvokerRegistry; 20 import org.jboss.remoting.detection.AbstractDetector; 21 import org.jboss.remoting.detection.Detection; 22 import org.jboss.remoting.ident.Identity; 23 import org.jboss.remoting.transport.PortUtil; 24 import org.jnp.interfaces.NamingContextFactory; 25 import org.jnp.server.Main; 26 27 53 public class JNDIDetector extends AbstractDetector implements JNDIDetectorMBean 54 { 55 private int port; 56 private String host; 57 private String contextFactory = NamingContextFactory.class.getName();; 58 private String urlPackage = "org.jboss.naming:org.jnp.interfaces";; 59 60 private Identity id; 61 private Context context; 62 private int cleanDetectionCount = 0; 63 64 public static final String DETECTION_SUBCONTEXT_NAME = "detection"; 65 66 69 private int detectionNumber = 5; 70 71 protected final Logger log = Logger.getLogger(getClass()); 72 73 78 public int getPort() 79 { 80 return port; 81 } 82 83 88 public void setPort(int port) 89 { 90 this.port = port; 91 } 92 93 98 public String getHost() 99 { 100 return host; 101 } 102 103 108 public void setHost(String host) 109 { 110 this.host = host; 111 } 112 113 118 public String getContextFactory() 119 { 120 return contextFactory; 121 } 122 123 129 public void setContextFactory(String contextFactory) 130 { 131 this.contextFactory = contextFactory; 132 } 133 134 139 public String getURLPackage() 140 { 141 return urlPackage; 142 } 143 144 149 public void setURLPackage(String urlPackage) 150 { 151 this.urlPackage = urlPackage; 152 } 153 154 159 public void start() throws Exception 160 { 161 createContext(); 162 id = Identity.get(mbeanserver); 163 super.start(); 164 } 165 166 171 protected void heartbeat() 172 { 173 try 174 { 175 if(context == null) 177 { 178 createContext(); 179 } 180 checkRemoteDetectionMsg(); 181 } 182 catch(NamingException nex) 183 { 184 log.error("Can not connect to JNDI server to register local connectors.", nex); 185 } 186 } 187 188 194 public int getCleanDetectionNumber() 195 { 196 return detectionNumber; 197 } 198 199 207 public void setCleanDetectionNumber(int cleanDetectionNumber) 208 { 209 detectionNumber = cleanDetectionNumber; 210 } 211 212 private void checkRemoteDetectionMsg() 213 { 214 try 215 { 216 boolean localFound = false; 217 cleanDetectionCount++; 218 boolean cleanDetect = cleanDetectionCount > detectionNumber; 219 String bindName = ""; 220 NamingEnumeration enumeration = context.listBindings(bindName); 221 while(enumeration.hasMore()) 222 { 223 Binding binding = (Binding ) enumeration.next(); 224 Detection regMsg = (Detection) binding.getObject(); 225 if(isRemoteDetection(regMsg)) 227 { 228 log.debug("Detected id: " + regMsg.getIdentity().getInstanceId() + ", message: " + regMsg); 229 230 if(cleanDetect) 231 { 232 if(log.isTraceEnabled()) 233 { 234 log.trace("Doing clean detection."); 235 } 236 ClassLoader cl = JNDIDetector.this.getClass().getClassLoader(); 239 if(!checkInvokerServer(regMsg, cl)) 240 { 241 unregisterDetection(regMsg.getIdentity().getInstanceId()); 242 } 243 } 244 else 245 { 246 detect(regMsg); 248 } 249 } 250 else 251 { 252 if(!verifyLocalDetectionMsg(regMsg)) 254 { 255 addLocalDetectionMsg(); 256 } 257 localFound = true; 258 } 259 } 260 if(cleanDetect) 261 { 262 cleanDetectionCount = 0; 264 } 265 if(!localFound) 266 { 267 addLocalDetectionMsg(); 269 } 270 } 271 catch(NamingException e) 272 { 273 log.error("Exception getting detection messages from JNDI server.", e); 274 } 275 } 276 277 private boolean verifyLocalDetectionMsg(Detection regMsg) throws NamingException 278 { 279 boolean verified = false; 280 281 InvokerLocator[] locators = InvokerRegistry.getRegisteredServerLocators(); 282 Detection msg = createDetection(); 283 String sId = id.getInstanceId(); 284 InvokerLocator[] invokers = regMsg.getLocators(); 285 286 if(sId.equals(regMsg.getIdentity().getInstanceId())) 288 { 289 290 boolean changed = false; 292 if(locators.length != invokers.length) 293 { 294 changed = true; 295 } 296 else 297 { 298 boolean found = false; for(int i = 0; i < locators.length; i++) 302 { 303 found = false; 304 for(int x = 0; x < invokers.length; x++) 305 { 306 if(locators[i].equals(invokers[x])) 307 { 308 found = true; 309 break; 310 } 311 } 312 if(!found) 313 { 314 break; 315 } 316 } 317 if(!found) 318 { 319 changed = true; 320 } 321 } 322 if(changed) 323 { 324 registerDetectionMsg(sId, msg); 325 } 326 verified = true; 328 } 329 return verified; 330 } 331 332 private void addLocalDetectionMsg() throws NamingException 333 { 334 Detection msg = createDetection(); 335 String sId = id.getInstanceId(); 336 registerDetectionMsg(sId, msg); 337 } 338 339 private void registerDetectionMsg(String sId, Detection msg) throws NamingException 340 { 341 try 342 { 343 context.bind(sId, msg); 344 log.info("Added " + sId + " to registry."); 345 } 346 catch(NameAlreadyBoundException nabex) 347 { 348 if(log.isTraceEnabled()) 349 { 350 log.trace(sId + " already bound to server."); 351 } 352 } 353 } 354 355 360 private void verifyJNDIServer() 361 { 362 if(host == null || host.length() == 0) 363 { 364 try 365 { 366 log.info("JNDI Server configuration information not present so will create a local server."); 367 port = PortUtil.findFreePort(); 368 host = InetAddress.getLocalHost().getHostName(); 369 370 log.info("Remoting JNDI detector starting JNDI server instance since none where specified via configuration."); 371 log.info("Remoting JNDI server started on host + " + host + " and port " + port); 372 373 Main server = new Main(); 375 server.setPort(port); 376 server.setBindAddress(host); 377 server.start(); 378 379 contextFactory = NamingContextFactory.class.getName(); 380 urlPackage = "org.jboss.naming:org.jnp.interfaces"; 381 } 382 catch(Exception e) 383 { 384 log.error("Error starting up JNDI server since none was specified via configuration.", e); 385 } 386 } 387 } 388 389 395 private void createContext() throws NamingException 396 { 397 verifyJNDIServer(); 398 399 Properties env = new Properties (); 400 401 env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory); 402 env.put(Context.PROVIDER_URL, host + ":" + port); 403 env.put(Context.URL_PKG_PREFIXES, urlPackage); 404 405 InitialContext initialContext = new InitialContext (env); 406 try 407 { 408 context = (Context ) initialContext.lookup(DETECTION_SUBCONTEXT_NAME); 409 } 410 catch(NamingException e) 411 { 412 try 413 { 414 context = initialContext.createSubcontext(DETECTION_SUBCONTEXT_NAME); 415 } 416 catch(NameAlreadyBoundException e1) 417 { 418 log.debug("The sub context " + DETECTION_SUBCONTEXT_NAME + " was created before we could."); 419 context = (Context ) initialContext.lookup(DETECTION_SUBCONTEXT_NAME); 420 } 421 } 422 } 423 424 public void stop() throws Exception 425 { 426 try 427 { 428 super.stop(); 429 } 430 finally { 432 String sId = id.getInstanceId(); 433 try 434 { 435 unregisterDetection(sId); 436 } 437 catch(NamingException e) 438 { 439 log.warn("Could not unregister " + sId + " before shutdown. " + 440 "Root cause is " + e.getMessage()); 441 } 442 } 443 } 444 445 private void unregisterDetection(String sId) throws NamingException 446 { 447 if(log.isTraceEnabled()) 448 { 449 log.trace("unregistering detector " + sId); 450 } 451 context.unbind(sId); 452 } 453 } 454 | Popular Tags |