Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/flexstor/common/util/AppServerClient.java


1   /*
2    * AppServerClient.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:31 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.common.util;
12  
13  import java.io.IOException;
14  import java.io.PrintWriter;
15  import java.io.StringWriter;
16  import java.rmi.Naming;
17  import java.rmi.RemoteException;
18  
19  import com.flexstor.common.constants.ServicesI;
20  import com.flexstor.common.data.ActionData;
21  import com.flexstor.common.data.ActionResult;
22  import com.flexstor.common.exceptions.AppServiceFailedException;
23  import com.flexstor.common.resources.Resources;
24  import com.flexstor.common.services.RMIServiceBrokerI;
25  import com.flexstor.common.settings.Settings;
26  
27  /**
28   * This class wraps around the proxy and encapsulates any CORBA specific
29   * code and mappings.
30   */
31  public class AppServerClient
32     implements Runnable
33  {
34     private static String                sVersion;
35     private static RMIServiceBrokerI   broker   = null;
36     private static boolean               bRetryRequest = true; // To retry remote request just once in
37                                                                // case of failure.
38  
39     public AppServerClient()
40     {
41        super();
42        sVersion = Resources.get(5049);
43     }
44  
45     /**
46      * Initializes the remote connection in a new thread,
47      * tests after n milliseconds for success, otherwise throws a NamingException
48      * @param nMilliSeconds ms to wait for check
49      */
50     public static void initialize(int nMilliSeconds)
51        throws RemoteException
52     {
53        long time     = 0L;
54        long duration = 0L;
55  
56        Thread t = new Thread( new AppServerClient(), "OAS Lookup Thread");
57        time = System.currentTimeMillis();
58  
59        t.start();
60        try
61        {
62           t.join(nMilliSeconds); // wait nMilliSeconds to perform lookup, then cancel
63           duration = System.currentTimeMillis() - time;
64           Diagnostic.trace(Diagnostic.CAT_OAS, "Lookup duration[ms]=" + duration);
65        }
66        catch(InterruptedException e) {}
67        if (broker == null)
68        {
69           if (duration >= nMilliSeconds )
70              Diagnostic.trace(Diagnostic.CAT_OAS, "Naming lookup timed out after " + nMilliSeconds + "ms." );
71           throw new RemoteException("Unable to connect to application server");
72        }
73     }
74  
75  
76     private void init ( )
77        throws Exception
78     {
79  
80        Diagnostic.trace(Diagnostic.CAT_OAS, "Initalizing Service Broker");
81  
82        // Try the naming lookup.
83        String sServer = Settings.getString( Settings.CLIENT_RMI_HOST );
84        String sPort   = Settings.getString( Settings.CLIENT_RMI_PORT );
85        String sLookupString = "rmi://" + sServer;
86        if ( sPort != null && sPort.equals("") == false )
87           sLookupString += ":" + sPort;
88        sLookupString += "/" + ServicesI.SERVICE_BROKER;
89  
90        Diagnostic.trace(Diagnostic.CAT_OAS, "    Looking for: " + sLookupString);
91        broker = (RMIServiceBrokerI) Naming.lookup(sLookupString);
92        Diagnostic.trace(Diagnostic.CAT_OAS, "Broker:  " + broker);
93        Diagnostic.trace(Diagnostic.CAT_OAS, "Naming lookup completed successfully." );
94  
95        sVersion = broker.ping();
96        Diagnostic.trace(Diagnostic.CAT_OAS, "ServiceBroker version: " + sVersion);
97        Settings.addString ( Settings.APP_SERVER_VERSION, sVersion );
98     }
99     /**
100     * Perform initialization in a new thread, ignores any exceptions
101     */
102    public void run()
103    {
104       try
105       {
106          init();
107       }
108       catch(Throwable t)
109       {
110          Diagnostic.trace(Diagnostic.CAT_OAS, "Error initializing ServiceBroker: " + t);
111       }
112    }
113 
114    public static int getUniqueNo()
115       throws RemoteException
116    {
117       try
118       {
119          if ( broker == null )
120             // this might throw a NamingException
121             initialize( 120000 ); // wait up to 10 seconds
122 
123          int nTransId = broker.getUniqueNo();
124          if ( nTransId == -1 )
125             throw new Throwable();
126 
127          Diagnostic.trace( Diagnostic.CAT_OAS, "Retrieved Transaction Id = " + nTransId );
128 
129          bRetryRequest = true;
130 
131          return nTransId;
132       }
133       catch( Throwable e )
134       {
135          broker = null;
136          if (bRetryRequest)
137          {
138             // Set to false, no more retries after this
139             bRetryRequest = false;
140             return getUniqueNo();
141          }
142          else
143          {
144             // Set to true, so next request has a chance to retry
145             bRetryRequest = true;
146             throw ( new RemoteException( "Unable to retrieve Transaction Id.", e.fillInStackTrace() ) );
147          }
148       }
149    }
150 
151 
152    /**
153     * Adds the QItem (data wrapper) to the remote service queue.
154     * This is an asynchronous invocation. i.e. the call returns
155     * before the service has finished.
156     * @param qi the new QItem
157     * @return the result data containing the assigned transaction id
158     */
159    public static ActionResult addQItem(ActionData qi)
160       throws RemoteException
161    {
162       return remoteRequest(false, qi);
163    }
164 
165    /**
166     * Invokes the service synchronously, i.e. the call
167     * return after the service has completed.
168     * @param qi the QItem
169     * @return the result data containing the assigned transaction id
170     */
171    public static ActionResult invokeImmediately(ActionData qi)
172       throws RemoteException
173    {
174       return remoteRequest(true, qi);
175    }
176 
177    /**
178     * Performs the remote request.
179     * Re-throws any exceptions and wraps them into a RemoteException.
180     * This avoids code changes in all users of this class.
181     * @param bImmediately indicates if this is a synchronous request
182     * @param the QItem
183     * @throw java.rmi.RemoteException
184     */
185    private static ActionResult remoteRequest(boolean bImmediately, ActionData qi)
186       throws AppServiceFailedException
187    {
188       ActionResult result;
189 
190       try
191       {
192          if (broker == null)
193             // this might throw a NamingException
194             initialize(120000); // wait up to 10 seconds
195 
196          if (bImmediately)
197             result = (ActionResult)broker.invokeImmediately ( qi );
198          else
199             result = (ActionResult)broker.addQItem ( qi );
200 
201          Diagnostic.trace(Diagnostic.CAT_OAS, "Transaction created. Id=" + result.getId());
202 
203          // Set to true, so next request has a chance to retry.
204          bRetryRequest = true;
205          return result;
206       }
207 
208 
209       // any unchecked exception/error
210       catch(Throwable e)
211       {
212          broker   = null;
213          int resID;
214          String trace = null;
215          if (bRetryRequest)
216          {
217             // Set to false, no more retries after this
218             bRetryRequest = false;
219             return remoteRequest(bImmediately, qi);
220          }
221          else
222          {
223             bRetryRequest = true;
224          }
225          if ( e instanceof RemoteException )
226          {
227             resID = 6188;
228             trace = getStackTrace(e);
229          }
230          else if (e instanceof NoClassDefFoundError)
231          {
232            resID = 6190;
233            trace = getStackTrace(e);
234          }
235          else if (e instanceof ClassNotFoundException)
236          {
237            resID = 6190;
238            trace = getStackTrace(e);
239          }
240          else
241          {
242            resID = 6189;
243            trace = getStackTrace(e);
244          }
245          throw ( new AppServiceFailedException ( resID, trace, e ) );
246       }
247    }  // remoteRequest
248 
249    private static String getStackTrace(Throwable t)
250    {
251       String sTrace = "";
252 
253       try
254       {
255          StringWriter sw = new StringWriter();
256          PrintWriter  pw = new PrintWriter(sw, true);
257          t.printStackTrace(pw);
258          sTrace = sw.toString();
259          pw.close();
260          sw.close();
261 
262          // Needed for JDK 1.1 (Only Java2 throws this exception)
263          if ( false )
264             throw new IOException();
265       }
266       catch ( IOException e )
267       {
268       }
269 
270       return sTrace;
271    }
272 
273 }  // end of class