project BLF > class ApplicationControl > method Main

Description

The applicationcontrol is started using the following syntax:

_progres -p applicationcontrol.p -param "<options>" -b > <LogFile>


Where <options> is a string that can be used to pass options to the applicationcontrol, and is of
the format "-<option> [<value] [-<option> [<value]]".
Where options can be:

* URL
is the connection string for the central application appserver. Typically this is formatted as follows:*/
"appserver://<HostName>:<NameServerPort>/<AppServiceName>". If the URL is not specified, the
logic is executed on the _progres session itself, rather than running the logic on the official appserver
machine.
* PROPATH
is the propath that should be used by the _progres session in case the logic is run in the process
itself rather than on the central appserver. (this is when <URL> is blank).
* ACTION
indicates what needs to be done. The <value> can be one of the following:
o StartApplication
This performs a sequence of steps that is required when the application starts up. This should be
executed right after the appserver has started. Following steps are done:
1. Run house keeping, which deletes the data of all inactive instances from the database.
2. For each daemon that needs to be started automatically, it tries to start the daemon.
o StartApplication_no_housekeeping
The same as "Start", but without the house keeping step.
o StopApplication
This performs a sequence of steps that is required when the application needs to be stopped. This
should be executed right before the appserver (and database server) go down.
In the current implementation, the only step that is done is stopping all running daemons.
o StopApplication_no_wait
This is the same as "Stop", but the system will not wait for max. 5 minutes to come back and wait
for the different processes to really stop gracefully.
o OnlineHousekeeping
This will run (partial) housekeeping while users are still active in the application.
o StartDaemon [<DaemonName>]
This tries to start a new instance of the named daemon.
If the DaemonName is not specified, it tries to start all daemons that are configured to run.
o StopDaemon <DaemonName>
This tries to stop all instances of the named daemon (sending a stop request).
o UnconditionalStopDaemon <DaemonName>
This tries to stop all instances of the named daemon unconditionally (kill if necessary)
o DaemonStatus [<DaemonName>]
This returns the status information about the named daemon.
If the DaemonName is not specified, it returns the status information of all defined daemons in the*/
system.
The following information is shown for the daemon(s):
Daemon Name: XmlDaemon
[Status] Status: Active
[Status] #Running instances: 2
[Status] Proces Ids: 1884, 4856
[Status] Start date of daemon: 04/12/2007
[Config] Log file: /users/xyz/logs/xmldaemon.log
[Config] Startup folder: /users/xyz/daemons/xmldaemon
[Config] Daemon login: mfg
[Config] XML input folder: /users/xyz/daemons/xmldaemon/input
o ResetDaemonConfiguration [<DaemonName>]
This needs to be executed when a system is copied (copy an application database from one
environment to another). It makes sure the configuration information of the daemons is reset to the*/
initial values (ApiSynchronise), so that the daemons cannot be accidentally be started, using
configurations of the system where it was copied from.
By default, this resets all daemons, but by specifying a Daemon name as extra parameter, it can be
limited to one daemon only.
o Synchronize [Full|Limited|Topic<XX>]
This performs a synchronize in a certain mode:
1. Full
2. Limited
3. Topic<XX>
The error/warning messages and other information is put on the std out. So, by redirecting the
output of the _progres command, the script can interpret the result of the ApplicationControl run.


Internal usage


unused


program code (program1/applicationcontrol.p)

/* ========================================================================================================== */
/* We use message statement of progress to report errors                                                      */
/* We expect that this are captured by directing standard-out to a file when executing from the command line  */
/* The applicationcontrol is started using the following syntax:                                              */
/* _progres -p applicationcontrol.p -param "<options>" -b > <LogFile>                                         */
/*                                                                                                            */
/* Where <options> is a string that can be used to pass options to the applicationcontrol, and is of          */
/* the format "-<option> [<value] [-<option> [<value]]".                                                      */
/* Where options can be:                                                                                      */
/*                                                                                                            */
/* * URL                                                                                                      */
/*   is the connection string for the central application appserver.  Typically this is formatted as follows: */
/*   "appserver://<HostName>:<NameServerPort>/<AppServiceName>".  If the URL is not specified, the logic is   */
/*   executed on the _progres session itself, rather than running the logic on the official appserver         */
/*   machine.                                                                                                 */
/* * PROPATH                                                                                                  */
/*   is the propath that should be used by the _progres session in case the logic is run in the process       */
/*   itself rather than on the central appserver. (this is when <URL> is blank).                              */
/* * ACTION                                                                                                   */
/*   indicates what needs to be done.  The <value> can be one of the following:                               */
/* 	o StartApplication                                                                                     */
/* 	  This performs a sequence of steps that is required when the application starts up.  This should be   */
/*        executed right after the appserver has started.  Following steps are done:                          */
/* 		1. Run house keeping, which deletes the data of all inactive instances from the database.       */
/* 		2. For each daemon that needs to be started automatically, it tries to start the daemon.        */
/* 	o StartApplication_no_housekeeping                                                                     */
/* 	  The same as "Start", but without the house keeping step.                                             */
/* 	o StopApplication                                                                                      */
/* 	  This performs a sequence of steps that is required when the application needs to be stopped. This    */
/*        should be executed right before the appserver (and database server) go down.                        */
/* 	  In the current implementation, the only step that is done is stopping all running daemons.           */
/* 	o StopApplication_no_wait                                                                              */
/* 	  This is the same as "Stop", but the system will not wait for max. 5 minutes to come back and wait    */
/*        for the different processes to really stop gracefully.                                              */
/* 	o OnlineHousekeeping                                                                                   */
/*        This will run (partial) housekeeping while users are still active in the application.               */
/* 	o StartDaemon [<DaemonName>]                                                                           */
/* 	  This tries to start a new instance of the named daemon.                                              */
/* 	  If the DaemonName is not specified, it tries to start all daemons that are configured to run.        */
/* 	o StopDaemon <DaemonName>                                                                              */
/* 	  This tries to stop all instances of the named daemon (sending a stop request).                       */
/*     o UnconditionalStopDaemon <DaemonName>                                                                 */
/*       This tries to stop all instances of the named daemon unconditionally (kill if necessary)             */
/* 	o DaemonStatus [<DaemonName>]                                                                          */
/* 	  This returns the status information about the named daemon.                                          */
/* 	  If the DaemonName is not specified, it returns the status information of all defined daemons in the  */
/*        system.                                                                                             */
/* 	  The following information is shown for the daemon(s):                                                */
/* 	  Daemon Name: 			XmlDaemon                                                            */
/* 	  [Status] Status:			Active                                                               */
/* 	  [Status] #Running instances: 	2                                                                    */
/* 	  [Status] Proces Ids: 		1884, 4856                                                           */
/* 	  [Status] Start date of daemon:	04/12/2007                                                           */
/* 	  [Config] Log file:			/users/xyz/logs/xmldaemon.log                                        */
/* 	  [Config] Startup folder:		/users/xyz/daemons/xmldaemon                                         */
/* 	  [Config] Daemon login:		mfg                                                                  */
/* 	  [Config] XML input folder:	/users/xyz/daemons/xmldaemon/input                                   */
/* 	o ResetDaemonConfiguration [<DaemonName>]                                                              */
/* 	  This needs to be executed when a system is copied (copy an application database from one             */
/*        environment to another). It makes sure the configuration information of the daemons is reset to the */
/*        initial values (ApiSynchronise), so that the daemons cannot be accidentally be started, using       */
/*        configurations of the system where it was copied from.                                              */
/* 	  By default, this resets all daemons, but by specifying a Daemon name as extra parameter, it can be   */
/*        limited to one daemon only.                                                                         */
/* 	o ClearDaemonQueue <DaemonName>                                                                        */
/* 	  This deletes all successfully processed entries from a daemon queue.                                 */
/* 	o Synchronize [Full|Limited|Topic<XX>]                                                                 */
/* 	  This performs a synchronize in a certain mode:                                                       */
/* 		1. Full                                                                                         */
/* 		2. Limited                                                                                      */
/* 		3. Topic<XX>                                                                                    */
/* 	  The error/warning messages and other information is put on the std out.  So, by redirecting the      */
/*        output of the _progres command, the script can interpret the result of the ApplicationControl run.  */
/*     o ActivateSOD                                                                                          */
/*       This will activate SOD in SOD Configuration Maintenance. Violations will be logged if any are found. */
/*     o DeactivateSOD                                                                                        */
/*       This will deactivate SOD in SOD Configuration Maintenance and reset all violations and loggings.     */
/*       This does not delete the SOD matrix.                                                                 */
/*                                                                                                            */
/* ========================================================================================================== */

assign vcParameter = session:parameter.

if vcParameter = "" or
   vcParameter = ?
then do:
    message "ERROR: Parameters should be supplied with applicationcontrol.p." skip.
    assign vlError = true.
end.
else do:
    if index(vcParameter, "-ACTION ") = 0
    then do:
        message "ERROR: Parameters should include the action to be performed." skip.
        assign vlError = true.
    end.

    if index(vcParameter, "-URL ")     = 0 and
       index(vcParameter, "-PROPATH ") = 0
    then do:
        assign vcPropath = os-getenv("PROPATH").

        if vcPropath = ? or
           vcPropath = ""
        then do:
            message "ERROR: If parameters does not include -URL then -PROPATH should be provided or PROPATH environment variable should be set." skip.
            assign vlError = true.
        end.
    end.
end.

if vlError
then do:
    message "Syntax is as follows : -param '-URL <url> -ACTION <action> -PROPATH <propath>'" skip
            "    where <action> can be one of the following:"                                skip
            "        o StartApplication"                                                     skip
            "        o StartApplication_no_housekeeping"                                     skip
            "        o StopApplication"                                                      skip
            "        o StopApplication_no_wait"                                              skip
            "        o StartDaemon [<DaemonName>]"                                           skip
            "        o StopDaemon <DaemonName>"                                              skip
            "        o UnconditionalStopDaemon <DaemonName>"                                 skip
            "        o DaemonStatus [<DaemonName>]"                                          skip
            "        o ResetDaemonConfiguration [<DaemonName>]"                              skip
            "        o ClearDaemonQueue <DaemonName>"                                        skip
            "        o Synchronize [Full|Limited|Topic<XX>]"                                 skip
            "        o OnlineHousekeeping"                                                   skip
            "        o ActivateSOD"                                                          skip
            "        o DeactivateSOD"                                                        skip.

    quit.
end.

assign vcAction  = if index(vcParameter, "-ACTION ") > 0
                   then entry(1, substr(vcParameter, index(vcParameter, "-ACTION ") + 8, -1, "CHARACTER"), "-")
                   else ""
       vcUrl     = if index(vcParameter, "-URL ") > 0
                   then entry(1, substr(vcParameter, index(vcParameter, "-URL ") + 5, -1, "CHARACTER"), " ")
                   else ""
       vcPropath = if index(vcParameter, "-PROPATH ") > 0
                   then entry(1, substr(vcParameter, index(vcParameter, "-PROPATH ") + 9, -1, "CHARACTER")," -")
                   else "".

if vcURL = ""
then do:
    assign vhServer = session.

    if vcPropath = ""
    then assign vcPropath = os-getenv("PROPATH").

    if vcPropath <> "" and
       vcPropath <> ?
    then do:
        message subst("PROPATH=&1", vcPropath) skip.
        assign propath = vcPropath.
    end.

    /* Start ComponentPool if necessary */
    assign vlFcOk = no.
    publish "ComponentPoolIsRunning" (output vlFcOk).

    if vlFcOk = no
    then do:
        <M-4 run Main  () in ComponentPool>
        session:add-super-procedure(vhFcComponent).
    end.
end.
else do:
    assign viCount       = 0
           vcConnection  = "-URL " + vcURL.

    create server vhServer.

    do while not vhServer:connected():
        assign vlFcOk = vhServer:connect(vcConnection, "", "", "") no-error.

        if not vlFcOk                    or
           error-status:error            or
           error-status:num-messages > 0 or
           not vhServer:connected()
        then do:
            if viCount = 2
            then leave.
            else do:
                pause 5 no-message.
                assign viCount = viCount + 1.
            end.
        end.
    end.

    if not vlFcOk                    or
       error-status:error            or
       error-status:num-messages > 0 or
       not vhServer:connected()
    then do:
        message subst("ERROR: Cannot connect to appservice: &1", vcURL) skip
                subst("       Connection parameters: &1", vcConnection) skip
                "Error-status of Progress:"                             skip.

        do viCount = 1 to error-status:num-messages:
            message error-status:get-message(viCount) skip.
        end.

        delete object vhServer.
        assign vhServer = ?.
        quit.
    end.
end.

EXECUTE-BLOCK:
do on error undo, leave
   on stop  undo, leave:
    run program/tapplication.p on vhServer persistent set vhProc (input 0) no-error.

    if error-status:error or
       error-status:num-messages > 0
    then leave EXECUTE-BLOCK.

    message "ExecuteAction Begin: Action=" vcAction skip.

    /* We put the method call to ExecuteAction between comments, so it will be reported when View Usage is used on the method!
    <M-3 run ExecuteActionDirect
       (input  ? (icAction), 
        output ? (ocMessage), 
        output ? (tDaemonStatusReturn), 
        output viFcReturnSuper (oiReturnStatus)) in TApplication>
    */
    run ExecuteActionDirect in vhProc(
        input vcAction,
        output vcMessage,
        output dataset tDaemonStatusRet,
        output viRet) no-error.

    if error-status:error or
       error-status:num-messages > 0
    then leave EXECUTE-BLOCK.

    for each tDaemonStatusRet:
        put tDaemonStatusRet.tcProperty format "x(40)" space.
        put unformatted tDaemonStatusRet.tcValue skip.
    end.

    message "ExecuteAction end:   Action=" vcAction ' * '
            "ReturnStatus="       viRet             ' * '
            "ErrorMsg="           vcMessage         skip 
            "Return status:"      viRet.
end.

do viCount = 1 to error-status:num-messages:
    message error-status:get-message(viCount) skip.
end.

empty temp-table tDaemonStatusRet.

if valid-handle(vhProc)
then do:
    run gipr_DeleteProcedure in vhProc no-error.

    if error-status:error or
       error-status:num-messages > 0
    then do viCount = 1 to error-status:num-messages:
        message error-status:get-message(viCount) skip.
    end.

    delete procedure vhProc no-error.

    if error-status:error or
       error-status:num-messages > 0
    then do viCount = 1 to error-status:num-messages:
        message error-status:get-message(viCount) skip.
    end.

    assign vhProc = ?.
end.

if vcURL <> ""
then do:
    assign vlFcOk = vhServer:disconnect() no-error.

    if not vlFcOk         or
       error-status:error or
       error-status:num-messages > 0
    then do viCount = 1 to error-status:num-messages:
        message error-status:get-message(viCount) skip.
    end.

    delete object vhServer.
    assign vhServer = ?.
end.

quit.