---
name: "NetSDS::App"
section: "3pm"
platform: "linux"
package: "libnetsds-perl"
version: "1.301-4"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/NetSDS::App"
---

# NetSDS::App(3pm)

common application superclass

## NAME

NetSDS::App - common application superclass

## SYNOPSIS

```
        #!/usr/bin/env perl

        use 5.8.0;
        use warnings;
        use strict;
        MyApp->run(
                conf_file => '/etc/NetSDS/myapp.conf', # default place for config search
                daemon => 1,      # run in daemon mode
                use_pidfile => 1, # write PID file to avoid double processing
                verbose => 0,     # no verbosity
        );
        1;
        # Application logic here
        package MyApp;
        use base 'NetSDS::App';
        # Startup hook
        sub start {
                my ($self) = @_;
                # Use configuration
                $self->{listen_port} = $self->conf->{listen_port};
                # Use logging subsystem
                $self->log("info", "Application successfully started with PID=".$self->pid);
        }
        # Main processing hook
        sub process {
                my ($self) = @_;
                print "Hello!";
                # Use verbose output
                $self->speak("Trying to be more verbose");
        }
```

## DESCRIPTION

`"NetSDS::App"` is a base class for NetSDS applications. It implements common functionality including the following:

```
        * initialization
        * configuration file processing
        * command line parameters processing
        * application workflow
        * daemonization
        * PID file processing
        * logging
        * event detail records writing
        * default signal handling
```

New application should be inherited from `"NetSDS::App"` class directly or via child classes for more specific tasks like CGI, AGI, SMPP and other.

Common application workflow is described on this diagram:

```
        App->run(%params)
           |
        initialize()
           |
           ----------
           |        |
        start()     |
           |        |
        process()   --- main_loop()
           |        |
        stop()      |
           |        |
           ----------
           |
        finalize()
```

When application is starting `"initialize()"` method is invoked first. It provides common start time functionality like CLI parameters processing, daemonization, reading configuration.

`"initialize()"` method may be overwritten in more specific frameworks to change default behaviour of some application types.

Then `"main_loop()"` method invoked to process main application logic. This method provides three redefinable hooks: `"start()"`, `"process()"` and `"stop()"`. Theese hooks should be overwritten to implement necessary logic.

- •

  **start()** - start time hook

- •

  **process()** - process iteration hook

- •

  **stop()** - finish time hook

Depending on `"infinite"` flag **main\_loop()** may call **process()** hook in infinite loop or only once.

`"main_loop()"` workflow may be redefined in inherited framework to implement some other process flow logic.

On the last step `"finalize()"` method is invoked to make necessary finalization actions on framework level.

## STARTUP PARAMETERS

Application class may be provided with a number of parameters that allows to manage application behaviour. For example it may be a configuration file, daemonization mode or debugging flag.

Such parameters are passed to **run()** method as hash:

```
        MyApp->run(
                has_conf => 1,
                conf_file => '/etc/sample/file.conf',
                daemon => 1,
                use_pidfile => 1,
        );
```

- •

  **has\_conf** - 1 if configuration file is required (default: yes)

  Mostly our applications requires configuration files but some of them doesn't require any configuration (e.g. small utilities, etc). Set `"has_conf"` parameter to 0 to avoid search of configuration file.

- •

  **conf\_file** - default path to configuration file (default: autodetect)

  This parameter allows to set explicitly path to configuration file. By default it's determined from application name and is looking like `"/etc/NetSDS/{name}.conf"`

- •

  **name** - application name (default: autodetect)

  This name is used for config and PID file names, logging. By default it's automatically detected by executable script name.

- •

  **debug** - 1 for debugging flag (default: no)

- •

  **daemon** - 1 for daemon mode (default: no)

- •

  **verbose** - 1 for verbose mode (default: no)

- •

  **use\_pidfile** - 1 to use PID files (default: no)

- •

  **pid\_dir** - path to PID files catalog (default: '/var/run/NetSDS')

- •

  **auto\_features** - 1 for auto features inclusion (default: no)

  This parameter should be set to 1 if you plan to use automatically plugged application features. Read `"PLUGGABLE APPLICATION FEATURES"` section below.

- •

  **infinite** - 1 for inifinite loop (default: yes)

- •

  **edr\_file** - EDR (event detail records) file name (default: undef)

## COMMAND LINE PARAMETERS

Command line parameters may be passed to NetSDS application to override defaults.

- •

  **--conf** - path to config file

- •

  **--\[no\]debug** - set debug mode

- •

  **--\[no\]daemon** - set daemon/foreground mode

- •

  **--\[no\]verbose** - set verbosity mode

- •

  **--name** - set application name

These CLI options overrides `"conf_file"`, `"debug"`, `"daemon"`, `"verbose"` and `"name"` default parameters that are passed in **run()** method.

Examples:

```
        # Debugging in foreground mode
        ./application --config=/etc/myapp.conf --nodaemon --debug
        # Set application name explicitly
        ./application --name=myapp
```

## CLASS API

- **new(\[%params\])** - class constructor

  Constructor is usually invoked from `"run()"` class method. It creates application object and set its initial properties from oarameters passed as hash.

  Standard parameters are:

  ```
          * name - application name
          * debug - set to 1 for debugging
          * daemon - set to 1 for daemonization
          * verbose - set to 1 for more verbosity
          * use_pidfile - set to 1 for PID files processing
          * pid_dir - path to PID files catalog
          * conf_file - path to configuration file
          * has_conf - set to 1 if configuration file is necessary
          * auto_features - set to 1 for auto features inclusion
          * infinite - set to 1 for inifinite loop
  ```

- **run(%parameters)** - application launcher

  This method calls class constructor and then switch to `"main_loop()"` method.

  All method parameters are transparently passed to application constructor.

  ```
          #!/usr/bin/env perl

          use 5.8.0;
          use warnings;
          use strict;
          MyApp->run(
                  conf_file => '/etc/myapp.conf',
                  daemon => 1,
                  use_pidfile => 1,
          );
          1;
          # **********************************
          # Logic of application
          package MyApp;
          use base 'NetSDS::App';
          1;
  ```

- **name(\[$name\])** - application name

  This method is an accessor to application name allowing to retrieve this or set new one.

  ```
          print "My name is " . $self->name;
  ```

- **pid()** - PID of application process

  Read only access to process identifier (PID).

  ```
          print "My PID is " . $self->pid;
  ```

- **debug()** - debugging flag

  This method provides an accessor to debugging flag. If application called with --debug option it will return TRUE value.

  ```
          if ($self->debug) {
                  print "Debug info: " . $debug_data;
          }
  ```

- **verbose()** - verbosity flag

  This method provides an accessor to verbosity flag.

  It may be used to increase application verbosity level if necessary.

  ```
          if ($self->verbose) {
                  print "I'm working!";
          };
  ```

  NOTE: This flag is is for normal operations. If you need implement debug  output or other development/testing functionality - use **debug()** instead.

- **logger()** - accessor to logger

  This method is accessor to logger (object of NetSDS::Logger class).

  NOTE: There is no need to use this method directly in application. See `"log()"` method description to understand logging features.

- **conf()** - accessor to configuration

  This method is accessor to application configuration represented as hash reference returned by NetSDS::Conf module.

  Configuration sample:

  ```
          ------------------------
          content_dir /var/lib/content
          <kannel>
                  send_url http://127.0.0.1:13013/
                  login netsds
                  passwd topsecret
          </kannel>
          ------------------------
  ```

  Code sample:

  ```
          # Retrieve configuration
          my $content_dir = $self->conf->{content_dir};
          my $kannel_url = $self->conf->{kannel}->{send_url};
  ```

- **use\_pidfile(BOOL)** - PID file checking flag

  Paramters: TRUE if PID file checking required

- **pid\_dir(\[$directory\])** - PID files storage

  Paramters: directory name

  ```
          $app->pid_dir("/var/run");
  ```

- **daemon(BOOL)** - daemonization flag

  Paramters: TRUE if application should be a daemon

  ```
          if ($self->daemon()) {
                  $self->log("info", "Yeah! I'm daemon!");
          };
  ```

- **auto\_features()** - auto features flag

  Automatic features inclusion allowed if TRUE.

- **infinite(\[$bool\])** - is application in infinite loop

  Example:

  ```
          # Switch to infinite loop mode
          $app->infinite(1);
  ```

- **edr\_file(\[$file\_name\])** - accessor to EDR file name

  Paramters: EDR file path

- **initialize()**

  Common application initialization:

  1\. Reading config if necessary.

  2\. Daemonize application.

  3\. Check PID file for already running application instances.

  4\. Start logger.

  5\. Prepare default signal handlers.

- **use\_auto\_features()** - add features to application

  This method implements automatic features inclusion by application configuration file (see `"feature"` sections).

- **add\_feature($name, $class, $config, %params)** - add feature

  Paramters: feature name, class name, parameters (optional)

  Returns: feature object

  ```
          $self->add_feature('kannel','NetSDS::Feature::Kannel', $self->conf->{feature}->{kannel});
          $self->kannel->send(.....);
  ```

- **finalize()** - switch to finalization stage

  This method called if we need to finish application.

- **start()** - user defined initialization hook

  Abstract method for postinitialization procedures execution.

  Arguments and return defined in inherited classes. This method should be overwritten in exact application.

  Remember that **start()** methhod is invoked after **initialize()**

- **process()** - main loop iteration hook

  Abstract method for main loop iteration procedures execution.

  Arguments and return defined in inherited classes.

  This method should be overwritten in exact application.

- **stop()** - post processing hook

  This method should be rewritten in target class to contain real post processing routines.

- **main\_loop()** - main loop algorithm

  This method provide default main loop alghorythm implementation and may be rewritten for alternative logic.

## LOGGING AND ERROR HANDLING

- **log($level, $message)** - write message to log

  This method provides ablity to write log messages to syslog.

  Example:

  ```
          $self->log("info", "New message arrived with id=$msg_id");
  ```

- **error($message)** - return error with logging

  This method extends inherited method functionality with automatically logging this message to syslog.

  Example:

  ```
          if (!$dbh->ping) {
                  return $self->error("We have problem with DBMS");
          }
  ```

- **speak(@strs)** - verbose output

  Paramters: list of strings to be written as verbose output

  This method implements verbose output to STDOUT.

  ```
          $self->speak("Do something");
  ```

- **edr($record \[,$record..\])** - write EDR

  Paramters: list of EDR records to write

  ```
          $app->edr({
                  event => "call",
                  status => "rejected",
          });
  ```

- **config\_file($file\_name)** - determine full configuration file name

  ## PLUGGABLE APPLICATION FEAUTURES

To add more flexibility to application development `"NetSDS::App"` framework allows to add pluggable features. Application feature is a class dynamically loaded into application using configuration file parameters.

To use application features developer should do the following:

\* set auto\_features **run()** parameter

\* create `"feature"` sections in application as described

\* create feature classes inherited from NetSDS::Feature

## EXAMPLES

See samples/app.pl

## BUGS

This module is a one bug itself :-)

## SEE ALSO

NetSDS, NetSDS::Class::Abstract, NetSDS::Logger

## TODO

Fix and cleanup!

## AUTHOR

Valentyn Solomko \<val@pere.org.ua\>

Michael Bochkaryov \<misha@rattler.kiev.ua\>

## LICENSE

Copyright (C) 2008-2009 Net Style Ltd.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
