While the APIs described in the previous section are required to to define the configuration of an experiment; software that interacts with the running program manager will do so via one or more of the REST interfaces and APIs provided for them.
REST, or REpresentational State Transfer interfaces are a mechanism to use normal web (http and https) protocols to map URLs and query/form data to operations in a server. The NSCLDAQ manager program provides several URL families (or domains) and we also provide Tcl packages to allow your applications to interact with those domains.
When the manager starts up, it uses the NSCLDAQ port manager to advertise its REST service port. By default this port is given the service name DAQManager. REST interfaces, in general, do not make use of persistent connections. In order to be robust with respect to manager restarts, the rest client code looks up the service port for each request.
In the remainder of this section we will:
Describe and show examples of the REST client for handling state transitions.
Describe and show examples of the REST client for checking the status of programs run by the manager.
Describe and show examples of the REST client for accessing the key value store.
Describe and show examples of the REST client for managing event logging.
This client package, stateclient provides a REST client to the State domain of the DAQ manager. In order to use it, you must know the host in which the DAQ manager is running and the user that ran the manager (the NSCLDAQ port manager advertises services as servicename-username pairs).
The REST client is exported in an object oriented manner. Applications create an inteface object and then invoke its methods to perform various actions. Reference material is available: stateclient
The sample application below gets the current state of the system, produces a list of the valid next states and then attempts a transition into the first of the valid next states. Please don't try this yourself, in general the state transition we're going to trigger makes little to no sense.
The application accepts the host and username as command parameters.
Example 46-17. Sample State Transition REST Client
if {[array names env DAQTCLLIBS] ne ""} { lappend auto_path $env(DAQTCLLIBS) } package require stateclientproc usage {msg} {
puts stderr "Usage: " puts stderr " $::argv0 host user" puts stderr "Where:" puts stderr " host is the host in which the manager is running and" puts stderr " user is the user that started the manager." exit -1 } if {[llength $argv] != 2} { usage } set host [lindex $argv 0]
set user [lindex $argv 1] StateClient client -host $host -user $user
puts "Current state: [client currentState"]
set nextStates [client nextStates]
puts "Allowed next states are [join $nextStates {, }]" client transition [lindex $nextStates 0]
client destroy
exit 0
Options can also be provided to construction and these, in this case, provide the host and username. The result of this construction is a command ensemble named client whose subcommands are object method invocations. Note that, as with Tk object construction, construction also returns the name of the object. In some object systems like e.g. snit, the special object name %AUTO% makes the object system assign a unique object name to the constructed object.
currentState
method of a
StateClient
object returns the name
of the current state in which the state machine is now in.
nextStates
method of
StateClient
objects returns a list of
valid next state names. That is a list of valid transitions
out of the current state. Note that the code that follows
assumes that the state we are in is not terminal, that is there is
at east one valid next state.
StateClient
object has a
pre-defined method destroy
which
destroys the object. We call this before exiting the program.
The programstatusclient package provides an
object oriented interface to the REST server domain that
exports information about container and program status. It
exports a single class: ProgramClient
.
Instances of that object support the status
method in addition to the pre-defined destroy
,
configure
and cget
methods
Reference information is available: programstatusclient.
The example below creates a client, requests the status and displays a list of which containers are activated and in which systems they have been activated.
Example 46-18. Using The programstatusclient Package
if {[array names env DAQTCLLIBS] ne ""} { lappend auto_path $env(DAQTCLLIBS) } package require programstatusclientproc usage {} { puts stderr "Usage:" puts stderr " $::argv0 host user" puts stderr "Where:" puts stderr " host is the host on which the manager is running and" puts stderr " user is the name of the user running the manager" exit -1 } if {[llength $argv] != 2} { usage } set host [lindex $argv 0] set user [lindex $argv 1] ProgramClient client -host $host -user $user
set info [client status]
set containers [dict get $info containers] puts "Active Containers:" foreach container $containers { set name [dict get $container name] set image [dict get $container image] set activations [dict get $container activations] if {[llength $activations] > 0} { puts "$name ($image) is active in [join $activations {, }]" } } client destroy
exit 0
ProgramClient
object
that will be used to communicate with the REST server.
The -host
and -user
options describe how to perform service discovery.
The user and host can be provided at construction time as
shown here or any time prior to the first REST request
using the configure
method.
The object name will be client. This will be a new base command for a command ensemble who's members are the methods supported by the object.
status
method/subcommand provides
the status of all containers and programs. The return value
is a dict with two keys: containers that
provides information about container activations and
programs which provides information about
the programs that have been defined and their status.
In this sample, we just output information about the containers. The value of the containers key is a list of dicts. Each of the dicts describes a container. For this application we only need to know that name is the container name, image is the path to the container image file in the host filesystem and activations is a list of the hosts on which the container is activated (this will be an empty list if the container is not active).
Subsequent code iterates over the containers outputting, for each container with at least one activation, information about the container and where it's active.
The kvclient package provides an object oriented API to the key value store. Using this package, you can set and get values of keys as well as list keys and dump the complete contents of the store.
Full documentation on this package is available at kvclient. In the example below we set the title key and dump the entire KV store. The title key is used by the Readout support software to set the run titles in the various Readouts used by the experiment.
Example 46-19. Using the kvclient Package.
if {[array names env DAQTCLLIBS] ne ""} { lappend auto_path $env(DAQTCLLIBS) } package require kvclientproc usage {} { puts stderr "Usage" puts stderr " $::argv0 host user new title words" puts stderr "Where:" puts stderr " host and user specify the host running the manager and puts stderr " user that started it. The remaining parameters are puts stderr " the new title to set. They will be combined separated by spaces" exit -1 } if {[llength $argv] < 3} { usage } set host [lindex $argv 0] set user [lindex $argv 1] set title [lrange $argv 2 end]
KvClient client -host $host -user $user
client setValue title $title
puts "Dump of kv store:" dict for {name value} [client list] {
puts "$name : $value" } client destroy
![]()
title
from the words on the command line that follow the host and user
(words 2 through the end).
-host
and -user
options
from the values on the command line. Note that constructing
the object does not network operations. Network operations, like
service discovery and connecting to the server are only
done when a REST request is made.
setValue
method accepts two parameters,
the name of an existing key value store key and the new value
to give to it. This sets the key title
to the title words the user passed in on the command line.
list
method dumps the entire
key value store, returning it as a dict whos keys are key value
store keys and whose values are the values of the corresponding
key value store key.
destroy
method destroys the client
when we are done using it. Note that given the nature of
interactions with REST servers, KvClient
instance objects are quite light weight.
The loggerrestclient package provides an object oriented interface to the REST domain (/Loggers) in the manager server that manages event loggers. Reference material for this package is available loggerrestclient
The following example program enables all loggers, sets the recording state on and starts the loggers.
Example 46-20. Using the loggerrestclient Package
if {[array names env DAQTCLLIBS] ne ""} { lappend auto_path $env(DAQTCLLIBS) } package require loggerrestclientproc usage {} { puts stderr "Usage:" puts stderr " $::argv0 host user" puts stderr "Where:" puts stderr " host is the host on which the manager server is running." puts stderr " user is the user who started the server. exit -1 } if {[length $argv] != 2} { usage } set host [lindex $argv 0] set user [lindex $argv 1] LoggerRestClient client -host $host -user $user
foreach logger [client listLoggers] {
client enableLogger [dict get $logger destination]
} client record 1
client start
client destroy
![]()
listLoggers
method of a logger
REST client instance returns a list of dicts. Each dict includes,
among other keys, a destination key
which contains the logger destination. The logger
destination is required, by the API to be unique and is used
in the REST API, rather than the invisible id, to identify
loggers.
enableLogger
method enables
the logger designated by its destination. If that logger
is already enabled this call silently has no effect.
record
method sets the state of
the global recording flag.