001: /*
002: * $Id: SrapClient.java,v 1.24 2006/06/21 06:07:40 vp154433 Exp $
003: * $Source: /m/portal/ps/srap/src/com/sun/portal/rproxy/configservlet/client/SrapClient.java,v $
004: * $Log: SrapClient.java,v $
005: * Revision 1.24 2006/06/21 06:07:40 vp154433
006: * BUG ID 6440920 Added method to get the portalServer available in the portal server list from the gateway profile, for gateway to pick the portal server URL after success login from the gateway profile instead of the "default success login URL" stored in Access Manager
007: *
008: * Revision 1.23 2005/11/30 11:27:16 ss150821
009: * 6356996 - Srap Code base needs to save files in the unix file format and not windows
010: *
011: * Revision 1.22 2005/03/01 10:22:37 np145014
012: * CR 6224556
013: *
014: * Revision 1.21 2005/02/25 09:44:11 ss150821
015: * RFE 6223490 - SRA Should use JDK based logging, changed to start throwing the full stacktrace for the exception in the logs
016: *
017: * Revision 1.20 2005/02/23 09:14:06 ss150821
018: * RFE 6223490 - SRA Should use JDK based logging
019: *
020: * Revision 1.19 2005/02/23 09:13:05 ss150821
021: * RFE 6223490 - SRA Should use JDK based logging
022: *
023: * Revision 1.18 2004/07/27 12:52:04 vt126379
024: * RFE#5075809, CRT#99
025: *
026: * Revision 1.17 2004/05/10 04:48:18 ss150821
027: * Codefix for 5043753 - StackOverflowError fix
028: *
029: * Revision 1.16 2003/09/01 12:33:10 mm132998
030: * Bug ID : 4911706 , 4801456
031: *
032: * Revision 1.15 2003/09/01 12:11:06 mm132998
033: * Bug ID : 4911706 , 4801456
034: *
035: * Revision 1.14 2003/08/11 13:36:57 mm132998
036: * Bug : 4893409
037: *
038: * Revision 1.13 2003/07/21 11:51:03 mm132998
039: * Bug 4889079
040: *
041: * Revision 1.12 2003/07/21 11:21:16 mm132998
042: * Bug 4889079
043: *
044: * Revision 1.11 2003/07/15 13:04:39 mm132998
045: * Beta showstopper - unresolved issues
046: *
047: * Revision 1.10 2003/06/10 12:23:08 mm132998
048: * Bug : 4875896 , Fix for opening ServerSockets only to 127.0.0.1
049: *
050: * Revision 1.9 2003/06/04 14:13:30 mm132998
051: * Bug ID : 4726157 - changes to SessionWrapper to handle Application Login SSOToken
052: *
053: * Revision 1.8 2003/05/30 12:54:29 mm132998
054: * Session Validation at server side
055: *
056: * Revision 1.7 2003/05/22 10:50:16 rt130506
057: * Netlet Proxy HA Changes
058: *
059: * Revision 1.6 2003/05/20 13:22:05 rt130506
060: * Rewriter Proxy Changes
061: *
062: * Revision 1.5 2003/03/24 07:27:37 bv131302
063: * 4824585 - make sure that the server is in the portalserver list
064: *
065: * Revision 1.4 2002/08/21 11:23:37 bv131302
066: * fix for 4730563
067: *
068: * Revision 1.3 2002/07/29 05:07:15 rt130506
069: * CRT 1742
070: *
071: * Revision 1.2 2002/07/02 14:08:13 rt130506
072: * CRT 1575
073: *
074: * Revision 1.1 2002/06/14 09:53:48 rt130506
075: * SRAP rebranding
076: *
077: * Revision 1.7 2002/06/12 07:55:59 bv131302
078: * more rebranding - filenames
079: *
080: * Revision 1.6 2002/06/11 16:02:10 bv131302
081: * new branded
082: *
083: * Revision 1.5 2002/05/28 09:38:44 mm132998
084: * Bug id - 4692062 , CRT - 1215 , Desc - Support for iDSAME in https mode.
085: *
086: * Revision 1.4 2002/05/13 06:22:25 mm132998
087: * Perf related modifications
088: *
089: * Revision 1.3 2002/02/21 06:03:10 mm132998
090: * Checkin for Bug id : 4640268 - RProxy migration to iDSAME
091: *
092: *
093: */
094: package com.sun.portal.rproxy.configservlet.client;
095:
096: import java.io.IOException;
097: import java.io.ObjectInputStream;
098: import java.io.ObjectOutputStream;
099: import java.net.MalformedURLException;
100: import java.net.URL;
101: import java.net.URLConnection;
102: import java.util.logging.Level;
103: import java.util.logging.Logger;
104:
105: import com.iplanet.sso.SSOToken;
106: import com.iplanet.sso.SSOTokenManager;
107: import com.sun.portal.log.common.PortalLogger;
108: import com.sun.portal.rproxy.configservlet.Request;
109: import com.sun.portal.rproxy.configservlet.Response;
110: import com.sun.portal.util.GWLogManager;
111: import com.sun.portal.util.HostAvailabilityEventImpl;
112: import com.sun.portal.util.HostAvailabilityMediator;
113: import com.sun.portal.util.SSOUtil;
114:
115: import com.sun.portal.rproxy.monitoring.MonitoringSubsystem;
116: import com.sun.portal.util.*;
117:
118: public class SrapClient {
119:
120: private static HostChooser hostChooser = new HostChooser();
121:
122: private static final String PORTAL_SERVER = "__sra_portal_server__";
123:
124: // private static Logger logger =
125: // Logger.getLogger("com.sun.portal.sra.rproxy");
126: private static Logger logger = PortalLogger
127: .getLogger(SrapClient.class);
128:
129: /*
130: * Avoids single point of failure of the GW in a multi portal instance
131: * configuration. Fetches profile from various available list of portal
132: * instances.
133: *
134: * Also implements a simple round-robin load balancing algorithm to
135: * distribute profile requests to various portal intances. Implements a kind
136: * of stickeness to of requests to the same portal instance for performance
137: *
138: * A kind of recursive function, Implementation similiar to chain of
139: * responsibility with depth 2 @ see getSessionServer(); @ see
140: * com.sun.portal.rproxy.configservlet.HostChooser @ see
141: * com.sun.portal.util.HostAvailabilityEvent @ see
142: * com.sun.portal.util.HostAvailabilityMediator @ see
143: * com.sun.portal.util.HostAvailabilityEventImpl
144: */
145:
146: public static Response execute(Request request)
147: throws SendRequestException, GetResponseException {
148: URLConnection conn = null;
149: String portalHost = null;
150: try {
151: request.setGatewaySessionID();
152: // System.out.println("Token ID set to :
153: // "+request.getGatewaySessionID());
154: } catch (Exception ex) {
155: // request.setGatewaySessionID();
156: // System.out.println("Token ID set to :
157: // "+request.getGatewaySessionID());
158: }
159:
160: try {
161:
162: /*
163: * get the session server associated with this request, If there
164: * exists one- for stickiness
165: */
166:
167: String sessionServerURL = getSessionServerURL(request);
168:
169: if (sessionServerURL != null) {
170:
171: /*
172: * See whether the session server associated with the request is
173: * alive if so use it
174: */
175:
176: if (hostChooser.isAvailable(sessionServerURL)) {
177: portalHost = sessionServerURL;
178: } else {
179: portalHost = hostChooser.getHost();
180: if (portalHost == null
181: || portalHost.trim().length() == 0) {
182: /*
183: * All servers down returning null
184: */
185: return null;
186: }
187: }
188: } else {
189:
190: /*
191: * Session Server is not available or the request has no session
192: * server associated with it, So choose a server from the list
193: * of avilable servers Round robin load balancing.
194: */
195:
196: portalHost = hostChooser.getHost();
197: if (portalHost == null
198: || portalHost.trim().length() == 0) {
199: /*
200: * All servers down returning null
201: */
202: return null;
203: }
204: }
205: conn = new URL(portalHost).openConnection();
206: MonitoringSubsystem
207: .handleEvent(SRAEvent.PLAIN_SOCKET_CREATED);
208: sendRequest(conn, request);
209: Response retres = getResponse(conn);
210: if (retres.getNeedRecreateSession()) {
211: GWLogManager.createAppSessionIfInvalid();
212: request.setGatewaySessionID();
213:
214: if (GWLogManager.loggingEnabled) {
215: GWLogManager.write("RProxy",
216: "App session is invalid !");
217: }
218: return execute(request);
219: }
220: return retres;
221: } catch (MalformedURLException e) {
222: throw new RuntimeException(
223: "Bad URL - check the url of the servlet");
224: } catch (SendRequestException e) {
225:
226: /*
227: * Choosen session server not available so generate a Event saying
228: * server has gone down
229: */
230:
231: HostAvailabilityEventImpl event = new HostAvailabilityEventImpl();
232: event.setHost(portalHost);
233: HostAvailabilityMediator.getHostAvailabilityMediator()
234: .notifyListeners(event);
235:
236: /*
237: * Try other available servers
238: */
239:
240: return execute(request);
241:
242: } catch (IOException ioe) {
243:
244: /*
245: * Server up but not responding - may be due to laod or network
246: * traffic So generate a event saying server not available
247: */
248: HostAvailabilityEventImpl event = new HostAvailabilityEventImpl();
249: event.setHost(portalHost);
250: HostAvailabilityMediator.getHostAvailabilityMediator()
251: .notifyListeners(event);
252:
253: /*
254: * Try other available servers
255: */
256: return execute(request);
257:
258: } finally {
259: conn = null;
260: MonitoringSubsystem
261: .handleEvent(SRAEvent.PLAIN_SOCKET_DESTROYED);
262: }
263: }
264:
265: /*
266: * @ returns the response from the boot up portal server. The boot up portal
267: * instance is the instance mentioned in the platform.conf. <instance_name>
268: * Used only to fetch the GW's profile during the GW boot up process rest of
269: * the requests get's load balanced across portal servers in case there are
270: * multiple portal instances @ see HostChooser.getBootupPortalServer() @
271: * used com.sun.portal.rproxy.configservlet.GatewayProfile @ used
272: * com.sun.portal.rproxy.configservlet.PlatformProfile
273: */
274:
275: public static Response bootupExecute(Request request)
276: throws SendRequestException, GetResponseException {
277: URLConnection conn = null;
278: String portalHost = HostChooser.getBootupPortalServer();
279: try {
280: // System.out.println("Retrieving token id ... ");
281: request.setGatewaySessionID();
282: // System.out.println("Token ID set to :
283: // "+request.getGatewaySessionID());
284: } catch (Exception ex) {
285: // request.setGatewaySessionID();
286: // System.out.println("Token ID set to :
287: // "+request.getGatewaySessionID());
288: }
289: try {
290: conn = new URL(portalHost).openConnection();
291: MonitoringSubsystem
292: .handleEvent(SRAEvent.PLAIN_SOCKET_CREATED);
293: sendRequest(conn, request);
294: return getResponse(conn);
295: } catch (Exception e) {
296: throw new RuntimeException(
297: "Bad URL - check the url of the servlet or Application Login failed");
298: } finally {
299: conn = null;
300: MonitoringSubsystem
301: .handleEvent(SRAEvent.PLAIN_SOCKET_DESTROYED);
302: }
303: }
304:
305: private static void sendRequest(URLConnection connection,
306: Request request) throws SendRequestException {
307: try {
308: connection.setDoOutput(true);
309: connection.setDoInput(true);
310: connection.setUseCaches(false);
311: connection.setAllowUserInteraction(false);
312: ObjectOutputStream objectStream = new ObjectOutputStream(
313: connection.getOutputStream());
314: objectStream.writeObject(request);
315: objectStream.flush();
316: } catch (Exception e) {
317: // e.printStackTrace();
318: // logger.log(Level.SEVERE, "Exception while sending request to
319: // server.", e);
320: logger.log(Level.SEVERE, "PSSRRPROXY_CSPRCSERVLETC004", e);
321: throw new SendRequestException(e.getMessage());
322: }
323: }
324:
325: private static Response getResponse(URLConnection connection)
326: throws GetResponseException {
327: try {
328: ObjectInputStream objectStream = new ObjectInputStream(
329: connection.getInputStream());
330: Response ret = (Response) objectStream.readObject();
331: objectStream.close();
332: return ret;
333: } catch (Exception e) {
334: // e.printStackTrace();
335: // logger.log(Level.SEVERE, "Exception while reading response to
336: // server.", e);
337: logger.log(Level.SEVERE, "PSSRRPROXY_CSPRCSERVLETC005", e);
338: throw new GetResponseException(e.getMessage());
339: }
340: }
341:
342: /*
343: * @ returns the Session Server of this Request if the client has a valid
344: * session id. Used to maintain stickyness to the same portal server
345: * instance in case the portal instance is available.
346: *
347: * Placing the request back to the same session server will be of better
348: * performance. Since there is a user profile cache implemented at the dsame
349: * servlet part. So the likelyhood of finding the object in the cache is
350: * more. @ see com.sun.portal.rproxy.server.UserProfileCache @ added Rajesh
351: * T
352: */
353:
354: private static String getSessionServerURL(Request req) {
355: String sid = req.getSSOTokenId();
356: String portalServer = null;
357: SSOToken token = null;
358:
359: if (sid == null || sid.equals("null")
360: || sid.trim().length() == 0)
361: return null;
362:
363: try {
364: SSOTokenManager manager = SSOTokenManager.getInstance();
365: token = SSOUtil.getSSOTokenNoDecode(sid);
366: MonitoringSubsystem
367: .handleEvent(SRAEvent.SSO_VALIDATION_START);
368: manager.validateToken(token);
369: MonitoringSubsystem
370: .handleEvent(SRAEvent.SSO_VALIDATION_END);
371: portalServer = token.getProperty(PORTAL_SERVER);
372: if (portalServer != null) {
373: return portalServer;
374:
375: } else {
376:
377: portalServer = hostChooser.getHost();
378: MonitoringSubsystem
379: .handleEvent(SRAEvent.SSO_SET_PROPERTY_START);
380: token.setProperty(PORTAL_SERVER, portalServer);
381: MonitoringSubsystem
382: .handleEvent(SRAEvent.SSO_SET_PROPERTY_END);
383: manager.refreshSession(token);
384: return portalServer;
385: }
386: } catch (Exception ssoEx) {
387: return null;
388: }
389:
390: /*
391: * SessionID sessid = new SessionID(sid); StringBuffer sessionServer
392: * =new StringBuffer(); try{ String protocol =
393: * sessid.getSessionServerProtocol(); String host =
394: * sessid.getSessionServer(); String port =
395: * sessid.getSessionServerPort(); if(host == null ||
396: * protocol.trim().length() == 0 || host.equals("null")) return null;
397: * sessionServer.append(protocol) .append("://").append(host)
398: * .append(":").append(port); return
399: * sessionServer.toString().toLowerCase(); }catch(RuntimeException re){
400: * //re.printStackTrace(); return null; }
401: */
402: }
403:
404: //Added for fix for bug id 6440920 Date June 20,2006
405: public static String getNextAvailablePortalHost() {
406: return hostChooser.getHost();
407: }
408: //End Of Addition
409: }
|