Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

server_template.cpp

Go to the documentation of this file.
00001 /*
00002  * server_template.h -- Template and server class deriving from
00003  *                      the DBMutableServerBase class.
00004  *
00005  *                      The base class handles communications, so this class
00006  *                      primarily must only concern itself with the specific
00007  *                      handling for this type of server (to include relevant
00008  *                      configuration, passports and calculations).
00009  * 
00010  */
00011 /*
00012  * Variable which are available from the base classes:
00013  * 
00014  *    bool Running;    true while running
00015  *                    false when told to quit/shutdown
00016  * 
00017  *    int LoggingOptions = various logging parameters (set in the base
00018  *                         class, depending on the mode)
00019  * 
00020  *    int LoggingLevel  =  Logging level assigned from the .d file.
00021  *                         Values:
00022  *                             WORM_LOG_ERRORS
00023  *                             WORM_LOG_STATUS
00024  *                             WORM_LOG_TRACKING
00025  *                             WORM_LOG_DETAILS
00026  *                             WORM_LOG_DEBUG
00027  * 
00028  *    MUTABLE_MODE_TYPE  Mode = Current mode in which the program is operating
00029  *               Values:
00030  *                  MMT_STANDALONE = command from args/stdin, data access and calculations internally
00031  *                  MMT_MODULE     = command from ring, data access and calculations internally [MT]
00032  *                  MMT_SERVER     = command from socket, calculations internally [MT]
00033  *                  MMT_CLIENT     = command from atgs/stdin, socket call to client for calculations
00034  * 
00035  *
00036  *  
00037  * MODULE AND MESSAGE TYPE IDS:
00038  * 
00039  *     WORM_INSTALLATION_ID  InstId  = TGlobalUtils::LookupInstallationId("INST_XXXX");
00040  *     WORM_MODULE_ID        ModulId = TGlobalUtils::LookupModuleId("INST_XXXX");
00041  *     WORM_MSGTYPE_ID       MsgId   = TGlobalUtils::LookupMessageTypeId("INST_XXXX");
00042  * 
00043  * 
00044  * AVAILABLE FUNCTIONS:
00045  * 
00046  *      // Put a status/error message onto the command ring
00047  *      //     type must be TYPE_ERROR
00048  *      void SendStatus( unsigned char type, short ierr, char *note );
00049  * 
00050  *      void InitializeDB();  // called by DBMutableServer::PrepareToRun(),
00051  *                            // but it might also need to be called elsewhere
00052  *                            // for some modes
00053  *         
00054  *      void GetDefaultsFromDB(); 
00055  * 
00056  *      // Compare SCNLs with wildcards
00057  *      // returns true or false
00058  *      bool DoSCNLsMatch( const char * p_s1
00059  *                       , const char * p_c1
00060  *                       , const char * p_n1
00061  *                       , const char * p_l1
00062  *                       , const char * p_s2
00063  *                       , const char * p_c2
00064  *                       , const char * p_n2
00065  *                       , const char * p_l2
00066  *                       )                    
00067  * 
00068  * LOGGING:
00069  * 
00070  *    Based upon the value of LoggingLevel (value list above),
00071  *    use the TLogger object to perform the logging functions:
00072  * 
00073  *     if( WORM_LOG_ERRORS <= LoggingLevel )
00074  *     {
00075  *        TLogger::Logit( LoggingOptions
00076  *                     , "ServerTemplate::GetRequestFromInput(): %d\n"
00077  *                     , some_int_value
00078  *                     );
00079  *     }
00080  * 
00081  * ERROR HANDLING WITH EXCEPTIONS:
00082  * 
00083  *     Through base class headers a class called worm_exception is
00084  *     understood.
00085  * 
00086  *     Often errors are handled in the methods using a try-catch pair:
00087  * 
00088  *     try
00089  *     {
00090  *         // some code
00091  * 
00092  *         if ( some_condition )
00093  *         {
00094  *            // an error was discovered
00095  *            
00096  *            throw worm_exception("My error message");
00097  *         }
00098  * 
00099  * 
00100  *         if ( some_int_value != 0 )
00101  *         {
00102  *            // an error was discovered
00103  *            
00104  *            worm_exception MyExcept("some_int_value not = 0: ");
00105  *                           MyExcept += (int)some_int_value;
00106  *                           MyExcept += ", Must quit";
00107  *            throw MyExcept;
00108  *         }
00109  * 
00110  *     }
00111  *     catch( worm_exception & _we )
00112  *     {
00113  *        // Handle any worm exception thrown in the above try block
00114  *        
00115  *        // At this point, '_we' is a reference to a worm_exception object
00116  *        // it has one method most useful here:
00117  * 
00118  *        char * _errptr = _we.what();  // returns the error message as a pointer to char
00119  * 
00120  *        // If desired, the exception may be re-thrown
00121  *        // (uncommon, but can be done).
00122  *        throw _we;
00123  *     }
00124  *     catch( ... )
00125  *     {
00126  *         // This second catch block is not needed, but it shown here to
00127  *         // demonstrate how to catch any type of exception.
00128  *         // Unfortunately, there is no available reference to the exception.
00129  *     }
00130  * 
00131  *     If a method/function includes a throw statement that is not surrounded
00132  *     by at try block (with an applicable catch block), then execution
00133  *     returns from the method immediately and then entire calling chain of
00134  *     functions are returned from -- Until one of the function calls is
00135  *     surrounded by a try block with an appropriate catch block.
00136  *     
00137  *     Memory allocations are NOT released, and file pointers may not be
00138  *     closed, so they should be handled in a manner such as this:
00139  * 
00140  *     char * MyBuffer = NULL;
00141  * 
00142  *     try
00143  *     {
00144  *         // some code, part A
00145  * 
00146  *         if ( (MyBuffer = new char[120]) == NULL )
00147  *         {
00148  *            throw worm_exception("failed allocation buffer");
00149  *         }
00150  * 
00151  *         // some other code, part B
00152  * 
00153  *     }
00154  *     catch( worm_exception & _we )
00155  *     {
00156  *        // error handling for worm_exceptions
00157  *     }
00158  *     catch( ... )
00159  *     {
00160  *        // error handling for other exceptions
00161  *     }
00162  * 
00163  * 
00164  *     if ( MyBuffer != NULL )
00165  *     {
00166  *        // Ensure memory is released
00167  *        // (we allocated an array of char, so we use "delete []"
00168  *        // instead of just "delete")
00169  *        //
00170  *        delete [] MyBuffer;
00171  *     }
00172  */
00173 
00174 
00175 // STEP 1: Do a global replacement of the string "ServerTemplate"
00176 //         with the name of the new class
00177 //
00178 
00179 // STEP 2: Replace this include with the .h file for the new class
00180 //
00181 #include "server_template.h"
00182 
00183 
00184 // STEP 3: Add includes for the appropriate type of message classes
00185 #include "request_template.h"
00186 #include "result_template.h"
00187 
00188 
00189 
00190 extern "C" {
00191 
00192 // STEP 4: Include any headers for C-style code
00193 
00194 }
00195 
00196 
00197 //------------------------------------------------------------------------------
00198 ServerTemplate::ServerTemplate()
00199 {
00200 // STEP 5 Perform any required variable initialization here
00201 //        Usually, that means initializing the default parameters:
00202    DefaultParameters.ExampleLongParam      = 0L;
00203    DefaultParameters.ExampleStringParam[0] = '\0'; 
00204    DefaultParameters.ExampleFlagParam      = false;
00205    
00206    
00207 //         (Any pointers that will refer to dynamically allocated memory
00208 //         must be NULLified here).
00209 //
00210 //     MyPointer = NULL;
00211 }
00212 
00213 //------------------------------------------------------------------------------
00214 ServerTemplate::~ServerTemplate()
00215 {
00216 // STEP 6 Perform any requisite clean-up for server termination here
00217 
00218 // (generally only needed to delete any dynamically-allocated memory)
00219 
00220    /*
00221     * if ( MyPointer != NULL )
00222     * {
00223     *    delete [] MyPointer;
00224     * }
00225     */
00226     
00227 }
00228 
00229 //------------------------------------------------------------------------------
00230 HANDLE_STATUS ServerTemplate::HandleConfigLine( ConfigSource * p_parser )
00231 {
00232 // STEP 7: Handle any Configuration parameter parsing here.
00233 //
00234 // THIS METHOD RECEIVES A SINGLE CONFIGURATION LINE AT A TIME; THUS, IT IS
00235 // CALLED REPEATEDLY.
00236 //
00237 // GENERALLY, ONLY THOSE CONFIGURATION ITEMS THAT MAY ONLY COME
00238 // FROM THE CONFIGURATION FILE (i.e. STARTUP CONFIGURATION) ARE
00239 // PROCESSED HERE.  THOSE ITEMS WHICH MAY ALSO BE CHANGED VIA A PASSPORT
00240 // ARE HANDED OFF TO THE METHOD HandleParameterLine() TOWARDS THE BOTTOM OF
00241 // THIS METHOD.
00242 //
00243 // THIS METHOD MUST RETURN ONE OF THESE VALUES: 
00244 //
00245 //       HANDLE_INVALID --  line invalid
00246 //       HANDLE_UNUSED  --  line not used
00247 //       HANDLE_USED    --  line used okay
00248 //
00249 
00250    // BASE CLASSES MUST BE GIVEN THE CHANCE TO GET CONFIG VARIABLES:
00251    HANDLE_STATUS r_status = DBMutableServerBase::HandleConfigLine( p_parser );
00252    
00253    
00254    if ( r_status == HANDLE_UNUSED )
00255    {
00256       // Base class didn't use it, then it must belong to this
00257       // derivative class
00258     
00259       try
00260       {
00261          // this do-while is solely to allow a single return point,
00262          // thus simplifying the code.
00263          
00264          do
00265          {
00266             char * _token;
00267             
00268             // WHEN ARRIVING HERE, p_parser HAS THE FIRST TOKEN ON 
00269             // THE [COMMAND] LINE LOADED INTO THE CURRENT TOKEN.
00270             // THUS WE MAY PERFORM A TEST FOR THE LINE TYPE USING Its("")
00271             //
00272             // Among others, a ConfigSource object has these  methods:
00273             //
00274             //          bool   Its("");           // compare current token to a string
00275             //    const char * GetCurrentToken();
00276             //    const char * GetCurrentLine();  
00277             //          char * String();          // next token as a string
00278             //          int    Int();             // next tokan as an int
00279             //          int    Long();            // next tokan as a long
00280             //          int    Double();          // next tokan as a double
00281             //
00282             // And these member values:
00283             //
00284             //        INVALID_INT
00285             //        INVALID_LONG
00286             //        INVALID_DOUBLE
00287             //
00288             
00289             
00290             
00291             // EXAMPLE LINE:
00292             //
00293             //    ExampleFlagParam true
00294             //    ExampleFlagParam false
00295             // 
00296             if ( p_parser->Its("ExampleFlagParam") )
00297             {
00298                _token = p_parser->String();
00299                
00300                // The ConfigSource::String() method will return an empty string
00301                // if no token is found, must perform a specific check for 
00302                // that condition.
00303                
00304                if ( p_parser->IsTokenNull() )
00305                {
00306                   // Didn't find an expected value on the line
00307                   throw worm_exception("Incomplete <ExampleFlagParam> line");
00308                }
00309                
00310                // Grab the value
00311                if ( strcmp( _token, "true" ) == 0 )
00312                {
00313                   DefaultParameters.ExampleFlagParam = true;
00314                }
00315                else
00316                {
00317                   DefaultParameters.ExampleFlagParam = false;
00318                }
00319                
00320                // Set the return status to indicate that the line was handled
00321                // okay.
00322                r_status = HANDLE_USED;
00323                
00324                // Skip past any other line checking
00325                continue;
00326             }
00327             
00328             
00329             // Additional Its() and handling
00330             
00331             
00332             
00333             // Pass any config-file only lines to the
00334             // shared config/passport handler
00335             //
00336             r_status = HandleParameterLine( p_parser, &DefaultParameters );
00337             
00338          } while( false );
00339       }
00340       catch( worm_exception & _we )
00341       {
00342          // Do all of our logging [including for HandleParameterLine()] here
00343          
00344          if ( WORM_LOG_ERRORS <= LoggingLevel )
00345          {
00346             TLogger::Logit( LoggingOptions
00347                           , "ServerTemplate::HandleConfigLine() Error:\n%s"
00348                           , _we.what()
00349                           );
00350          }
00351                
00352          r_status = HANDLE_INVALID;
00353       }  
00354    }
00355    
00356    return r_status;
00357 }
00358 
00359 //------------------------------------------------------------------------------
00360 HANDLE_STATUS ServerTemplate::HandleParameterLine( ConfigSource * p_parser
00361                                                  , void         * p_params
00362                                                  )
00363 {
00364 // STEP 8: Handle processing parameters here.
00365 //
00366 // GENERALLY, THIS METHOD IS USED TO HANDLE PROCESSING-RELATED PARAMETERS THAT
00367 // MIGHT ORIGINATE FROM EITHER THE CONFIGURATION FILE, OR THE PASSPORT.
00368 //
00369 // THIS METHOD RECEIVES A SINGLE CONFIGURATION LINE AT A TIME; THUS, IT IS
00370 // CALLED REPEATEDLY.
00371 //
00372 // THIS METHOD MUST RETURN ONE OF THESE VALUES: 
00373 //
00374 //       HANDLE_INVALID --  line invalid
00375 //       HANDLE_UNUSED  --  line not used
00376 //       HANDLE_USED    --  line used okay
00377 // 
00378 // OR THROW worm_exception() FOR ERRORS.
00379 //
00380 // Any errors that are encountered are not logged here, but are throw as an
00381 // worm_exception for the caller to handle and report. 
00382 
00383    HANDLE_STATUS r_status = HANDLE_UNUSED;
00384    
00385    // Cast the arriving pointer to a parameters struct to the correct type for
00386    // this server
00387    //
00388    ServerTemplate_PARAMS * CurrentParameters = (ServerTemplate_PARAMS *)p_params;
00389    
00390    
00391    do
00392    {
00393       char * _token;
00394             
00395       // WHEN ARRIVING HERE, p_parser HAS THE FIRST TOKEN ON 
00396       // THE [COMMAND] LINE LOADED INTO THE CURRENT TOKEN.
00397       // THUS WE MAY PERFORM A TEST FOR THE LINE TYPE.
00398             
00399             
00400       // EXAMPLE PARAMETER/PASSPORT LINE:
00401       //
00402       //    ExampleDualValue  some_string_without_whitespace  some_integer
00403       // 
00404       if ( p_parser->Its("ExampleDualValue") )
00405       {
00406          _token = p_parser->String();
00407          
00408          if ( p_parser->IsTokenNull() )
00409          {
00410             // Didn't find an expected value on the line
00411             throw worm_exception("Incomplete <ExampleDualValue> line");
00412          }
00413          
00414          if ( 30 <  strlen( _token ) )
00415          {
00416             throw worm_exception("Invalid <ExampleDualValue> line: string too long");
00417          }
00418          
00419          // Grab the string value
00420          strcpy( CurrentParameters->ExampleStringParam, _token );
00421          
00422          // Now get the int
00423                   
00424          if ( (CurrentParameters->ExampleLongParam = p_parser->Int()) == p_parser->INVALID_INT )
00425          {
00426             // Didn't find an expected value on the line
00427             CurrentParameters->ExampleLongParam = 0;
00428             throw worm_exception("Incomplete <ExampleDualValue> line: missing int");
00429          }
00430                
00431          // Set the return status to indicate that the line was handled
00432          // okay.
00433          r_status = HANDLE_USED;
00434              
00435          // Skip past any other line checking
00436          continue;
00437       }
00438       
00439       
00440       // Additional Its() and handling
00441       
00442             
00443    } while( false );
00444 
00445    return r_status;
00446 }
00447 
00448 
00449 //------------------------------------------------------------------------------
00450 void ServerTemplate::CheckConfig()
00451 {
00452    // MUST ALWAYS ALLOW BASE CLASSES A CHANCE TO CHECK THEIR OWN
00453    // CONFIGURATION STATE.
00454    //
00455    // If the Mode is required for testing, then this statement must
00456    // come first.
00457    //
00458    DBMutableServerBase::CheckConfig();
00459    
00460    
00461    // CHECK THIS CLASS'S CONFIGURATION VARIABLES,
00462    //
00463    // There may be need to perform testing based upon the mode in which the
00464    // program is to run.  For example, a client won't likely need to know
00465    // about any waveservers, so it won't check the values of any waveserver
00466    // variables despite their existence in support of the server.
00467    // The operating mode is kept in variable 'Mode' (see top of file).
00468    //
00469    // IF A PROBLEM IS FOUND, LOG IT, AND DO:
00470    //
00471    //       ConfigStatus = WORM_STAT_BADSTATE;
00472    //
00473    // BUT DON'T RETURN, THUS ALL CONFIGURATION ERRORS CAN BE REPORTED
00474    // FROM ONE ATTEMPTED RUN.
00475    
00476 // STEP 9: Perform any configuration checking here
00477 
00478    if ( DefaultParameters.ExampleLongParam == 0 )
00479    {
00480       TLogger::Logit( LoggingOptions
00481                     , "ServerTemplate::CheckConfig(): Did not find a valid <ExampleDualValue> line"
00482                     );
00483       ConfigStatus = WORM_STAT_BADSTATE;
00484    }
00485    
00486    
00487 }
00488 
00489 //------------------------------------------------------------------------------
00490 bool ServerTemplate::PrepareToRun()
00491 {
00492    bool r_status = false;
00493 
00494    try
00495    {
00496       if ( DBMutableServerBase::PrepareToRun() )
00497       {   
00498          // Get any default parameters from the database
00499          //
00500          // (this will ultimately end up calling the HandleParameterLine() method) 
00501          //
00502          if ( GetDefaultsFromDB( &DefaultParameters ) )
00503          {
00504    
00505 // STEP 10: If the new class needs to perform any activities after configuration,
00506 //         but before starting the main processing, add that here.
00507 //       
00508 //         RETURN false IF AN ERROR PREVENTS CONTINUING.
00509    
00510    
00511             // indicate preparations completed successfully
00512             r_status = true;
00513          }
00514       }
00515    }
00516    catch( worm_exception & _we )
00517    {
00518       if( WORM_LOG_ERRORS <= LoggingLevel )
00519       {
00520          TLogger::Logit( LoggingOptions
00521                        , "ServerTemplate::PrepareToRun() Error: %s\n"
00522                        , _we.what()
00523                        );
00524       }
00525       
00526       r_status = false;
00527    }
00528    return r_status;
00529 }
00530 
00531 //------------------------------------------------------------------------------
00532 MutableServerRequest * ServerTemplate::GetRequestContainer()
00533 {
00534 // STEP 11: Change "RequestTemplate" to the appropriate type of request container
00535 //          (2 times)
00536    RequestTemplate * r_object = NULL;
00537 
00538    try
00539    {
00540       if ( (r_object = new RequestTemplate()) == NULL )
00541       {
00542          throw worm_exception("Failed to create Request container");
00543       }
00544    }
00545    catch( worm_exception & _we )
00546    {
00547       if( WORM_LOG_ERRORS <= LoggingLevel )
00548       {
00549          TLogger::Logit( LoggingOptions
00550                       , "ServerTemplate::GetRequestContainer(): %s\n"
00551                       , _we.what()
00552                       );
00553       }
00554    }
00555 
00556    return r_object;
00557 }
00558 
00559 //------------------------------------------------------------------------------
00560 MutableServerResult * ServerTemplate::GetResultContainer()
00561 {
00562 // STEP 12: Change "ResultTemplate" to the appropriate type of request container
00563 //          (2 times)
00564 
00565    ResultTemplate * r_object = NULL;
00566 
00567    try
00568    {
00569       if ( (r_object = new ResultTemplate()) == NULL )
00570       {
00571          throw worm_exception("Failed to create Result container");
00572       }
00573    }
00574    catch( worm_exception & _we )
00575    {
00576       if( WORM_LOG_ERRORS <= TGlobalUtils::GetLoggingLevel() )
00577       {
00578          TLogger::Logit( LoggingOptions
00579                       , "ServerTemplate::GetResultContainer(): %s\n"
00580                       , _we.what()
00581                       );
00582       }
00583    }
00584 
00585    return r_object;
00586 }
00587 
00588 //------------------------------------------------------------------------------
00589 WORM_STATUS_CODE ServerTemplate::GetRequestFromInput( int    p_argc
00590                                                     , char * p_argv[]
00591                                                     , void * r_container
00592                                                     )
00593 {
00594    WORM_STATUS_CODE r_status = WORM_STAT_SUCCESS;
00595 
00596    try
00597    {
00598       if ( r_container == NULL )
00599       {
00600          throw worm_exception("NULL request container parameter");
00601       }
00602 
00603       if ( p_argc < 2 )
00604       {
00605          throw worm_exception("Too few parameters from program command line");
00606       }
00607 
00608       if ( WORM_LOG_DEBUG < LoggingLevel )
00609       {
00610          TLogger::Logit( LoggingOptions
00611                        , "ServerTemplate::GetRequestFromInput() argc: %d  [1] = %s\n"
00612                        , p_argc
00613                        , p_argv[1]
00614                        );
00615       }
00616       
00617 
00618 // STEP 13: Cast the arriving container to the request class appropriate to
00619 //          this server class.
00620 //
00621       RequestTemplate * ThisRequest = (RequestTemplate *)r_container;
00622 
00623 
00624 // STEP 14: Perform whatever actions are needed, based upon the command line
00625 //          input.  Commonly this might include getting event info from the
00626 //          database.
00627 //
00628 //          Since this is for client and standalone modes only, these should
00629 //          generally be activities needed to perform the processing request.
00630 //
00631 //          Throw worm_exception for errors.
00632 //
00633 //          For example, if the request class tracks origin id there might
00634 //          be code that looks something like:
00635 //
00636 //          ThisRequest->SetEventId( atoi(argv[1]) );
00637 
00638 
00639    }
00640    catch( worm_exception & _we )
00641    {
00642       r_status = WORM_STAT_FAILURE;
00643 
00644       if( WORM_LOG_ERRORS <= TGlobalUtils::GetLoggingLevel() )
00645       {
00646          TLogger::Logit( LoggingOptions
00647                       , "ServerTemplate::GetRequestFromInput(): %s\n"
00648                       , _we.what()
00649                       );
00650       }
00651    }
00652 
00653    return r_status;
00654 }
00655 
00656 //------------------------------------------------------------------------------
00657 WORM_STATUS_CODE ServerTemplate::ProcessRequest( void * p_requestcontainer
00658                                                , void * r_resultcontainer
00659                                                )
00660 {
00661    // on algorithm failure (but not error) set r_status = WORM_STAT_BADSTATE
00662    // before throwing a worm_exception
00663    // 
00664    // (r_status is set to WORM_STAT_SUCCESS at bottom of method)
00665    //
00666    WORM_STATUS_CODE r_status = WORM_STAT_FAILURE;
00667 
00668    // Passport for this processing run
00669    ServerTemplate_PARAMS    LocalParameters;
00670    
00671    ResultTemplate  * ThisResult  = NULL;
00672    
00673    try
00674    {
00675       if ( p_request == NULL || r_result == NULL )
00676       {
00677          throw worm_exception("NULL container parameter");
00678       }
00679       
00680 // STEP 15:
00681       // Cast request and result containers to the appropriate types for
00682       // this server
00683       RequestTemplate * ThisRequest = (RequestTemplate *)p_requestcontainer;
00684                         ThisResult  = (ResultTemplate *)r_resultcontainer;
00685       
00686       
00687 
00688 // STEP 16: 
00689       // Copy default parameters into the local parameters for this calculation
00690       
00691               LocalParameters.ExampleLongParam   = DefaultParameters.ExampleLongParam;
00692       strcpy( LocalParameters.ExampleStringParam , DefaultParameters.ExampleStringParam );
00693               LocalParameters.ExampleFlagParam   = DefaultParameters.ExampleFlagParam;
00694       
00695 
00696 // STEP 17:
00697 //
00698 // THIS IS EXAMPLE CODE THAT CAN BE USED IF THE REQUEST CONTAINER IS DERIVED
00699 // FROM MutableServerRequest CLASS (WHICH KNOWS ABOUT PASSPORTS.
00700 // IT CAN BE INCLUDED EVEN IF NO PASSPORT DATA IS BEING PASSED AT THIS TIME.
00701 //
00702 // IF THE REQUEST CONTAINER DOES NOT DERIVE FROM MutableServerRequest CLASS,
00703 // THIS PROBABLY MUST BE REMOVED.
00704 
00705       if( WORM_LOG_DEBUG <= LoggingLevel )
00706       {
00707          TLogger::Logit( WORM_LOG_TOFILE
00708                        , "ServerTemplate::ProcessRequest() Getting Passport:\n"
00709                        );
00710       }
00711 
00712       
00713       // Process any passport lines that arrive
00714       //
00715       if ( 0 < ThisRequest->GetPassportLineCount() )
00716       {
00717          // basic command line parser object
00718          ConfigSource _parser;
00719    
00720          for ( int _p = 0, _sz = ThisRequest->GetPassportLineCount() ; _p < _sz ; _p++ )
00721          {
00722             if( WORM_LOG_DEBUG <= LoggingLevel )
00723             {
00724                TLogger::Logit( WORM_LOG_TOFILE
00725                              , "   >%s\n"
00726                              , _request->GetPassportLine( _p )
00727                             );
00728             }
00729 
00730             _parser.Load( ThisRequest->GetPassportLine( _p ) );
00731 
00732             // HandleParameterLine() will throw worm_exception
00733             // which will be caught by the catch block at the end
00734             // of this method.  To continue processing on parameter line
00735             // errors, this statement must be wrapped in at try block
00736             //
00737             HandleParameterLine( &_parser, &LocalParameters );
00738          }
00739       }
00740       
00741       
00742       
00743 // STEP 18: Perform the actual seimological processing here.
00744 //
00745 //          Any parameters needed should be in LocalParameters (which should be
00746 //          passed to any other methods instead of DefaultParameters.
00747 //
00748 //          Any event data needed should be in the ThisRequest object,
00749 //          something like:   ThisRequest->GetEventId()
00750 //
00751 //          On algorithmic incompletion/failure:
00752 //               r_status = WORM_STAT_BADSTATE;
00753 //               ThisResult->SetStatus( MSB_RESULT_FAIL );
00754 //               throw worm_exception("error description");
00755 //
00756 //          On system failure:
00757 //               r_status = WORM_STAT_FAILURE;
00758 //               ThisResult->SetStatus( MSB_RESULT_ERROR );
00759 //               throw worm_exception("error description");
00760 
00761 
00762 
00763       // Put the appropriate result status into the Result object
00764       // (alternatives above)
00765       ThisResult->SetStatus( MSB_RESULT_GOOD );
00766       
00767       // Set the return state 
00768       //
00769       r_status = WORM_STAT_SUCCESS;
00770    }
00771    catch( worm_exception & _we )
00772    {
00773       // r_status should have been set above
00774 
00775       if( WORM_LOG_ERRORS <= TGlobalUtils::GetLoggingLevel() )
00776       {
00777          TLogger::Logit( LoggingOptions
00778                       , "ServerTemplate::ProcessRequest(): %s\n"
00779                       , _we.what()
00780                       );
00781       }
00782    }
00783 }
00784 
00785 //------------------------------------------------------------------------------
00786 WORM_STATUS_CODE ServerTemplate::HandleResult( void * p_resultcontainer )
00787 {
00788    WORM_STATUS_CODE r_status = WORM_STAT_SUCCESS;
00789 
00790    try
00791    {
00792 // STEP 19: Cast the result container to the appropriate type
00793 //
00794       ResultTemplate  * ThisResult  = (ResultTemplate *)p_resultcontainer;
00795 
00796 
00797       if( WORM_LOG_DEBUG <= LoggingLevel )
00798       {
00799          TLogger::Logit( LoggingOptions
00800                        , "ServerTemplate::HandleResult(): DEBUG result of processing: %d\n"
00801                        , _result->GetStatus()
00802                        );
00803       }
00804       
00805 
00806       if ( ThisResult->GetStatus() == MSB_RESULT_GOOD )
00807       {
00808          
00809 // STEP 20: Perform activities for a good result (i.e.: database storage)
00810 //
00811 //       throw worm_exception for errors
00812 
00813          
00814       } // received good magnitude result
00815       else
00816       {
00817          switch( _result->GetStatus() )
00818          {
00819            case MSB_RESULT_FAIL:
00820                 r_status = WORM_STAT_BADSTATE;
00821                 break;
00822            case MSB_RESULT_ERROR:
00823                 r_status = WORM_STAT_FAILURE;
00824                 break;
00825          }
00826       } // calculations not good
00827    }
00828    catch( worm_exception & _we )
00829    {
00830       r_status = WORM_STAT_FAILURE;
00831 
00832       if( WORM_LOG_ERRORS <= TGlobalUtils::GetLoggingLevel() )
00833       {
00834          TLogger::Logit( LoggingOptions
00835                       , "ServerTemplate::HandleResult(): %s\n"
00836                       , _we.what()
00837                       );
00838       }
00839    }
00840 
00841    return r_status;
00842 }
00843 //------------------------------------------------------------------------------

Generated on Tue May 6 09:16:09 2003 for Earthworm Libs by doxygen1.3-rc3