PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/jtopen-7.8/src/com/ibm/as400/access/ProxyServer.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 849 lines | 343 code | 111 blank | 395 comment | 68 complexity | 1cc0cdabea61644353a416f54b38e267 MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // JTOpen (IBM Toolbox for Java - OSS version)
  4. //
  5. // Filename: ProxyServer.java
  6. //
  7. // The source code contained herein is licensed under the IBM Public License
  8. // Version 1.0, which has been approved by the Open Source Initiative.
  9. // Copyright (C) 1997-2003 International Business Machines Corporation and
  10. // others. All rights reserved.
  11. //
  12. ///////////////////////////////////////////////////////////////////////////////
  13. package com.ibm.as400.access;
  14. import java.io.IOException;
  15. import java.io.PrintStream;
  16. import java.lang.reflect.Constructor;
  17. import java.lang.reflect.InvocationTargetException;
  18. import java.lang.reflect.Method;
  19. import java.net.BindException;
  20. import java.net.InetAddress;
  21. import java.net.UnknownHostException;
  22. import java.util.Enumeration;
  23. import java.util.Vector;
  24. /**
  25. Fulfills requests from programs
  26. using the proxy jar file. The proxy server is responsible for
  27. creating and invoking methods on Toolbox objects on behalf of the
  28. program. The proxy server is intended for use on a middle-tier in
  29. a multiple tier environment.
  30. <p>If there is already a proxy server active for the specified
  31. port, then a new proxy server will not be started. Instead,
  32. the existing proxy server's configuration will be updated.
  33. <p>A ProxyServer object can be created and run directly from a
  34. program. Alternately, the proxy server can be run as an
  35. application, as follows:
  36. <blockquote>
  37. <pre>
  38. <strong>java com.ibm.as400.access.ProxyServer</strong> [ options ]
  39. </pre>
  40. </blockquote>
  41. <p>Options:
  42. <dl>
  43. <dt><b><code>-balanceThreshold </b></code><var>balanceThreshold</var></dt>
  44. <dd>
  45. Specifies the number of connections that must be active before
  46. the peer server starts load balancing by dispatching requests to
  47. peer proxy servers. Specify 0 to start load balancing immediately or
  48. -1 to never start load balancing. This option may be abbreviated
  49. <code>-bt</code>. The default is -1. This has no effect unless peer
  50. proxy servers are specified.
  51. </dd>
  52. <dt><b><code>-configuration </b></code><var>configuration</var></dt>
  53. <dd>
  54. Specifies a properties file which lists configuration
  55. properties in the following format:
  56. <pre>
  57. balanceThreshold=<var>balanceThreshold</var>
  58. jdbcDrivers=<var>jdbcDriver1[;jdbcDriver2[;...]]</var>
  59. maxConnections=<var>maxConnections</var>
  60. peers=<var>hostname1[:port1][;hostname2[:port2][;...]]</var>
  61. verbose=true|false
  62. </pre>
  63. This option may be abbreviated <code>-c</code>. The default is
  64. to not load a configuration. If a property is loaded in
  65. a configuration and specified in a command line argument,
  66. then the command line argument takes precedence.
  67. </dd>
  68. <dt><b><code>-jdbcDrivers </b></code><var>jdbcDriver1[;jdbcDriver2;...]</var></dt>
  69. <dd>
  70. Specifies a list of JDBC driver class names to register with
  71. the JDBC DriverManager. Use this to register any JDBC drivers
  72. to which clients might need to connect. This option may be abbreviated
  73. <code>-jd</code>. The default is to load only the IBM Toolbox
  74. for Java JDBC driver.
  75. </dd>
  76. <dt><b><code>-maxConnections </b></code><var>maxConnections</var></dt>
  77. <dd>
  78. Specifies the maximum number of connections which can be active
  79. at any particular time. This refers to connections to the proxy
  80. server, that are initiated by clients. If the maximum number of
  81. connections are active, then any further connection requests will
  82. be rejected and an exception is thrown to the client program.
  83. Specify 0 to not allow any connections, or -1 for no limit.
  84. This option may be abbreviated <code>-mc</code>. The default is
  85. to allow an unlimited number of connections.
  86. </dd>
  87. <dt><b><code>-peers </b></code><var>hostname1[:port1][;hostname2[:port2];...]</var></dt>
  88. <dd>
  89. Specifies a list of peer proxy servers for use in load balancing.
  90. In some cases, connections to this proxy server will be
  91. reassigned to a peer. This option may be abbreviated
  92. <code>-pe</code>. The default is not to do load balancing.
  93. </dd>
  94. <dt><b><code>-port </b></code><var>port</var></dt>
  95. <dd>
  96. Specifies the port to use for accepting connections from clients.
  97. This option may be abbreviated <code>-po</code>. The default port is 3470.
  98. </dd>
  99. <dt><b><code>-securePort </b></code><var>securePort</var></dt>
  100. <dd>
  101. Specifies the port to use for accepting Secure Sockets Layer (SSL)
  102. connections from clients. This option may be abbreviated <code>-sp</code>.
  103. The proxy server will only accept SSL connections
  104. when the com.ibm.sslight package is in the classpath.
  105. The default port is 3471.
  106. </dd>
  107. <dt><b><code>-keyringName </b></code><var>keyringName</var></dt>
  108. <dd>
  109. Specifies the keyring to use for Secure Sockets Layer (SSL)
  110. communications from clients. This option may be abbreviated <code>-kn</code>.
  111. The keyring specified by this option must be in the classpath for SSL
  112. communications to work properly between the proxy server and client.
  113. If the com.ibm.sslight package is not the classpath, this option will
  114. be ignored.
  115. </dd>
  116. <dt><b><code>-keyringPassword </b></code><var>keyringPassword</var></dt>
  117. <dd>
  118. Specifies the password to the keyring. This option may be
  119. abbreviated <code>-kp</code>. This option msut be used in conjunction
  120. with the -keyringName option. If the com.ibm.sslight package is not the
  121. classpath, this option will be ignored.
  122. </dd>
  123. <dt><b><code>-verbose</b></code> [true|false]</dt>
  124. <dd>
  125. Specifies whether to print status and connection
  126. information to System.out. This option may be abbreviated
  127. <code>-v</code>. The default is not to print status and
  128. connection information.
  129. </dd>
  130. <dt><b><code>-help</b></code></dt>
  131. <dd>
  132. Prints usage information to System.out. This option may be abbreviated
  133. <code>-h</code> or <code>-?</code>. The default is not to print usage
  134. information.
  135. </dd>
  136. </dl>
  137. <p>Example usage:
  138. <p>To start the proxy server from a program:
  139. <pre>
  140. ProxyServer proxyServer = new ProxyServer ();
  141. proxyServer.setMaxConnections (25);
  142. proxyServer.run ();
  143. </pre>
  144. <p>Alternatively, the above action can be performed directly
  145. from the command line as follows:
  146. <pre>
  147. java com.ibm.as400.access.ProxyServer -maxconnections 25
  148. </pre>
  149. **/
  150. //
  151. // Implementation notes:
  152. //
  153. // 1. It was suggested that we provide a property which defines
  154. // whether we listen for non-secure connections, SSL connections,
  155. // or both. A suggestion says that this is more of a firewall
  156. // issue, and the specific ports can be turned on/off at the
  157. // firewall.
  158. //
  159. public class ProxyServer
  160. {
  161. // Private data.
  162. private static final PrintStream errors_ = System.err;
  163. private PSConfig configuration_;
  164. private PSLoad load_;
  165. private PSLoadBalancer loadBalancer_;
  166. private int port_;
  167. private int securePort_; //$B1C
  168. private String keyringName_; //$B1A
  169. private String keyringPwd_; //$B1A
  170. private Vector threadGroup_;
  171. static
  172. {
  173. // If the proxy server is running, it should ignore the proxy
  174. // server system property! (Otherwise, it would make connections
  175. // to itself.)
  176. SystemProperties.ignoreProperty(SystemProperties.AS400_PROXY_SERVER);
  177. }
  178. /**
  179. Constructs a ProxyServer object.
  180. **/
  181. public ProxyServer ()
  182. {
  183. port_ = ProxyConstants.PORT_NUMBER;
  184. securePort_ = ProxyConstants.SECURE_PORT_NUMBER; //$B1C
  185. keyringName_ = null; //$B1A
  186. keyringPwd_ = null; //$B1A
  187. threadGroup_ = null;
  188. load_ = new PSLoad ();
  189. loadBalancer_ = new PSLoadBalancer (load_);
  190. configuration_ = new PSConfig (load_, loadBalancer_);
  191. }
  192. /**
  193. Returns the number of active connections.
  194. @return The number of active connections.
  195. **/
  196. public int getActiveConnections ()
  197. {
  198. return load_.getActiveConnections ();
  199. }
  200. /**
  201. Returns the balance threshold. This is the number of
  202. connections that must be active before the peer server starts
  203. load balancing by dispatching requests to peer proxy servers.
  204. Specify 0 to start load balancing immediately or -1 to never
  205. start load balancing.
  206. @return The balance threshold, or 0 to start load
  207. balancing immediately or -1 to never start load
  208. balancing.
  209. **/
  210. public int getBalanceThreshold ()
  211. {
  212. return load_.getBalanceThreshold ();
  213. }
  214. /**
  215. Returns the name of the configuration properties.
  216. @return The name of the configuration properties, or null
  217. if not set.
  218. **/
  219. public String getConfiguration()
  220. {
  221. return configuration_.getName ();
  222. }
  223. /**
  224. Returns the keyring file that the proxy server will use during
  225. SSL connections from clients.
  226. @return The proxy server keyring file name.
  227. **/
  228. public String getKeyring () //$B1A
  229. {
  230. return keyringName_;
  231. }
  232. /**
  233. Returns the password to the proxy server keyring file.
  234. @return The proxy server keyring password.
  235. **/
  236. String getKeyringPassword () //$B1A
  237. {
  238. return keyringPwd_;
  239. }
  240. /**
  241. Returns the maximum number of connections which can be
  242. active at any particular time.
  243. @return The maximum number of connections which can be
  244. active at any particular time, or -1 for
  245. unlimited connections.
  246. **/
  247. public int getMaxConnections ()
  248. {
  249. return load_.getMaxConnections ();
  250. }
  251. /**
  252. Returns a list of peer proxy servers for use in load balancing.
  253. Each peer proxy server is specified in the format
  254. <var>hostname[:port]</var>. This returns an empty array if
  255. there are no peer proxy servers.
  256. @return A list of peer proxy servers for use in load balancing.
  257. **/
  258. public String[] getPeers ()
  259. {
  260. return loadBalancer_.getPeers ();
  261. }
  262. /**
  263. Returns the port to use for accepting connections from clients.
  264. @return The port to use for accepting connections from clients.
  265. **/
  266. public int getPort ()
  267. {
  268. return port_;
  269. }
  270. /**
  271. Returns the port to use for accepting Secure Sockets Layer (SSL)
  272. connections from clients.
  273. @return The port to use for accepting Secure Sockets Layer (SSL)
  274. connections from clients.
  275. **/
  276. public int getSecurePort () //$B1C
  277. {
  278. return securePort_;
  279. }
  280. /**
  281. Indicates if the proxy server has been started.
  282. @return true if the proxy server has been started, false otherwise.
  283. **/
  284. public boolean isStarted ()
  285. {
  286. return (threadGroup_ != null);
  287. }
  288. /**
  289. Indicates whether to print status and connection information
  290. to System.out.
  291. @return true to print status and connection information to
  292. System.out, false otherwise.
  293. **/
  294. public boolean isVerbose ()
  295. {
  296. return Verbose.isVerbose ();
  297. }
  298. /**
  299. Runs the proxy server as an application.
  300. @param args The command line arguments.
  301. **/
  302. public static void main (String args[])
  303. {
  304. ProxyServer proxyServer = new ProxyServer ();
  305. if (proxyServer.parseArgs (args)) {
  306. Verbose.forcePrintln (ResourceBundleLoader.getText ("PROXY_SERVER_STARTED"));
  307. proxyServer.start ();
  308. }
  309. else {
  310. PSConfig.usage (System.err);
  311. }
  312. }
  313. /**
  314. Parses the command line arguments and sets the properties
  315. accordingly.
  316. @param args The command line arguments.
  317. @return true if the combination of command line
  318. arguments is valid, false otherwise.
  319. **/
  320. private boolean parseArgs (String[] args)
  321. {
  322. CommandLineArguments cla = new CommandLineArguments (args,
  323. PSConfig.expectedOptions_,
  324. PSConfig.shortcuts_);
  325. if (cla.getOptionValue ("-help") != null)
  326. return false;
  327. try {
  328. configuration_.apply (cla);
  329. }
  330. catch (Exception e) {
  331. errors_.println (e.getMessage ());
  332. if (Trace.isTraceErrorOn ())
  333. Trace.log (Trace.ERROR, "Exception while parsing command line arguments", e);
  334. return false;
  335. }
  336. // Options that are not part of the configuration.
  337. String portOptionValue = cla.getOptionValue ("-port");
  338. if (portOptionValue != null)
  339. if (portOptionValue.length() > 0)
  340. setPort (Integer.parseInt (portOptionValue));
  341. String securePortOptionValue = cla.getOptionValue ("-securePort"); //$B1C
  342. if (securePortOptionValue != null) //$B1C
  343. if (securePortOptionValue.length() > 0) //$B1C
  344. setSecurePort (Integer.parseInt (securePortOptionValue)); //$B1C
  345. String keyringNameOptionValue = cla.getOptionValue ("-keyringName"); //$B1A
  346. String keyringPwdOptionValue = cla.getOptionValue ("-keyringPassword"); //$B1A
  347. try //$B1A
  348. { //$B1A
  349. // Try to load the SSLight classes. If they are not found then we do not need to //$B1A
  350. // check for the keyring command line parms. //$B1A
  351. //$B1A
  352. Class.forName("com.ibm.sslight.SSLContext"); //$B1A
  353. if (keyringNameOptionValue != null && keyringPwdOptionValue != null) //$B1A
  354. { //$B1A
  355. if (keyringNameOptionValue.length() > 0 && keyringPwdOptionValue.length() > 0) //$B1A
  356. { //$B1A
  357. setKeyringName (keyringNameOptionValue); //$B1A
  358. setKeyringPassword (keyringPwdOptionValue); //$B1A
  359. } //$B1A
  360. else //$B1A
  361. { //$B1A
  362. Verbose.forcePrintln ("\n" + //$B1A
  363. ResourceBundleLoader.getText("PROXY_SERVER_NO_KEYRING") + //$B1A
  364. "\n"); //$B1A
  365. } //$B1A
  366. } //$B1A
  367. else //$B1A
  368. { //$B1A
  369. Verbose.forcePrintln ("\n" + //$B1A
  370. ResourceBundleLoader.getText("PROXY_SERVER_KEYRING_EXPLAIN") + //$B1A
  371. "\n"); //$B1A
  372. } //$B1A
  373. } //$B1A
  374. catch (ClassNotFoundException e) //$B1A
  375. { /* No need to parse the keyring options since the SSLight classes are not in the CLASSPATH. */ //$B1A
  376. } //$B1A
  377. // Extra options.
  378. Enumeration list = cla.getExtraOptions ();
  379. while (list.hasMoreElements ()) {
  380. String extraOption = list.nextElement ().toString ();
  381. errors_.println (ResourceBundleLoader.getText ("PROXY_OPTION_NOT_VALID", extraOption));
  382. }
  383. // Values without options. @A1A
  384. String noOptionValues = cla.getOptionValue("-"); // @A1A
  385. if (noOptionValues != null) // @A1A
  386. if (noOptionValues.length() > 0) // @A1A
  387. errors_.println(ResourceBundleLoader.getText("PROXY_VALUE_NO_OPTION", noOptionValues)); // @A1A
  388. return true;
  389. }
  390. /**
  391. Sets the number of connections that must be active before
  392. the peer server starts load balancing by dispatching requests to
  393. peer proxy servers. The default is -1.
  394. @param balanceThreshold The number of connections that must be
  395. active before the peer server starts load
  396. balancing by dispatching requests to peer
  397. proxy servers. Specify 0 to start load
  398. balancing immediately or -1 to never start
  399. load balancing.
  400. **/
  401. public void setBalanceThreshold (int balanceThreshold)
  402. {
  403. load_.setBalanceThreshold (balanceThreshold);
  404. }
  405. /**
  406. Sets and loads the properties file which lists
  407. configuration properties. The default is not to load
  408. a configuration.
  409. @param configuration The properties file which list
  410. configuration properties.
  411. @exception IOException If the configuration can not be loaded.
  412. **/
  413. public void setConfiguration (String configuration)
  414. throws IOException
  415. {
  416. if (configuration == null)
  417. throw new NullPointerException ("configuration");
  418. if (configuration.length() == 0)
  419. throw new ExtendedIllegalArgumentException ("configuration", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
  420. configuration_.setName (configuration);
  421. configuration_.load ();
  422. }
  423. /**
  424. Sets the name of the keyring the proxy server
  425. will use during SSL communications. The proxy
  426. server keyring name can be set only if the proxy
  427. server is not running.
  428. @param keyringName The proxy server keyring name.
  429. **/
  430. public void setKeyringName(String keyringName) //$B1A
  431. {
  432. if (keyringName == null)
  433. throw new NullPointerException ("keyringName");
  434. if (keyringName.length() == 0)
  435. throw new ExtendedIllegalArgumentException ("keyringName", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
  436. keyringName_ = keyringName;
  437. }
  438. /**
  439. Sets the password to the keyring the proxy server
  440. will use during SSL communications. The proxy
  441. server keyring password can be set only if the proxy
  442. server is not running.
  443. @param keyringPassword The proxy server keyring password.
  444. **/
  445. public void setKeyringPassword(String keyringPassword) //$B1A
  446. {
  447. if (keyringPassword == null)
  448. throw new NullPointerException ("keyringPassword");
  449. if (keyringPassword.length() == 0)
  450. throw new ExtendedIllegalArgumentException ("keyringPassword", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
  451. keyringPwd_ = keyringPassword;
  452. }
  453. /**
  454. Sets the maximum number of connections which can be active
  455. at any particular time. If the maximum number of connections
  456. are active, then any further connection requests will be
  457. rejected. The default is to allow an unlimited number of
  458. connections.
  459. <p>Setting this to a number less than the number of active
  460. connections will not drop any active connections. It will
  461. simply prevent new connections from being accepted until the
  462. number of active connections is less than the limit.
  463. @param maxConnections The maximum number of connections
  464. which can be active at any particular
  465. time. Specify 0 to not allow any
  466. connections or -1 for unlimited
  467. connections.
  468. **/
  469. public void setMaxConnections (int maxConnections)
  470. {
  471. load_.setMaxConnections (maxConnections);
  472. }
  473. /**
  474. Sets the list of peer proxy servers for use in load
  475. balancing. In some cases, connections to the proxy
  476. server will be reassigned to a peer. The default is
  477. not to do load balancing. Specify each peer proxy
  478. server in the format <var>hostname[:port]</var>.
  479. @param peers The list of peer proxy servers for
  480. use in load balancing, or an empty
  481. array to not do load balancing.
  482. **/
  483. public void setPeers (String[] peers)
  484. {
  485. if (peers == null)
  486. throw new NullPointerException ("peers");
  487. for (int i = 0; i < peers.length; ++i) {
  488. if (peers[i] == null)
  489. throw new NullPointerException ("peers[" + i + "]");
  490. if (peers[i].length() == 0)
  491. throw new ExtendedIllegalArgumentException ("peers[" + i + "]", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
  492. }
  493. loadBalancer_.setPeers (peers);
  494. }
  495. /**
  496. Sets the port to use for accepting connections from
  497. clients. The default is 3470. Specify 0 to indicate
  498. that any free port can be used. The port number can
  499. be set only if the proxy server is not running.
  500. @param port The port to use for accepting connections
  501. from clients.
  502. **/
  503. public void setPort (int port)
  504. {
  505. if (isStarted ())
  506. throw new ExtendedIllegalStateException ("port", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED);
  507. if ((port < 0) || (port > 65535))
  508. throw new ExtendedIllegalArgumentException ("port", ExtendedIllegalArgumentException.RANGE_NOT_VALID);
  509. port_ = port;
  510. }
  511. /**
  512. Sets the port to use for accepting Secure Sockets
  513. Layer (SSL) connections from clients. The default
  514. is 3471. Specify 0 to indicate that any free port
  515. can be used. The proxy server will only accept SSL
  516. connections when the com.ibm.sslight package is in
  517. the classpath. The secure port number can be set
  518. only if the proxy server is not running.
  519. @param securePort The port to use for accepting Secure
  520. Sockets Layer (SSL) connections from
  521. clients.
  522. **/
  523. public void setSecurePort (int securePort) //$B1C
  524. {
  525. if (isStarted ())
  526. throw new ExtendedIllegalStateException ("port", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED);
  527. if ((securePort < 0) || (securePort > 65535))
  528. throw new ExtendedIllegalArgumentException ("port", ExtendedIllegalArgumentException.RANGE_NOT_VALID);
  529. securePort_ = securePort;
  530. }
  531. /**
  532. Sets whether to print status and connection information
  533. to System.out. The default is false.
  534. @param verbose true to print status and connection
  535. information to System.out, false otherwise.
  536. **/
  537. public void setVerbose (boolean verbose)
  538. {
  539. Verbose.setVerbose (verbose);
  540. }
  541. /**
  542. Starts the proxy server. This starts several threads which process
  543. client requests, and then return immediately. The proxy server is still
  544. running after the return. Use <a href="#stop()">stop()</a> to stop all threads
  545. for this proxy server.
  546. **/
  547. public void start()
  548. {
  549. // Throw an exception if the proxy server is already started.
  550. if (threadGroup_ != null)
  551. throw new ExtendedIllegalStateException (ExtendedIllegalStateException.PROXY_SERVER_ALREADY_STARTED);
  552. // Initialize a thread group for this proxy server. This will make
  553. // it much easier to stop all running threads.
  554. threadGroup_ = new Vector ();
  555. // Initialize the server socket. If the port is in use, send the
  556. // existing proxy server a configure request.
  557. try {
  558. PSServerSocketContainerAdapter serverSocket = new PSServerSocketContainer (port_);
  559. port_ = serverSocket.getLocalPort ();
  560. PSController controller = new PSController (threadGroup_,
  561. this,
  562. load_,
  563. loadBalancer_,
  564. configuration_,
  565. serverSocket);
  566. controller.start ();
  567. threadGroup_.addElement (controller);
  568. Verbose.println (ResourceBundleLoader.getText ("PROXY_SERVER_LISTENING", serverSocket, Integer.toString (port_)));
  569. }
  570. catch (BindException e) {
  571. Verbose.println (ResourceBundleLoader.getText ("PROXY_ALREADY_LISTENING", Integer.toString (port_)));
  572. try {
  573. PxPeerConnection peerConnection = new PxPeerConnection (InetAddress.getLocalHost ().getHostName () + ":" + port_);
  574. peerConnection.configure (configuration_);
  575. peerConnection.close ();
  576. return;
  577. }
  578. catch (UnknownHostException e1) {
  579. if (Trace.isTraceErrorOn ())
  580. Trace.log (Trace.ERROR, "Peer host is unknown.", e);
  581. errors_.println (e.getMessage ());
  582. }
  583. }
  584. catch (IOException e) {
  585. if (Trace.isTraceErrorOn ())
  586. Trace.log (Trace.ERROR, "Error opening server socket.", e);
  587. errors_.println (e.getMessage ());
  588. }
  589. // Check to see if the sslight classes are in the classpath.
  590. // If so, we can handle SSL, otherwise we can not.
  591. //
  592. // Note that we do not need to send a configure request in
  593. // this case, since the server will already be reconfigured
  594. // using the non-secure socket (and it is the same server,
  595. // just listenening to 2 ports, not 2 servers). //$B1C
  596. try
  597. {
  598. Class.forName ("com.ibm.sslight.SSLContext");
  599. // The SSL Proxy port will only be started if the keyringName and keyringPwd are //$B1A
  600. // correctly specified. If either command line option is bad, the Proxy Server
  601. // will not do SSL, but will continue to handle regular Proxy communications.
  602. if (keyringName_ != null && keyringPwd_ != null) //$B1A
  603. {
  604. // Since SSLight is no longer support, access this class (in include tree) via reflection
  605. // int/String/String
  606. Class classPSSecureServerSocketContainer = Class.forName("com.ibm.as400.access.PSSecureServerSocketContainer");
  607. Class[] parameterTypes = new Class[3];
  608. parameterTypes[0] = Integer.TYPE;
  609. parameterTypes[1] = "".getClass();
  610. parameterTypes[2] = "".getClass();
  611. Constructor constructor = classPSSecureServerSocketContainer.getConstructor(parameterTypes);
  612. Object[] args = new Object[3];
  613. args[0] = new Integer(securePort_);
  614. args[1] = keyringName_;
  615. args[2] = keyringPwd_;
  616. Object serverSocket = constructor.newInstance(args);
  617. try //$B1A
  618. {
  619. parameterTypes = new Class[0];
  620. Method getLocalPortMethod = classPSSecureServerSocketContainer.getMethod("getLocalPort", parameterTypes);
  621. args = new Object[0];
  622. securePort_ = ((Integer)getLocalPortMethod.invoke(serverSocket, args)).intValue();
  623. PSController controller = new PSController (threadGroup_,
  624. this,
  625. load_,
  626. loadBalancer_,
  627. configuration_,
  628. (PSServerSocketContainerAdapter) serverSocket);
  629. controller.start ();
  630. threadGroup_.addElement (controller);
  631. Verbose.println (ResourceBundleLoader.getText ("PROXY_SERVER_LISTENING", serverSocket, Integer.toString (securePort_)));
  632. }
  633. catch (NullPointerException e) //$B1A
  634. { //$B1A
  635. // If the proxy server failed to load the proxy keyring, then we don't //$B1A
  636. // want to display a message saying the secure proxy server was started. Instead display //$B1A
  637. // a message saying it didn't start and the details can be seeing by turning ERROR tracing on. //$B1A
  638. Verbose.println (ResourceBundleLoader.getText ("PROXY_SERVER_LISTENING", //$B1A
  639. "Secure proxy server NOT", //$B1A
  640. Integer.toString (securePort_))); //$B1A
  641. }
  642. }
  643. }
  644. catch (NoSuchMethodException e) {
  645. if (Trace.isTraceDiagnosticOn ())
  646. Trace.log (Trace.DIAGNOSTIC, "NoSuchMethodException using SSLight classes SSL support is not enabled.");
  647. errors_.println (e.getMessage ());
  648. }
  649. catch (InvocationTargetException e ) {
  650. if (Trace.isTraceDiagnosticOn ())
  651. Trace.log (Trace.DIAGNOSTIC, "InvocationTargetException using SSLight classes SSL support is not enabled.");
  652. errors_.println (e.getMessage ());
  653. Throwable e2 = e.getCause();
  654. if (e2 != null) {
  655. errors_.println (e2.getMessage ());
  656. }
  657. }
  658. catch (InstantiationException e) {
  659. if (Trace.isTraceDiagnosticOn ())
  660. Trace.log (Trace.DIAGNOSTIC, "InstantiationException using SSLight classes SSL support is not enabled.");
  661. errors_.println (e.getMessage ());
  662. }
  663. catch (ClassNotFoundException e)
  664. {
  665. if (Trace.isTraceDiagnosticOn ())
  666. Trace.log (Trace.DIAGNOSTIC, "SSLight classes are not in the classpath, SSL support is not enabled.");
  667. } catch (IllegalArgumentException e) {
  668. if (Trace.isTraceDiagnosticOn ())
  669. Trace.log (Trace.DIAGNOSTIC, "IllegalArgumentException using SSLight classes SSL support is not enabled.");
  670. errors_.println (e.getMessage ());
  671. } catch (IllegalAccessException e) {
  672. if (Trace.isTraceDiagnosticOn ())
  673. Trace.log (Trace.DIAGNOSTIC, "IllegalAccessException using SSLight classes SSL support is not enabled.");
  674. errors_.println (e.getMessage ());
  675. }
  676. }
  677. /**
  678. Stops the proxy server. This stops all threads relating to this
  679. proxy server.
  680. **/
  681. public void stop()
  682. {
  683. // Throw an exception if the proxy server is not started.
  684. if (threadGroup_ == null)
  685. throw new ExtendedIllegalStateException (ExtendedIllegalStateException.PROXY_SERVER_NOT_STARTED);
  686. // Force the load's active connection count to be accurate.
  687. load_.allConnectionsClosed ();
  688. // Stop all of the threads safely.
  689. Enumeration list = threadGroup_.elements ();
  690. while (list.hasMoreElements ())
  691. ((StoppableThread) list.nextElement ()).stopSafely ();
  692. // Clear the thread group.
  693. threadGroup_ = null;
  694. }
  695. }