~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to src/core/WebService/.svn/text-base/Global.asax.cs.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
 |
3
 
 | Copyright (c) 2007 Novell, Inc.
4
 
 | All Rights Reserved.
5
 
 |
6
 
 | This program is free software; you can redistribute it and/or
7
 
 | modify it under the terms of version 2 of the GNU General Public License as
8
 
 | published by the Free Software Foundation.
9
 
 |
10
 
 | This program is distributed in the hope that it will be useful,
11
 
 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 | GNU General Public License for more details.
14
 
 |
15
 
 | You should have received a copy of the GNU General Public License
16
 
 | along with this program; if not, contact Novell, Inc.
17
 
 |
18
 
 | To contact Novell about this file by physical or electronic mail,
19
 
 | you may find current contact information at www.novell.com 
20
 
 |
21
 
 | Author: Calvin Gaisford <cgaisford@novell.com>
22
 
 |***************************************************************************/
23
 
 
24
 
 
25
 
using System;
26
 
using System.Collections;
27
 
using System.ComponentModel;
28
 
using System.IO;
29
 
using System.Net;
30
 
using System.Net.Sockets;
31
 
using System.Text;
32
 
using System.Threading;
33
 
using System.Web;
34
 
using System.Web.SessionState;
35
 
 
36
 
using Simias;
37
 
using Simias.Client;
38
 
using Simias.Client.Event;
39
 
using Simias.Event;
40
 
using Simias.Storage;
41
 
 
42
 
namespace Simias.Web
43
 
{
44
 
        /// <summary>
45
 
        /// Summary description for Global.
46
 
        /// </summary>
47
 
        public class Global : HttpApplication
48
 
        {
49
 
                #region Class Members
50
 
 
51
 
                /// <summary>
52
 
                /// Environment variables used by apache.
53
 
                /// </summary>
54
 
                private static string EnvSimiasRunAsClient = "SimiasRunAsClient";
55
 
                private static string EnvSimiasDataDir = "SimiasDataDir";
56
 
                private static string EnvSimiasVerbose = "SimiasVerbose";
57
 
                
58
 
                /// <summary>
59
 
                /// Object used to manage the simias services.
60
 
                /// </summary>
61
 
                static private Simias.Service.Manager serviceManager;
62
 
                
63
 
                /// <summary>
64
 
                /// A thread to keep the application alive long enough to close Simias.
65
 
                /// </summary>
66
 
                private Thread keepAliveThread;
67
 
 
68
 
                /// <summary>
69
 
                /// Quit the application flag.
70
 
                /// </summary>
71
 
                private bool quit;
72
 
 
73
 
                /// <summary>
74
 
                /// Specifies whether to run as a client or server.
75
 
                /// </summary>
76
 
                private static bool runAsServer = true;
77
 
 
78
 
                /// <summary>
79
 
                /// Prints extra data for debugging purposes.
80
 
                /// </summary>
81
 
                private static bool verbose = false;
82
 
 
83
 
                /// <summary>
84
 
                /// Path to the simias data area.
85
 
                /// </summary>
86
 
                private static string simiasDataPath = null;
87
 
 
88
 
                /// <summary>
89
 
                /// Port used as an IPC between application domains.
90
 
                /// </summary>
91
 
                private static int ipcPort;
92
 
 
93
 
                /// <summary>
94
 
                /// Port used to talk local service. This will be (-1) if running
95
 
                /// in an enterprise configuration.
96
 
                /// </summary>
97
 
                private static int localServicePort = -1;
98
 
 
99
 
                #endregion
100
 
 
101
 
                #region Constructor
102
 
 
103
 
                /// <summary>
104
 
                /// Static constructor that starts only one shutdown thread.
105
 
                /// </summary>
106
 
                static Global()
107
 
                {
108
 
                        // The presedence for settings is
109
 
                        // 1. Command Line
110
 
                        // 2. Environment
111
 
                        // 3. defaults.conf (in etc)
112
 
 
113
 
                        ReadDefaultsConfig();
114
 
                        ParseEnvironmentVariables();
115
 
                        ParseConfigurationParameters( Environment.GetCommandLineArgs() );
116
 
 
117
 
 
118
 
                        // Make sure that there is a data path specified.
119
 
                        if ( simiasDataPath == null )
120
 
                        {
121
 
                                ApplicationException apEx = new ApplicationException( "The Simias data path was not specified." );
122
 
                                Console.Error.WriteLine( apEx.Message );
123
 
                                throw apEx;
124
 
                        }
125
 
 
126
 
                        if ( verbose )
127
 
                        {
128
 
                                Console.Error.WriteLine("Simias Application Path: {0}", Environment.CurrentDirectory);
129
 
                                Console.Error.WriteLine("Simias Data Path: {0}", simiasDataPath);
130
 
                                Console.Error.WriteLine("Run in {0} configuration", runAsServer ? "server" : "client" );
131
 
                                Console.Error.WriteLine("Local service port = {0}", localServicePort );
132
 
                        }
133
 
 
134
 
                        // Check the current datadir, if it's not setup then copy the bootstrap files there
135
 
                        // only do this if we are starting up as a server.
136
 
                        if( runAsServer )
137
 
                        {
138
 
                                Setup_Datadir();
139
 
                        }
140
 
 
141
 
                        // Initialize the store.
142
 
                        Store.Initialize( simiasDataPath, runAsServer, localServicePort );
143
 
                }
144
 
 
145
 
                #endregion
146
 
 
147
 
                #region Private Methods
148
 
 
149
 
                /// <summary>
150
 
                /// Parses the command line parameters to get the configuration for Simias.
151
 
                /// </summary>
152
 
                /// <param name="args">Command line parameters.</param>
153
 
                private static void ParseConfigurationParameters( string[] args )
154
 
                {
155
 
                        for ( int i = 0; i < args.Length; ++i )
156
 
                        {
157
 
                                switch ( args[ i ].ToLower() )
158
 
                                {
159
 
                                        case "--runasclient":
160
 
                                        {
161
 
                                                runAsServer = false;
162
 
                                                break;
163
 
                                        }
164
 
 
165
 
                                        case "--datadir":
166
 
                                        {
167
 
                                                if ( ( i + 1 ) < args.Length )
168
 
                                                {
169
 
                                                        simiasDataPath = args[ ++i ];
170
 
                                                }
171
 
                                                else
172
 
                                                {
173
 
                                                        ApplicationException apEx = new ApplicationException( "Error: The Simias data dir was not specified." );
174
 
                                                        Console.Error.WriteLine( apEx.Message );
175
 
                                                        throw apEx;
176
 
                                                }
177
 
 
178
 
                                                break;
179
 
                                        }
180
 
 
181
 
                                        case "--port":
182
 
                                        {
183
 
                                                if ( ( i + 1 ) < args.Length )
184
 
                                                {
185
 
                                                        localServicePort = Convert.ToInt32( args[ ++i ] );
186
 
                                                }
187
 
                                                else
188
 
                                                {
189
 
                                                        ApplicationException apEx = new ApplicationException( "Error: The local service port was not specified." );
190
 
                                                        Console.Error.WriteLine( apEx.Message );
191
 
                                                        throw apEx;
192
 
                                                }
193
 
 
194
 
                                                break;
195
 
                                        }
196
 
 
197
 
                                        case "--ipcport":
198
 
                                        {
199
 
                                                if ( ( i + 1 ) < args.Length )
200
 
                                                {
201
 
                                                        ipcPort = Convert.ToInt32( args[ ++i ] );
202
 
                                                }
203
 
                                                else
204
 
                                                {
205
 
                                                        ApplicationException apEx = new ApplicationException( "Error: The IPC port was not specified." );
206
 
                                                        Console.Error.WriteLine( apEx.Message );
207
 
                                                        throw apEx;
208
 
                                                }
209
 
 
210
 
                                                break;
211
 
                                        }
212
 
 
213
 
                                        case "--verbose":
214
 
                                        {
215
 
                                                verbose = true;
216
 
                                                break;
217
 
                                        }
218
 
                                }
219
 
                        }
220
 
                }
221
 
 
222
 
 
223
 
                /// <summary>
224
 
                /// Gets the Simias environment variables set by mod-mono-server in the apache process.
225
 
                /// </summary>
226
 
                private static void ParseEnvironmentVariables()
227
 
                {
228
 
                        string tmpPath;
229
 
                        if( Environment.GetEnvironmentVariable( EnvSimiasRunAsClient ) != null )
230
 
                        {
231
 
                                runAsServer = false;
232
 
                        }
233
 
 
234
 
                        tmpPath = Environment.GetEnvironmentVariable( EnvSimiasDataDir );
235
 
                        if( tmpPath != null )
236
 
                        {
237
 
                                simiasDataPath = tmpPath.Trim( new char [] { '\"' } );
238
 
                        }
239
 
 
240
 
                        if( Environment.GetEnvironmentVariable( EnvSimiasVerbose ) != null )
241
 
                        {
242
 
                                verbose = true;
243
 
                        }
244
 
                }
245
 
 
246
 
 
247
 
                /// <summary>
248
 
                /// Gets the default settings from the /etc/defaults.config file
249
 
                /// </summary>
250
 
                private static void ReadDefaultsConfig()
251
 
                {
252
 
                        runAsServer = !Simias.Defaults.RunsAsClient;
253
 
                        simiasDataPath = Simias.Defaults.SimiasDataDir;
254
 
                        //verbose = Simias.Defaults.Verbose;
255
 
                }
256
 
 
257
 
 
258
 
                /// <summary>
259
 
                /// Sends the specified message via the IPC to the listening process.
260
 
                /// </summary>
261
 
                /// <param name="message">Message to send.</param>
262
 
                private static void SendIpcMessage( string message )
263
 
                {
264
 
                        // Put the message into a length preceeded buffer.
265
 
                        UTF8Encoding utf8 = new UTF8Encoding();
266
 
                        int msgLength = utf8.GetByteCount( message );
267
 
                        byte[] msgHeader = BitConverter.GetBytes( msgLength );
268
 
                        byte[] buffer = new byte[ msgHeader.Length + msgLength ];
269
 
 
270
 
                        // Copy the message length and the message into the buffer.
271
 
                        msgHeader.CopyTo( buffer, 0 );
272
 
                        utf8.GetBytes( message, 0, message.Length, buffer, 4 );
273
 
 
274
 
                        // Allocate a socket to send the shutdown message on.
275
 
                        Socket socket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
276
 
                        try
277
 
                        {
278
 
                                // Connect to the listening client on the specifed ipc port.
279
 
                                socket.Connect( new IPEndPoint( IPAddress.Loopback, ipcPort ) );
280
 
                                socket.Send( buffer );
281
 
                                socket.Shutdown( SocketShutdown.Send );
282
 
                                socket.Close();
283
 
                        }
284
 
                        catch
285
 
                        {}
286
 
                }
287
 
 
288
 
                #endregion
289
 
 
290
 
                #region Protected Methods
291
 
 
292
 
                /// <summary>
293
 
                /// Application_Start
294
 
                /// </summary>
295
 
                /// <param name="sender"></param>
296
 
                /// <param name="e"></param>
297
 
                protected void Application_Start(Object sender, EventArgs e)
298
 
                {
299
 
#if WINDOWS
300
 
                        // update the prefix of the installed directory
301
 
                        // but only if we are on windows
302
 
                        SimiasSetup.prefix = Path.Combine(Server.MapPath(null), "..");
303
 
#endif
304
 
                        Environment.CurrentDirectory = SimiasSetup.webbindir;
305
 
 
306
 
                        if ( verbose )
307
 
                        {
308
 
                                Console.Error.WriteLine("Simias Process Starting");
309
 
                        }
310
 
 
311
 
                        serviceManager = Simias.Service.Manager.GetManager();
312
 
                        serviceManager.StartServices();
313
 
                        serviceManager.WaitForServicesStarted();
314
 
 
315
 
                        // Send the simias up event.
316
 
                        EventPublisher eventPub = new EventPublisher();
317
 
                        eventPub.RaiseEvent( new NotifyEventArgs("Simias-Up", "The simias service is running", DateTime.Now) );
318
 
 
319
 
                        if ( verbose )
320
 
                        {
321
 
                                Console.Error.WriteLine("Simias Process Running");
322
 
                        }
323
 
 
324
 
                        // start keep alive
325
 
                        // NOTE: We have seen a FLAIM corruption because the database was not given
326
 
                        // the opportunity to close on shutdown.  The solution is to work with
327
 
                        // Dispose() methods with the native calls and to control our own life cycle
328
 
                        // (which in a web application is difficult). It would mean separating the
329
 
                        // database application from the web application, which is not very practical
330
 
                        // today.  We can bend the rules in the web application by using a foreground
331
 
                        // thread. This is a brittle solution, but it seems to work today.
332
 
                        keepAliveThread = new Thread(new ThreadStart(this.KeepAlive));
333
 
                        quit = false;
334
 
                        keepAliveThread.Start();
335
 
                }
336
 
 
337
 
 
338
 
                /// <summary>
339
 
                /// Setup_Datadir
340
 
                /// </summary>
341
 
                protected static void Setup_Datadir()
342
 
                {
343
 
                        if(simiasDataPath == null)
344
 
                        {
345
 
                                if(verbose)
346
 
                                        Console.Error.WriteLine("SimiasDataPath was null, ignoring bootstrap process");
347
 
                                return;
348
 
                        }
349
 
 
350
 
                        // if we don't have a bootstrap, nothing to do!
351
 
                        if(!Directory.Exists(SimiasSetup.bootstrapdir))
352
 
                        {
353
 
                                if(verbose)
354
 
                                        Console.Error.WriteLine("Ignoring bootstrap process because file not found at : " + SimiasSetup.bootstrapdir);
355
 
                                return;
356
 
                        }
357
 
 
358
 
                        string[] fileEntries = 
359
 
                                Directory.GetFileSystemEntries(simiasDataPath);
360
 
 
361
 
                        // if we find entries in our current
362
 
                        // data path, bail out
363
 
                        if(fileEntries.Length > 1)
364
 
                        {
365
 
                                if(verbose)
366
 
                                        Console.Error.WriteLine("Files found in exising simias data area... Ignoring bootstrap process");
367
 
                                return;
368
 
                        }
369
 
 
370
 
                        // move all of the files
371
 
                        fileEntries = Directory.GetFiles(SimiasSetup.bootstrapdir);
372
 
                foreach(string fileName in fileEntries)
373
 
                        {
374
 
                                try
375
 
                                {
376
 
                                        File.Copy(fileName, Path.Combine(simiasDataPath, 
377
 
                                                                Path.GetFileName(fileName)) );
378
 
                                }
379
 
                                catch (Exception e)
380
 
                                {
381
 
                                        Console.Error.WriteLine("Error bootstraping file: " + fileName);
382
 
                                        Console.Error.WriteLine(e.Message);
383
 
                                }
384
 
                        }
385
 
 
386
 
                        // move all of the dirs
387
 
                        fileEntries = Directory.GetDirectories(SimiasSetup.bootstrapdir);
388
 
                foreach(string fileName in fileEntries)
389
 
                        {
390
 
                                try
391
 
                                {
392
 
                                        CopyDirectory(fileName, simiasDataPath);
393
 
                                }
394
 
                                catch (Exception e)
395
 
                                {
396
 
                                        Console.Error.WriteLine("Error bootstraping diretory: " + fileName);
397
 
                                        Console.Error.WriteLine(e.Message);
398
 
                                }
399
 
                        }
400
 
                }
401
 
 
402
 
                protected static void CopyDirectory(string src, string targetdir)
403
 
                {
404
 
                        string dirName = Path.GetFileName(src);
405
 
                        string targetName = Path.Combine(targetdir, dirName);
406
 
 
407
 
                        DirectoryInfo di = new DirectoryInfo(targetdir);
408
 
                        di.CreateSubdirectory(dirName);
409
 
 
410
 
                        // move all of the files
411
 
                        string[] fileEntries = Directory.GetFiles(src);
412
 
                foreach(string fileName in fileEntries)
413
 
                        {
414
 
                                File.Copy(fileName, Path.Combine(targetName, 
415
 
                                                                Path.GetFileName(fileName)) );
416
 
                        }
417
 
 
418
 
                        // move all of the dirs
419
 
                        fileEntries = Directory.GetDirectories(src);
420
 
                foreach(string fileName in fileEntries)
421
 
                        {
422
 
                                CopyDirectory(fileName, targetdir);
423
 
                        }
424
 
                }
425
 
 
426
 
 
427
 
                /// <summary>
428
 
                /// Keep Alive Thread
429
 
                /// </summary>
430
 
                protected void KeepAlive()
431
 
                {
432
 
                        TimeSpan span = TimeSpan.FromSeconds(1);
433
 
                        
434
 
                        while(!quit)
435
 
                        {
436
 
                                Thread.Sleep(span);
437
 
                        }
438
 
                }
439
 
 
440
 
                /// <summary>
441
 
                /// Session_Start
442
 
                /// </summary>
443
 
                /// <param name="sender"></param>
444
 
                /// <param name="e"></param>
445
 
                protected void Session_Start(Object sender, EventArgs e)
446
 
                {
447
 
                }
448
 
 
449
 
                /// <summary>
450
 
                /// Application_BeginRequest
451
 
                /// </summary>
452
 
                /// <param name="sender"></param>
453
 
                /// <param name="e"></param>
454
 
                protected void Application_BeginRequest(Object sender, EventArgs e)
455
 
                {
456
 
                }
457
 
 
458
 
                /// <summary>
459
 
                /// Application_EndRequest
460
 
                /// </summary>
461
 
                /// <param name="sender"></param>
462
 
                /// <param name="e"></param>
463
 
                protected void Application_EndRequest(Object sender, EventArgs e)
464
 
                {
465
 
                }
466
 
 
467
 
                /// <summary>
468
 
                /// Application_AuthenticateRequest
469
 
                /// </summary>
470
 
                /// <param name="sender"></param>
471
 
                /// <param name="e"></param>
472
 
                protected void Application_AuthenticateRequest(Object sender, EventArgs e)
473
 
                {
474
 
                }
475
 
 
476
 
                /// <summary>
477
 
                /// Application_Error
478
 
                /// </summary>
479
 
                /// <param name="sender"></param>
480
 
                /// <param name="e"></param>
481
 
                protected void Application_Error(Object sender, EventArgs e)
482
 
                {
483
 
                }
484
 
 
485
 
                /// <summary>
486
 
                /// Session_End
487
 
                /// </summary>
488
 
                /// <param name="sender"></param>
489
 
                /// <param name="e"></param>
490
 
                protected void Session_End(Object sender, EventArgs e)
491
 
                {
492
 
                }
493
 
 
494
 
                /// <summary>
495
 
                /// Application_End
496
 
                /// </summary>
497
 
                /// <param name="sender"></param>
498
 
                /// <param name="e"></param>
499
 
                protected void Application_End(Object sender, EventArgs e)
500
 
                {
501
 
                        if ( verbose )
502
 
                        {
503
 
                                Console.Error.WriteLine("Simias Process Starting Shutdown");
504
 
                        }
505
 
 
506
 
                        if ( serviceManager != null )
507
 
                        {
508
 
                                // Send the simias down event and wait for 1/2 second for the message to be routed.
509
 
                                EventPublisher eventPub = new EventPublisher();
510
 
                                eventPub.RaiseEvent( new NotifyEventArgs("Simias-Down", "The simias service is terminating", DateTime.Now) );
511
 
                                Thread.Sleep( 500 );
512
 
 
513
 
                                serviceManager.StopServices();
514
 
                                serviceManager.WaitForServicesStopped();
515
 
                                serviceManager = null;
516
 
                        }
517
 
 
518
 
                        if ( verbose )
519
 
                        {
520
 
                                Console.Error.WriteLine("Simias Process Shutdown");
521
 
                        }
522
 
 
523
 
                        // end keep alive
524
 
                        // NOTE: an interrupt or abort here is currently causing a hang on Mono
525
 
                        quit = true;
526
 
                }
527
 
 
528
 
                #endregion
529
 
 
530
 
                #region Public Methods
531
 
 
532
 
                /// <summary>
533
 
                /// Causes the controlling server process to shut down the web services.
534
 
                /// </summary>
535
 
                public static void SimiasProcessExit()
536
 
                {
537
 
                        SendIpcMessage( "stop_server" );
538
 
                }
539
 
 
540
 
                #endregion
541
 
        }
542
 
}
543