Programmer’s Manual – Node Services

Access Grid Toolkit Documentation

 

Argonne National Lab and University of Chicago
ag-info@mcs.anl.gov

3/9/2005

 

Abstract

This manual is a guide for developers interested in creating services for an Access Grid node. The manual gives an overview of the node services infrastructure currently available in the Access Grid Toolkit and provides step-by-step instructions on how to build a service. In addition, this document describes how to package and install a service to make it available in Venue Clients. The Access Grid team highly encourages developers to build node services, and this manual provides necessary information to successfully implement the task.

1. Introduction

The media tools for the Access Grid Toolkit 2.3 (AGTk), VIC for video and RAT for audio, are encapsulated in the node service infrastructure illustrated in Figure 1.

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 1 Node Setup

 

For each machine in the node, an AGServiceManager is started to administer AGServices controlling media tools on that machine. The Venue Client connects to the AGNodeService, the central communication point for AGServiceManagers, to collect information and communicate with the AGServices distributed in the node. This configuration allows for flexibility of your AG room arrangement; you can add hardware such as an extra machine or cameras based on your specific requirements. The node in Figure 1 is running a VIC video consumer service on the Video Display Machine, and a RAT audio service and three VIC video producer services for camera capture on the Audio and Video Capture Machine.

 

The AGTk is not restricted to using VIC and RAT for media but can be extended with new services using other tools. Here we focus on how to create a simple service, from concept to installation, providing a step-by-step example of how to get started developing a new media service for the Access Grid. 

 

2. The Debug Service – A Minimal Service Example

The following example, creation of a simple Debug Service, describes necessary steps for implementing a new service. Please note that the example is used simply to demonstrate the concept. The following sections provide a walkthrough of the Debug Service code given below. You can also find the Debug Service package here.

 

 

import os

import sys

 

from AccessGrid.GUID import GUID

from AccessGrid.AGService import AGService, AGServiceI, RunService

from AccessGrid.Types import Capability

from AccessGrid.AGParameter import ValueParameter, OptionSetParameter

from AccessGrid.AGParameter import RangeParameter, TextParameter

 

1.                class DebugService(AGService):

2.                """

3.                Simple service that prints configuration information. It claims to    

4.                be a video and audio producer and consumer just to get information.

5.                """

 

6.                def __init__(self):

7.                    AGService.__init__(self)

8.                    self.log.debug("DebugService.__init__: Init Service")

9.                    self.id = str(GUID())

 

10.                # Set capabilities

11.                self.capabilities = [ Capability( Capability.CONSUMER,

                                            Capability.AUDIO

                                Capability( Capability.CONSUMER,   

                                            Capability.VIDEO ),

                                Capability( Capability.PRODUCER,

                                            "debug" ) ]

12.                # Set executable

13.                self.executable = None

 

14.                # Set configuration parameters

15.                self.param1 = OptionSetParameter("Configuration Parameter 1: 

16.                                                ", "On", ["On", "Off"] )

17.                self.param2 = RangeParameter( "Configuration Parameter 2: ",

1.                0, 0, 100 )

18.                self.param3 = TextParameter( "Configuration Parameter 3: ",

1.                "DebugService" )

19.                self.param4 = ValueParameter("Configuration Parameter 4:", 25)

 

20.                # Append parameters to the configuration list

21.                self.configuration.append(self.param1)

22.                self.configuration.append(self.param2)

23.                self.configuration.append(self.param3)

24.                self.configuration.append(self.param4)

 

25.                # ------------------------------------------------------------

26.                # overridden methods inherited from AGService

27.                # ------------------------------------------------------------

 

28.                def Start(self):

29.                    self.log.debug("DebugService.Start")

 

30.                def Stop(self):

31.                    self.log.debug("DebugService.Stop")

 

32.                def ConfigureStream(self, streamDescription):

33.                    self.log.debug("DebugService.ConfigureStream %s  

34.                                   "%streamDescription)

35.                    if self.param1.value == "On":

            self.log.info("DebugService.ConfigureStream: value

                           parameter is on!")

 

36.                def SetIdentity(self, profile):

37.                    self.log.debug("DebugService.Set Identity %s"%profile)

38.                    if self.param1.value == "On":

            self.log.info("DebugService.SetIdentity: value

                           parameter is on!")

 

 

39.            if __name__ == '__main__':

 

40.                # The port argument should always be set to sys.argv[1]

41.                port = int(sys.argv[1])

 

42.                # Create the display service

43.                debugService = DebugService()

 

44.                # Create the SOAP interface for the service

45.                debugServiceI = AGServiceI(debugService)

 

46.                # Start the service

47.                RunService(debugService, debugServiceI, port)

 

 

2.1 The AGService Base Class

The AGService is the base class to use when creating services for your node. It includes the core functionality necessary to create a node service. The new class should inherit from the AGService class and override appropriate methods.

 

1.                class DebugService(AGService):

2.                """

3.                Simple service that prints configuration information. It claims to    

4.                be a video and audio producer and consumer just to get information.

5.                """

 

6.                def __init__(self):

7.                    AGService.__init__(self)

2.2 Defining Capabilities

Each service is defined by its capabilities, describing what actions the service is able to perform. In the 2.3 version of the toolkit, a capability consists of the role and type parameters; the role reflects whether the service is a consumer or a producer, and the type specifies what kind of content is exchanged. The Debug Service specifies three capabilities: audio consumer, audio producer, and video consumer. The video consumer capability also adds a custom type, “debug,” which demonstrates how a new type may be set. When entering a venue, each new producer of a certain type is assigned its own multicast address in the venue for communication. 

 

10.    # Set capabilities

11.    self.capabilities = [ Capability( Capability.CONSUMER,

                                         Capability.AUDIO

                             Capability( Capability.CONSUMER,   

                                         Capability.VIDEO ),

                             Capability( Capability.PRODUCER,

                                         "debug" ) ]

2.3 Receiving Information

When entering a venue, the service gets information about streams it will consume or produce via the ConfigureStream method. The overridden method should include necessary code for configuring the service. Profile information, which may be use for RTP data, is received via the SetIdentity method.

 

32.    def ConfigureStream(self, streamDescription):

33.        self.log.debug("DebugService.ConfigureStream %s  

34.                       "%streamDescription)

35.        if self.param1.value == "On":

               self.log.info("DebugService.ConfigureStream: value

                              parameter is on!")

 

36.    def SetIdentity(self, profile):

37.        self.log.debug("DebugService.Set Identity %s"%profile)

38.        if self.param1.value == "On":

self.log.info("DebugService.SetIdentity: value

parameter is on!")

2.4 Setting the Executable

The service must specify the name of the executable file; for the standard audio service this is rat. Since the Debug Service does not really do anything, we just set the executable to None.

 

12.    # Set executable

13.    self.executable = None

 

2.5 Starting and Stopping the Service

The new service must implement Start and Stop methods with correct code to initialize and shut down the service.  The Access Grid team recommends using the AGService._Start(options) method from the super class. To actually start the executable file with an option list, you would add this in the Start() method, as indicated below.

 

28.    def Start(self):

29.        self.log.debug("DebugService.Start")

 

30.    def Stop(self):

31.        self.log.debug("DebugService.Stop")

 

2.6 Setting Configurable Options

If the service needs configurable parameters, they can be added to the configuration list of the AGService. The parameters will be displayed and editable in the Node Management window if you select to configure a service; see Figure 2. There are four kinds of parameters (i.e., four ways to display configurable options for the user):

 

OptionSetParameter(name, defaultOption, optionsList)  - The optionsList will be displayed in a dropdown menu with defaultOption set as default.

 

RangeParameter(name,  initialValue, startValue, stopValue) – Shows a slider with startValue as minimum value and stopValue as maximum value. The initialValue will be the starting point for the slider.

 

TextParameter(name, value) Represents a text field set to value as a string.

 

ValueParameter() – Represents a integer field set to value as an integer.

 

The Debug Service implements following configuration parameters:

 

       # Set configuration parameters

15.    self.param1 = OptionSetParameter(Configuration Parameter 1: 

16.                                    , On, [On, Off])

17.    self.param2 = RangeParameter(Configuration Parameter 2: ,

0, 0, 100 )

18.    self.param3 = TextParameter(Configuration Parameter 3: ,

DebugService)

19.    self.param4 = ValueParameter(Configuration Parameter 4:, 25)

 

20.    # Append parameters to the configuration list

21.    self.configuration.append(self.param1)

22.    self.configuration.append(self.param2)

23.    self.configuration.append(self.param3)

24.    self.configuration.append(self.param4)

 

Figure 2 shows how the Debug Service parameters above are displayed in the Node Configuration Dialog accessible from the Node Management window. You can open the dialog by right-clicking a service and then select Configure….

 

Figure 2 Configuration Dialog.

2.7 Initializing the Service

Each service must be accessible via a SOAP interface for the AGServiceManagers to connect to services over the network. To expose a SOAP interface in the AGTk 2.3, create a service instance from the AGServiceI class. The RunService(implementation, interface, port) function is available in AGService to start the SOAP service. It takes the implementation object, the SOAP interface object, and a port as parameters. The port is always specified via the command line. The following code must be in the main module of the service to make it start properly.

 

39.    if __name__ == '__main__':

 

40.        # The port argument should always be set to sys.argv[1]

41.        port = int(sys.argv[1])

 

42.        # Create the display service

43.        debugService = DebugService()

 

44.        # Create the SOAP interface for the service

45.        debugServiceI = AGServiceI(debugService)

 

46.        # Start the service

47.        RunService(debugService, debugServiceI, port)

 

2.8 Packaging and Installation

To distribute your service, you should create a service package. The zip archive should contain the service file, executable files, and a SVC file describing the service. The following is DebugService.svc:

 

[ServiceDescription]

name = DebugService

description = Example Debug Service

capabilities = Capability1 Capability2 Capability3

executable = DebugService.py

platform = neutral

version = 1.0

 

[Capability1]

role = consumer

type = audio

 

[Capability2]

role = consumer

type = video

 

[Capability3]

role = producer

type = debug

 

After creating the package, use the Access Grid Package Manager (AGPM) to install it with following command agpm.py --package=/path/to/package.zip. The --help flag lists all possible options for agpm.

 

The service package is stored in

 

Windows: C:\Program Files\AGTk-2.3\NodeServices 

Linux: /etc/AccessGrid/NodeServices

 

All services in this directory are listed in the service dialog available from the Node Management window, see Figure 3.

 

Figure 3 Service Dialog.

 

When first added in the Node Management window, the service gets extracted into the following directory:

 

Windows: C:\Documents and Settings\<user>\Application Data\AccessGrid\local_services

Linux: ~/.AccessGrid/local_services

 

This situation happens once; if a service with the same version is already present, the package will not be extracted.

 

2.9 Using the Service

Once the service has been added, the Node Management window can be used to start, stop, and configure the service. From the Venue Client menu, open Preferences – Manage My Node…, select a ServiceManager from the list, and go to Services – Add… in the menu. Select the service, and click OK. If you right-click the added service, you will find available user options.

 

3. Logging

Error and debug information added in your code will be stored in the log files. On Windows platforms you can find this information in

 

Windows: C:\Documents and Settings\<user>\Application Data\AccessGrid\Logs

Linux: ~/.AccessGrid/Logs