KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > server > core > channel > AdminChannel


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /**
25  * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
26  *
27  * Copyright 2001-2002 by iPlanet/Sun Microsystems, Inc.,
28  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
29  * All rights reserved.
30  */

31 package com.sun.enterprise.admin.server.core.channel;
32
33 import java.io.File JavaDoc;
34 import java.io.FileInputStream JavaDoc;
35 import java.io.FileOutputStream JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.ObjectOutputStream JavaDoc;
38 import java.io.PrintWriter JavaDoc;
39 import java.io.StringWriter JavaDoc;
40 import java.net.InetAddress JavaDoc;
41 import java.rmi.NoSuchObjectException JavaDoc;
42 import java.rmi.RemoteException JavaDoc;
43 import java.rmi.server.RemoteStub JavaDoc;
44 import java.rmi.server.UnicastRemoteObject JavaDoc;
45 import java.security.SecureRandom JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.logging.Level JavaDoc;
48 import java.util.logging.Logger JavaDoc;
49
50 import com.sun.enterprise.admin.common.constant.AdminConstants;
51 import com.sun.enterprise.admin.event.AdminEventResult;
52 import com.sun.enterprise.server.Constants;
53 import com.sun.enterprise.instance.ServerManager;
54 import com.sun.appserv.server.ServerLifecycleException;
55
56 import com.sun.enterprise.util.SystemPropertyConstants;
57
58 //i18n import
59
import com.sun.enterprise.util.i18n.StringManager;
60
61 /**
62  * Admin channel is used for communication between admin service agents
63  * running in different server instances.
64  */

65 public class AdminChannel {
66
67     /**
68      * A reference to logger object
69      */

70     static Logger JavaDoc logger = Logger.getLogger(AdminConstants.kLoggerName);
71
72     static String JavaDoc instanceRoot = null;
73     
74     static final String JavaDoc fileSeparator = "/";
75
76     static final int SEED_LENGTH = 16;
77
78     private static AdminChannelServer server = null;
79
80     private static HashMap JavaDoc rmiClientMap = new HashMap JavaDoc();
81
82     // i18n StringManager
83
private static StringManager localStrings =
84         StringManager.getManager( AdminChannel.class );
85
86     /**
87      * Create a RMI channel. This method creates a server object and exposes
88      * the stub on local filesystem.
89      */

90     public static void createRMIChannel() throws ServerLifecycleException {
91         try {
92             server = createServerObject();
93             saveStubToFile(server.getRemoteStub());
94         } catch (Exception JavaDoc e) {
95             warn(SERVER_CREATION_ERRCODE);
96             debug(e);
97             throw new ServerLifecycleException(e);
98         }
99     }
100
101     /**
102      * Remove RMI channel. Remove the server object from JVM (do not accept
103      * any more calls and abort in process calls) and clean up the stub
104      * exposed on filesystem.
105      */

106     public static void destroyRMIChannel() throws ServerLifecycleException {
107         if (server != null) {
108             server.setChannelStopping();
109             try {
110                 UnicastRemoteObject.unexportObject(server, true);
111             } catch (NoSuchObjectException JavaDoc nsoe) {
112                 throw new ServerLifecycleException(nsoe);
113             }
114         }
115         deleteStubFile();
116     }
117
118     /**
119      * Create a shared secret. The shared secret is saved on the filesystem
120      * and is verified during every call on admin channel.
121      */

122     public static void createSharedSecret() throws ServerLifecycleException {
123         assertAdminServerChannelNotNull();
124         String JavaDoc fileName = getSeedFileName();
125         File JavaDoc seedFile = new File JavaDoc(fileName);
126         byte[] prevSeed = getPreviousSeed(seedFile);
127         SecureRandom JavaDoc sr = new SecureRandom JavaDoc(prevSeed);
128         byte[] seed = new byte[SEED_LENGTH];
129         sr.nextBytes(seed);
130         saveSeedToFile(seed, seedFile);
131         server.setSharedInfo(seed);
132         server.setChannelStarting();
133     }
134
135     /**
136      * Enable reconfiguration of Sun ONE Web Server core.
137      */

138     public static void enableWebCoreReconfig() {
139         try {
140             ReconfigHelper.enableWebCoreReconfig();
141         } catch (Throwable JavaDoc t) {
142             // If reconfiguration could not be enabled log a warning
143
// message and continue
144
warn(RECONFIG_ENABLE_ERROR );
145             debug(t);
146         }
147     }
148
149     /**
150      * Get RMI client for specified instance.
151      */

152     public static RMIClient getRMIClient(String JavaDoc instanceName) {
153         //KE FIXME: All of this code is obsolete whent the stub file
154
//is removed.
155
RMIClient client = (RMIClient)rmiClientMap.get(instanceName);
156         if (client == null) {
157             client = new RMIClient(getStubFileName(),
158                     getSeedFileName());
159             rmiClientMap.put(instanceName, client);
160         }
161         return client;
162     }
163
164     /**
165      * Set channel to ready state. This means that the server instance that
166      * initialized the channel is ready to serve client requests.
167      * @throws RuntimeException if the channel has not been initialized
168      */

169     public static void setRMIChannelReady() {
170         assertAdminServerChannelNotNull();
171         server.setChannelReady();
172     }
173
174     public static void setRMIChannelStopping() {
175         assertAdminServerChannelNotNull();
176         server.setChannelStopping();
177     }
178
179     /**
180      * Set the channel to failed state. If the client detects this state, then
181      * it will try to get the port number that caused failure from the channel.
182      * @param port port number.
183      */

184     public static void setRMIChannelAborting(int port) {
185         assertAdminServerChannelNotNull();
186         server.setChannelAborting(port);
187     }
188     
189     static final String JavaDoc stubFileName = "admch";
190
191     //Begin EE: 4921345 instanceRoot cannot be statically initialized since it relies on
192
//a system property which may not be set until startup time. This removes the
193
//dependency ond AdminService.
194
static String JavaDoc getInstanceRoot() {
195         if (instanceRoot == null) {
196             instanceRoot = System.getProperty(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY);
197         }
198         return instanceRoot;
199     }
200     //End EE: 4921345 instanceRoot cannot be statically initialized since it relies on
201
//a system property which may not be set until startup time. This removes the
202
//dependency ond AdminService.
203

204     static String JavaDoc getStubFileName() {
205         return getInstanceRoot() + fileSeparator
206                 + Constants.CONFIG_DIR_NAME + fileSeparator
207                 + stubFileName;
208     }
209
210     static final String JavaDoc seedFileName = "admsn";
211
212     static String JavaDoc getSeedFileName() {
213         return getInstanceRoot() + fileSeparator
214                 + Constants.CONFIG_DIR_NAME + fileSeparator
215                 + seedFileName;
216     }
217
218     /**
219      * Create server object that serves RMI client. If local loopback address
220      * can be determined the server object listens on only local loopback
221      * address, otherwise it listens on all interfaces (default RMI behavior).
222      */

223     private static AdminChannelServer createServerObject()
224             throws RemoteException JavaDoc {
225         AdminChannelServer server = null;
226         InetAddress JavaDoc localAddress = getLocalLoopbackAddress();
227         if (localAddress == null) {
228             server = new AdminChannelServer();
229         } else {
230             LocalRMIClientSocketFactory csf =
231                     new LocalRMIClientSocketFactory(localAddress);
232             LocalRMIServerSocketFactory ssf =
233                     new LocalRMIServerSocketFactory(localAddress);
234             server = new AdminChannelServer(0, csf, ssf);
235             server.setLocalAddress(localAddress);
236         }
237         return server;
238     }
239
240     /**
241      * Get local loopback address.
242      * @return local loopback address, if it can be determined, null otherwise
243      */

244     private static InetAddress JavaDoc getLocalLoopbackAddress() {
245         InetAddress JavaDoc localAddr = null;
246         try {
247             localAddr = InetAddress.getByName(null);
248             if (!localAddr.isLoopbackAddress()) {
249                 localAddr = null;
250             }
251         } catch (Throwable JavaDoc t) {
252             // Catch all exceptions and return null to the caller
253
localAddr = null;
254         }
255         return localAddr;
256     }
257
258     /**
259      * Get previous seed. This seed is read either from previous session's
260      * shared secret file or initialized using SecureRandom.getSeed (if the
261      * shared secret file does not exist). This seed is then used with
262      * SecureRandom to generate next key value.
263      */

264     private static byte[] getPreviousSeed(File JavaDoc seedFile) {
265         boolean haveSeed = false;
266         byte[] prevSeed = new byte[SEED_LENGTH];
267
268         // Using secure.seed bits to mix in a few extra bits of randomness
269
// since we cannot use SecureRandoms built-in seeding.
270
// Read bugs 4703002 and 4709460 for some background on this.
271
SecureRandom JavaDoc sr =
272             com.sun.enterprise.server.J2EEServer.secureRandom;
273         assert (sr != null); // was initialized early on startup
274
sr.setSeed(System.currentTimeMillis());
275         
276         if (seedFile.exists() && seedFile.canRead()) {
277             FileInputStream JavaDoc fis = null;
278             try {
279                 fis = new FileInputStream JavaDoc(seedFile);
280                 fis.read(prevSeed);
281                 sr.setSeed(prevSeed);
282                 sr.nextBytes(prevSeed);
283                 haveSeed = true;
284             } catch (IOException JavaDoc ioe) {
285                 warn(KEY_READ_ERROR);
286                 debug(ioe);
287             } finally {
288                 if (fis != null) {
289                     try {
290                         fis.close();
291                     } catch (IOException JavaDoc ioe) {
292                     }
293                 }
294             }
295         }
296         if (!haveSeed) {
297             sr.nextBytes(prevSeed);
298         }
299         return prevSeed;
300     }
301
302     /**
303      * Save shared secret in file (so that it becomes shared)
304      */

305     private static void saveSeedToFile(byte[] seed, File JavaDoc seedFile) {
306         FileOutputStream JavaDoc fos = null;
307         try {
308             fos = new FileOutputStream JavaDoc(seedFile);
309             fos.write(seed);
310         } catch (IOException JavaDoc ioe) {
311             warn(KEY_WRITE_ERROR);
312             debug(ioe);
313         } finally {
314             if (fos != null) {
315                 try {
316                     fos.close();
317                 } catch (IOException JavaDoc ioe) {
318                 }
319             }
320         }
321     }
322
323     /**
324      * Save remote stub for admin channel server to file.
325      */

326     private static void saveStubToFile(RemoteStub JavaDoc stub) {
327         String JavaDoc fileName = getStubFileName();
328         try {
329             File JavaDoc file = new File JavaDoc(fileName);
330             FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(file);
331             ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(fos);
332             oos.writeObject(stub);
333             fos.close();
334         } catch (Exception JavaDoc e) {
335             String JavaDoc msg = localStrings.getString( "admin.server.core.channel.unable_saving_stub_to_file", fileName );
336             throw new RuntimeException JavaDoc( msg, e );
337         }
338     }
339
340     /**
341      * Cleanup stub file (is invoked on shutdown)
342      */

343     private static void deleteStubFile() {
344         String JavaDoc fileName = getStubFileName();
345         new File JavaDoc(fileName).delete();
346     }
347
348     /**
349      * Assert than Admin server channel is not null.
350      * @throws RuntimeException if admin server channel is null.
351      */

352     private static final void assertAdminServerChannelNotNull() {
353         if (server == null) {
354             String JavaDoc msg = localStrings.getString( "admin.server.core.channel.admin_server_channel_not_initialized" );
355             throw new RuntimeException JavaDoc( msg );
356         }
357     }
358
359     static void warn(String JavaDoc s) {
360         logger.warning(s);
361     }
362
363     static void warn(String JavaDoc msgkey, String JavaDoc obj1) {
364         logger.log(Level.WARNING, msgkey, obj1);
365     }
366
367     static void debug(String JavaDoc s) {
368         logger.fine(s);
369     }
370
371     static void debug(String JavaDoc msgkey, String JavaDoc obj1) {
372         logger.log(Level.FINE, msgkey, obj1);
373     }
374
375     static void debug(String JavaDoc msgkey, Object JavaDoc[] objarr) {
376         logger.log(Level.FINE, msgkey, objarr);
377     }
378
379     static void debug(Throwable JavaDoc t) {
380         logger.log(Level.FINE, t.getMessage(), t);
381     }
382
383     static void trace(Throwable JavaDoc t) {
384         logger.log(Level.FINEST, t.getMessage(), t);
385     }
386
387     static final String JavaDoc LOCAL_ONLY_ACCESS = "high";
388     static final String JavaDoc ALLOW_ALL_ACCESS = "none";
389
390     /**
391      * Get access level. FIX to use config parameter
392      */

393     static String JavaDoc getAccessLevel() {
394         return LOCAL_ONLY_ACCESS;
395     }
396
397     static final String JavaDoc ENFORCE = "high";
398     static final String JavaDoc REQUIRE_KEY = "medium";
399     static final String JavaDoc NO_ENFORCE = "low";
400
401     /**
402      * Get key check level. FIX to use config parameter.
403      */

404     static String JavaDoc getKeyCheckLevel() {
405         return ENFORCE;
406     }
407
408     /**
409      * Is Auto Refresh enabled for RMIClient objects (so they will keep on
410      * scanning file system for changes to stub file and reset themselves).
411      * FIX to use config parameter
412      */

413     static boolean getClientAutoRefreshEnabled() {
414         return true;
415     }
416
417     /**
418      * How frequently should the RMI client objects refresh themselves (in
419      * milliseconds). FIX to use config parameter
420      */

421     static long getClientAutoRefreshInterval() {
422         // 1 minute
423
return (1 * 60 * 1000);
424     }
425
426     static final String JavaDoc RECONFIG_ENABLE_ERROR = "channel.reconfig_enable_error";
427     static final String JavaDoc SERVER_CREATION_ERRCODE = "channel.creation_error";
428     static final String JavaDoc KEY_READ_ERROR = "channel.key_read_error";
429     static final String JavaDoc KEY_WRITE_ERROR = "channel.key_write_error";
430 }
431
Popular Tags