1 18 package org.apache.geronimo.interop.rmi.iiop.client; 19 20 import java.io.IOException ; 21 import java.lang.reflect.Constructor ; 22 import java.net.Socket ; 23 24 import org.apache.geronimo.interop.SystemException; 25 import org.apache.geronimo.interop.properties.BooleanProperty; 26 import org.apache.geronimo.interop.properties.IntProperty; 27 import org.apache.geronimo.interop.properties.PropertyMap; 28 import org.apache.geronimo.interop.properties.SystemProperties; 29 import org.apache.geronimo.interop.rmi.iiop.BadMagicException; 30 import org.apache.geronimo.interop.rmi.iiop.CdrInputStream; 31 import org.apache.geronimo.interop.rmi.iiop.CdrOutputStream; 32 import org.apache.geronimo.interop.rmi.iiop.GiopMessage; 33 import org.apache.geronimo.interop.rmi.iiop.ObjectRef; 34 import org.apache.geronimo.interop.rmi.iiop.SecurityInfo; 35 import org.apache.geronimo.interop.rmi.iiop.SimpleObjectInputStream; 36 import org.apache.geronimo.interop.rmi.iiop.UnsupportedProtocolVersionException; 37 import org.apache.geronimo.interop.util.ExceptionUtil; 38 import org.apache.geronimo.interop.util.InstancePool; 39 import org.apache.geronimo.interop.util.StringUtil; 40 import org.apache.geronimo.interop.util.ThreadContext; 41 import org.omg.GIOP.MsgType_1_1; 42 import org.omg.GIOP.ReplyHeader_1_2; 43 import org.omg.GIOP.ReplyStatusType_1_2; 44 import org.omg.GIOP.RequestHeader_1_2; 45 import org.omg.GIOP.SystemExceptionReplyBody; 46 import org.omg.GIOP.SystemExceptionReplyBodyHelper; 47 import org.omg.GIOP.TargetAddress; 48 import org.omg.IOP.ServiceContext ; 49 50 public class Connection 51 { 52 53 private static final byte reservedBA[] = new byte[] { 0, 0, 0}; 54 private int requestid_ = 0; 55 56 private boolean httpTunnelled; 58 private String httpHeaders; 59 private String webProxyHost; 60 private int webProxyPort; 61 62 public Connection() 63 { 64 } 65 66 public static Connection getInstance(String endpoint, ObjectRef objectRef, PropertyMap connProps) 67 { 68 Connection conn = new Connection(); 69 conn.init(endpoint, objectRef, connProps); 70 return conn; 71 } 72 73 public static final BooleanProperty simpleIDLProperty = 74 new BooleanProperty(SystemProperties.class, "org.apache.geronimo.interop.simpleIDL"); 75 76 public static final IntProperty socketTimeoutProperty = 77 new IntProperty(Connection.class, "socketTimeout") 78 .defaultValue(600); 80 private static final boolean SIMPLE_IDL = simpleIDLProperty.getBoolean(); 81 82 private static final ServiceContext [] EMPTY_SERVICE_CONTEXT = {}; 83 84 private static final byte[] CODE_SET_ENCAPSULATION = 85 { 86 (byte)0, (byte)0, (byte)0, (byte)0, (byte)0x05, (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x01, (byte)0x09, }; 91 92 private static final ServiceContext CODE_SET_SERVICE_CONTEXT = new ServiceContext (1, CODE_SET_ENCAPSULATION); 93 94 private String url; 95 96 private boolean ok; 97 98 private InstancePool pool; 99 100 private Socket socket; 101 102 protected org.apache.geronimo.interop.rmi.iiop.ObjectInputStream input; 103 104 protected org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream output; 105 106 private CdrOutputStream parameters; 107 108 private CdrOutputStream requestOut; 109 110 private CdrInputStream results; 111 112 private String exceptionType; 113 114 private Exception exception; 115 116 private RequestHeader_1_2 requestHeader; 117 118 private int callForget; 119 120 121 protected java.io.InputStream socketIn; 122 123 protected java.io.OutputStream socketOut; 124 125 public String getInstanceName() 126 { 127 return url; 128 } 129 130 public void close() 131 { 132 parameters = null; 133 input = null; 134 output = null; 135 if (ok) 136 { 137 pool.put(this); 138 } 139 else 140 { 141 shutdown(); 142 } 143 } 144 145 public void beforeInvoke() { 146 ok = false; 147 parameters = CdrOutputStream.getInstance(); 148 } 149 150 public void forget(Object requestKey) { 151 } 152 153 public void invoke(ObjectRef object, String method, Object requestKey, int retryCount) 154 { 155 if(object.$getForwardingAddress() != null) 156 { 157 object = object.$getForwardingAddress(); 158 } 159 160 RequestHeader_1_2 request = requestHeader; 161 162 request.request_id = requestid_++; 163 request.response_flags = 3; 164 request.target = new TargetAddress(); 165 request.target.object_key(object.$getObjectKey()); 166 request.operation = method; 167 request.service_context = getServiceContext(object, requestKey, retryCount); 168 request.reserved = reservedBA; 170 if (requestOut == null) 171 { 172 requestOut = CdrOutputStream.getInstance(); 173 } 174 requestOut.write_request(request, parameters); 175 176 177 try 178 { 179 if(httpTunnelled) 180 { 181 requestOut.send_http_request(socketOut, url, httpHeaders); 182 } 183 else 184 { 185 requestOut.send_message(socketOut, url); 186 } 187 } catch (RuntimeException ex) { 188 throw ex; 189 } 190 191 requestOut.reset(); 192 193 if (results == null) 194 { 195 results = CdrInputStream.getInstance(); 196 } 197 else 198 { 199 results.reset(); 200 } 201 202 results.setNamingContext(object.$getNamingContext()); 203 GiopMessage message; 204 try 205 { 206 if(httpTunnelled) 207 { 208 message = results.receive_http_response(socketIn, url); 209 } 210 else 211 { 212 message = results.receive_message(socketIn, url); } 214 } 215 catch (BadMagicException ex) 216 { 217 throw new SystemException(ex); 218 } 219 catch (UnsupportedProtocolVersionException ex) 220 { 221 throw new SystemException(ex); 222 } 223 catch (RuntimeException ex) 224 { 225 throw new RetryInvokeException(ex); 226 } 227 228 switch (message.type) 229 { 230 case MsgType_1_1._Reply: 231 processReply(message.reply, object); 232 break; 233 234 default: 235 throw new SystemException("TODO: message type = " + message.type); 236 } 237 238 ok = true; 239 } 240 241 public InstancePool getInstancePool() { 242 return pool; 243 } 244 245 public void setInstancePool(InstancePool pool) { 246 this.pool = pool; 247 } 248 249 public org.apache.geronimo.interop.rmi.iiop.ObjectInputStream getInputStream() { 250 if (SIMPLE_IDL) { 251 return getSimpleInputStream(); 252 } 253 if (input == null) { 254 input = org.apache.geronimo.interop.rmi.iiop.ObjectInputStream.getInstance(results); 255 } 256 return input; 257 } 258 259 public org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream getOutputStream() { 260 if (SIMPLE_IDL) { 261 return getSimpleOutputStream(); 262 } 263 if (output == null) { 264 output = org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream.getInstance(parameters); 265 } 266 return output; 267 } 268 269 public org.apache.geronimo.interop.rmi.iiop.ObjectInputStream getSimpleInputStream() { 270 if (input == null) { 271 input = org.apache.geronimo.interop.rmi.iiop.SimpleObjectInputStream.getInstance(results); 272 } 273 return input; 274 } 275 276 public org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream getSimpleOutputStream() { 277 if (output == null) { 278 output = org.apache.geronimo.interop.rmi.iiop.SimpleObjectOutputStream.getInstance(parameters); 279 } 280 return output; 281 } 282 283 public String getExceptionType() { 284 return exceptionType; 285 } 286 287 public Exception getException() { 288 if (exception == null) { 289 if (exceptionType != null) { 290 return new SystemException(exceptionType, new org.omg.CORBA.UNKNOWN ()); 291 } else { 292 throw new IllegalStateException ("no exception"); 293 } 294 } else { 295 return exception; 296 } 297 } 298 299 public void clearException() 300 { 301 exceptionType = null; 302 exception = null; 303 } 304 305 protected void init(String endpoint, ObjectRef objectRef, PropertyMap connProps) 307 { 308 setHttpTunnelledPropsIfTrue(connProps); 309 310 if(httpTunnelled) 311 { 312 httpInit(endpoint, connProps); 313 return; 314 } 315 316 url = "iiop://" + endpoint; 317 UrlInfo urlInfo = UrlInfo.getInstance(url); 318 String host = urlInfo.getHost(); 319 int port = urlInfo.getPort(); 320 int socketTimeout = socketTimeoutProperty.getInt(endpoint, connProps); 321 try 322 { 323 socket = new Socket (host, port); 324 socketIn = socket.getInputStream(); 325 socketOut = socket.getOutputStream(); 326 socket.setSoTimeout(1000 * socketTimeout); 327 } 328 catch (Exception ex) 329 { 330 throw new SystemException(ex); 331 } 332 requestHeader = new RequestHeader_1_2(); 333 requestHeader.reserved = reservedBA; 334 } 335 336 private void httpInit(String endpoint, PropertyMap connProps) 337 { 338 String host = null; 339 int port; 340 url = "iiop://" + endpoint; 341 int socketTimeout = socketTimeoutProperty.getInt(endpoint, connProps); 342 343 if(webProxyHost != null) 344 { 345 host = webProxyHost; 346 port = webProxyPort; 347 } 348 else 349 { 350 UrlInfo urlInfo = UrlInfo.getInstance(url); 351 host = urlInfo.getHost(); 352 port = urlInfo.getPort(); 353 } 354 355 try 356 { 357 socket = new Socket (host, port); 358 socketIn = socket.getInputStream(); 359 socketOut = socket.getOutputStream(); 360 socket.setSoTimeout(1000 * socketTimeout); 361 } 362 catch (IOException ex) 363 { 364 throw new SystemException(ex); 365 } 366 requestHeader = new RequestHeader_1_2(); 367 requestHeader.reserved = reservedBA; 368 } 369 370 public ServiceContext [] getServiceContext(ObjectRef object, Object requestKey, int retryCount) { 371 String username; 372 String password; 373 SecurityInfo securityInfo = SecurityInfo.getCurrent(); 374 if (securityInfo == null) { 375 ClientNamingContext namingContext = object.$getNamingContext(); 376 if (namingContext != null) { 377 username = namingContext.getUsername(); 378 password = namingContext.getPassword(); 379 } else { 380 username = null; 381 password = null; 382 } 383 } else { 384 username = securityInfo.username; 385 password = securityInfo.password; 386 } 387 if (username != null && username.length() == 0) { 388 username = null; } 390 if (password != null && password.length() == 0) { 391 password = null; } 393 int count = 0; 394 if (username != null) { 395 count++; 396 } 397 if (password != null) { 398 count++; 399 } 400 if (requestKey != null) { 401 count++; 402 } 403 ServiceContext [] context = new ServiceContext [count]; 404 int index = 0; 405 context[index++] = CODE_SET_SERVICE_CONTEXT; 406 if (username != null) { 407 context[index++] = new ServiceContext (SecurityInfo.TAG_USERNAME, SecurityInfo.encode(username)); 408 } 409 if (password != null) { 410 context[index++] = new ServiceContext (SecurityInfo.TAG_PASSWORD, SecurityInfo.encode(password)); 411 } 412 return context; 413 } 414 415 protected void processReply(ReplyHeader_1_2 reply, ObjectRef object) 416 { 417 processReplyServiceContext(reply); 418 int status = reply.reply_status.value(); 419 switch (status) 420 { 421 case ReplyStatusType_1_2._NO_EXCEPTION: 422 processNormalReply(reply); 423 break; 424 case ReplyStatusType_1_2._USER_EXCEPTION: 425 processUserException(reply); 426 break; 427 case ReplyStatusType_1_2._SYSTEM_EXCEPTION: 428 processSystemException(reply); 429 break; 430 case ReplyStatusType_1_2._LOCATION_FORWARD: 431 processLocationForward(reply, object); 432 break; 433 case ReplyStatusType_1_2._LOCATION_FORWARD_PERM: 434 processLocationForward(reply, object); 435 break; 436 case ReplyStatusType_1_2._NEEDS_ADDRESSING_MODE: 437 throw new SystemException("TODO"); 438 default: 439 throw new SystemException("reply status = " + status); 440 } 441 } 442 443 protected void processLocationForward(ReplyHeader_1_2 reply, ObjectRef object) 444 { 445 ObjectRef ref = (ObjectRef)results.read_Object(); 446 object.$setForwardingAddress(ref); 447 throw new RetryInvokeException(new RuntimeException ("LOCATION_FORWARD")); 448 } 449 450 protected void processReplyServiceContext(ReplyHeader_1_2 reply) { 451 ServiceContext [] list = reply.service_context; 452 int n = list.length; 453 for (int i = 0; i < n; i++) { 454 ServiceContext sc = list[i]; 455 if (sc.context_id == 0xCFCFCFCF 456 || sc.context_id == 0xDFDFDFDF) { 457 callForget = sc.context_id; 460 } 461 } 462 } 463 464 protected void processNormalReply(ReplyHeader_1_2 reply) { 465 } 467 468 protected void processUserException(ReplyHeader_1_2 reply) 469 { 470 exception = null; 471 String type = results.read_string(); 472 type = StringUtil.removePrefix(type, "IDL:"); 473 type = StringUtil.removeSuffix(type, ":1.0"); 474 if (! (input instanceof SimpleObjectInputStream)) 475 { 476 if (type.endsWith("Ex")) 477 { 478 type = StringUtil.removeSuffix(type, "Ex") + "Exception"; 479 } 480 } 481 type = type.replace('/', '.'); 482 exceptionType = type; 483 ok = true; 484 } 485 486 protected void processSystemException(ReplyHeader_1_2 reply) 487 { 488 exceptionType = "???"; 489 SystemExceptionReplyBody replyBody = SystemExceptionReplyBodyHelper.read(results); 490 String id = replyBody.exception_id; 491 id = StringUtil.removePrefix(id, "IDL:CORBA/"); id = StringUtil.removePrefix(id, "IDL:omg.org/CORBA/"); 493 id = StringUtil.removeSuffix(id, ":1.0"); 494 String causedBy = null; 495 if (results.hasMoreData()) 496 { 497 causedBy = ExceptionUtil.causedBy(results.read_string()); 500 } 501 ok = true; 502 String exceptionClassName = "org.omg.CORBA." + id; 503 try 504 { 505 Class exceptionClass = ThreadContext.loadClass(exceptionClassName); 506 Constructor constructor = exceptionClass.getConstructor 507 ( 508 new Class [] { String .class } 509 ); 510 org.omg.CORBA.SystemException corbaException; 511 corbaException = (org.omg.CORBA.SystemException )constructor.newInstance 512 ( 513 new Object [] { causedBy == null ? "" : causedBy } 514 ); 515 corbaException.minor = replyBody.minor_code_value; 516 corbaException.completed = org.omg.CORBA.CompletionStatus.from_int(replyBody.completion_status); 517 exception = corbaException; 518 } 519 catch (Exception ex) 520 { 521 ex.printStackTrace(); 523 if (causedBy == null) 524 { 525 causedBy = replyBody.exception_id; 526 } 527 else 528 { 529 causedBy = replyBody.exception_id + "\nCaused by: " + causedBy; 530 } 531 exception = new org.omg.CORBA.UNKNOWN (causedBy, 532 replyBody.minor_code_value, 533 org.omg.CORBA.CompletionStatus.from_int(replyBody.completion_status)); 534 } 535 } 536 537 private void setHttpTunnelledPropsIfTrue(PropertyMap connprops) 538 { 539 if(connprops.get("http") != null) 540 { 541 httpTunnelled = true; 542 } 543 else 544 { 545 httpTunnelled = false; 546 } 547 548 if(httpTunnelled) 549 { 550 httpHeaders = connprops.getProperty("HttpExtraHeader"); 552 553 if(httpHeaders != null && httpHeaders.toLowerCase().indexOf("user-agent") == -1) 554 { 555 httpHeaders += "User-Agent: Geronimo/1.0\r\n"; 556 } 557 558 if(httpHeaders == null) 559 { 560 httpHeaders = "User-Agent: Geronimo/1.0\r\n"; 561 } 562 563 webProxyHost = connprops.getProperty("WebProxyHost"); 565 String port = connprops.getProperty("WebProxyPort"); 566 567 if(port != null) 568 { 569 try 570 { 571 webProxyPort = java.lang.Integer.parseInt(port); 572 } 573 catch(java.lang.NumberFormatException e) 574 { 575 throw new SystemException(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e)); 576 } 577 } 578 579 if(port == null && webProxyHost != null) 580 { 581 webProxyPort = 80; } 583 } 584 else 585 { 586 webProxyHost = null; 587 httpHeaders = null; 588 } 589 } 590 591 public void shutdown() { 592 if (socketOut != null) { 593 try { 594 socketOut.close(); 595 } catch (Exception ignore) { 596 } 597 socketOut = null; 598 } 599 if (socketIn != null) { 600 try { 601 socketIn.close(); 602 } catch (Exception ignore) { 603 } 604 socketIn = null; 605 } 606 if (socket != null) { 607 try { 608 socket.close(); 609 } catch (Exception ignore) { 610 } 611 socket = null; 612 } 613 } 614 } 615 | Popular Tags |