1 /*
   2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.rmi.RemoteException;
  25 import java.rmi.registry.Registry;
  26 import java.rmi.registry.LocateRegistry;
  27 import java.util.logging.Logger;
  28 import java.util.logging.Level;
  29 
  30 /**
  31  * The ApplicationServer class provides the other server side of the "juicer"
  32  * stress test of RMI.
  33  */
  34 public class ApplicationServer implements Runnable {
  35 
  36     /** number of remote Apple objects to export */
  37     private static final Logger logger = Logger.getLogger("reliability.orange");
  38     private static final int LOOKUP_ATTEMPTS = 5;
  39     private static final int DEFAULT_NUMAPPLES = 10;
  40     private static final String DEFAULT_REGISTRYHOST = "localhost";
  41     private static final int DEFAULT_REGISTRYPORT = -1;
  42     private final int numApples;
  43     private final String registryHost;
  44     private final int registryPort;
  45     private final Apple[] apples;
  46     private AppleUser user;
  47 
  48     ApplicationServer(int registryPort) {
  49         this(DEFAULT_NUMAPPLES, DEFAULT_REGISTRYHOST, registryPort);
  50     }
  51 
  52     ApplicationServer(int numApples, String registryHost, int registryPort) {
  53         this.numApples = numApples;
  54         this.registryHost = registryHost;
  55         this.registryPort = registryPort;
  56         apples = new Apple[numApples];
  57     }
  58 
  59     /*
  60      * On initialization, export remote objects and register
  61      * them with server.
  62      */
  63     public void run() {
  64         try {
  65             int i = 0;
  66 
  67             /*
  68              * Locate apple user object in registry.  The lookup will
  69              * occur until it is successful or fails LOOKUP_ATTEMPTS times.
  70              * These repeated attempts allow the ApplicationServer
  71              * to be started before the AppleUserImpl.
  72              */
  73             Exception exc = null;
  74             for (i = 0; i < LOOKUP_ATTEMPTS; i++) {
  75                 try {
  76                     Registry registry = LocateRegistry.getRegistry(
  77                            registryHost, registryPort);
  78                     user = (AppleUser) registry.lookup("AppleUser");
  79                     user.startTest();
  80                     break; //successfully obtained AppleUser
  81                 } catch (Exception e) {
  82                     exc = e;
  83                     Thread.sleep(10000); //sleep 10 seconds and try again
  84                 }
  85             }
  86             if (user == null) {
  87                 logger.log(Level.SEVERE, "Failed to lookup AppleUser:", exc);
  88                 return;
  89             }
  90 
  91             /*
  92              * Create and export apple implementations.
  93              */
  94             try {
  95                 for (i = 0; i < numApples; i++) {
  96                     apples[i] = new AppleImpl("AppleImpl #" + (i + 1));
  97                 }
  98             } catch (RemoteException e) {
  99                 logger.log(Level.SEVERE,
 100                     "Failed to create AppleImpl #" + (i + 1) + ":", e);
 101                 user.reportException(e);
 102                 return;
 103             }
 104 
 105             /*
 106              * Hand apple objects to apple user.
 107              */
 108             try {
 109                 for (i = 0; i < numApples; i++) {
 110                     user.useApple(apples[i]);
 111                 }
 112             } catch (RemoteException e) {
 113                 logger.log(Level.SEVERE,
 114                     "Failed to register callbacks for " + apples[i] + ":", e);
 115                 user.reportException(e);
 116                 return;
 117             }
 118         } catch (Exception e) {
 119             logger.log(Level.SEVERE, "Unexpected exception:", e);
 120         }
 121     }
 122 
 123     private static void usage() {
 124         System.err.println("Usage: ApplicationServer [-numApples <numApples>]");
 125         System.err.println("                         [-registryHost <host>]");
 126         System.err.println("                         -registryPort <port>");
 127         System.err.println("  numApples  The number of apples (threads) to use.");
 128         System.err.println("             The default is 10 apples.");
 129         System.err.println("  host       The host running rmiregistry " +
 130                                          "which contains AppleUser.");
 131         System.err.println("             The default is \"localhost\".");
 132         System.err.println("  port       The port the rmiregistry is running" +
 133                                          "on.");
 134         System.err.println();
 135     }
 136 
 137     public static void main(String[] args) {
 138         int num = DEFAULT_NUMAPPLES;
 139         int port = -1;
 140         String host = DEFAULT_REGISTRYHOST;
 141 
 142         // parse command line args
 143         try {
 144             for (int i = 0; i < args.length ; i++ ) {
 145                 String arg = args[i];
 146                 if (arg.equals("-numApples")) {
 147                     i++;
 148                     num = Integer.parseInt(args[i]);
 149                 } else if (arg.equals("-registryHost")) {
 150                     i++;
 151                     host = args[i];
 152                 } else if (arg.equals("-registryPort")) {
 153                     i++;
 154                     port = Integer.parseInt(args[i]);
 155                 } else {
 156                     usage();
 157                 }
 158             }
 159 
 160             if (port == -1) {
 161                 usage();
 162                 throw new RuntimeException("Port must be specified.");
 163             }
 164         } catch (Throwable t) {
 165             usage();
 166             throw new RuntimeException("TEST FAILED: Bad argument");
 167         }
 168 
 169         // start the client server
 170         Thread server = new Thread(new ApplicationServer(num,host,port));
 171         server.start();
 172         // main should exit once all exported remote objects are gc'd
 173     }
 174 }