Getting Started with Cognate

Welcome to Cognate, a package designed with making it easy to create component services. Cognate strives to ease the burden of configuration management and logging configuration, by providing the infrastructure. Cognate fosters component service architectures by making the design, implementation, and testing of services less of a chore.

To get up and running the following topics will be covered:

The intent is for ComponentCore to make life easier in the implementation of stand alone applications. The hope is to take some common service requirements and make the expression of those requirements trivial.

This guide will demonstrate utilizing the ComponentCore class to implement a service component in Hola Mundo Demo Service. The example service will be used to explain the configuration and logging features of Cognate.

Hola Mundo Demo Service

The HolaMundo example is a service that will print out a salutation, such as “Hola Mundo”. HolaMundo will allow for configuring the language translations of ‘Hola’ as the exclamation of the salutation. Language configuration should be per HolaMundo service instance. The default language setting will be Spanish. HolaMundo should allow for dynamically setting of the target of the salutation, with the default being Mundo.

Another requirement for the HolaMundo service, is that it should be easy to execute as a runnable service, and also be usable as a component to create more complex services.

The HolaMundo service is defined by the HolaMundo class, which is listed below. The source for HolaMundo can also be found at ‘example/hola_mundo.py’ of the Cognate source. Be sure to review the HolaMundo source, afterwards explanation of key features will be covered.

 1import sys
 2from cognate.component_core import ComponentCore
 3
 4class HolaMundo(ComponentCore):
 5    salutation_map = {
 6        'Basque': u'Kaixo',
 7        'Chinese': u"Nǐ hǎo",
 8        'English': u'Hello',
 9        'French': u'Bonjour',
10        'German': u'Hallo',
11        'Hindi': u"Namastē",
12        'Japanese': u"Kon'nichiwa",
13        'Spanish': u'Hola',
14    }
15
16    lang_choices = salutation_map.keys()
17
18    def __init__(self, lang='Spanish', **kwargs):
19        self.lang = lang
20
21        super(HolaMundo, self).__init__(**kwargs)
22
23    def cognate_options(self, arg_parser):
24        arg_parser.add_argument('-l', '--lang',
25                                default=self.lang,
26                                choices=self.lang_choices,
27                                help='Set the language for the salutation.')
28
29    def cognate_configure(self, args):
30        if self.lang not in self.lang_choices:
31            msg = '"lang" value of %s not allowed.' % args.lang
32            self.log.error(msg)
33            raise ValueError(msg)
34
35    def greet(self, name='Mundo'):
36        if not name:
37            name = 'Mundo'
38        salutation = self.salutation_map[self.lang]
39        greeting = salutation + ' ' + name
40        self.log.debug('Greeting: %s', greeting)
41        return greeting
42
43
44if __name__ == '__main__':
45    argv = sys.argv
46    service = HolaMundo(argv=argv)
47
48    while (True):
49        name = raw_input('Enter name ("quit" exits):')
50        if name == 'quit':
51            break
52
53        greeting = service.greet(name)
54        print greeting

The HolaMundo class lang attribute is used to control the language option of the service. The salutation_map and lang_choices class attributes manage the languages supported. The greet method will return a greeting with the configured language exclamation and the target name.

The HolaMundo service can be executed with the command:

python example/hola_mundo.py

Configuration Management and Initialization

The HolaMundo class hierarchy is as shown below:

_images/cognate_utilization_example_hierarchy.png

ComponentCore Example Hierarchy

The essence of how ComponentCore performs it’s operations is via the use of cognate.component_core module to derive configuration of service stack. The basic call sequence is depicted in the image below.

_images/cognate_utilization_example_sequence.png

cognate_options() and cognate_configure() methods via the use of the invoke_method_on_children(). This effectively calls the cognate_options and cognate_configure methods on all primary base classes that derive from ComponentCore.

ComponentCore helps out with configuration management and initialization of runtime services. it does this by creating a configuration loop. Utilizing the Hola Mundo Demo Service as an example.

Command Line Option Construction

ComponentCore provides the means for command line construction to inheriting classes. This is achieved by the ingestion of command line options through invocation of configure_option method on the chain of ancestor classes that declare the configuration_option method.

The net effect is that ComponentCore will collect all of the configuration options in one bundle, and manage them as a unified instance configuration. This allows for the centralization of common options and the attending code.

For more detail on this feature, be sure to check out _execute_configuration().

Logging and Log Configuration

ComponentCore supports console and file output. In addition ComponentCore supports the four basic log levels: debug,`info`,`warning`,`error`.

The configuration logging options are:

arg

–log_level {debug,info,warning,error}

Set the log level for the log output.

arg

–log_path LOG_PATH

Set the path for log output. The default file created is “<log_path>/<service_name>.log”. If the path ends with a “.log” extension, then the path be a target file.

arg

–verbose

Enable verbose log output to console. Useful for debugging.

ComponentCore log configuration takes advantage of the Dynamic Service Naming for log file naming, as well as in log name output.

For example:

2012-12-02 03:26:03,030 - <name> - INFO - Logging configured for:
VentilatorWindmill

The <name> value will be assigned by default to the instance class utilizing ComponentCore, but will be overridden by the use of the ‘–service_name <name>’ option.

Dynamic Service Naming

ComponentCore provides a mechanism to allow for dynamic naming of progenitor class service instances. This is achieved through the use of the ‘–service_name <name>’ option. When this flag is set ComponentCore will set the self.service_name instance to the designated value. In addition, ComponentCore will set the self.name_set flag to True.

By default ComponentCore will set the name of the instance class.

The assigned name can effect the output log name, as well as name of the log output. The use of self.name may also effect features from other progenitor classes that take advantage of ComponentCore dynamic naming.

Child classes of ComponentCore can access the configured service app name through self.service_name.