This chapter discusses several approaches as to where to keep configuration
that is specific to services you develop, i.e. it’s not about how to configure Zato itself, rather where to
keep run-time parameters you will want to use in your own services.

In short, you can keep it anywhere you want, in any data source and you’re not limited
to the choices described here but these are still recommendations you may want to
consider using.

zato_extra_paths is a directory to
keep extra libraries that are not part of Zato. When a server is starting,
anything that is on zato_extra_paths - either directly or through symlinks - will
be added to PYTHONPATH.

This allows one to import values from a config library simply like from any other Python
module.

The drawback is, any changes you make to the config module won’t be automatically
picked up, each server needs to be restarted manually for new changes to take effect.

You can store configuration in plain Python in a SimpleIO-based (SIO)
service designated to a role of a config service. This will be a service that itself won’t usually accept
any external requests nor will it be allowed to invoke it through a channel
or scheduler.

As with Redis, such an approach lets you
hot-deploy
any config changes without restarting
the servers.

Note that any config values must always be assigned to a class directly - never
to an instance (self). As described in the
programming conventions section, this is because each invocation
of a service creates a new instance.

Being a SIO one, you can invoke it with regular Python dicts or anything dict-like.

Note however that there is no guarantee as to in what order services are deployed
on servers, hence, you must ensure that such a service is available to its users
before other services start accessing it.

You have access to a range of hooks that let you plug
into a lifecycle of a service so you can fetch configuration from data
sources outside of Zato if need be.

In particular, before_add_to_store is a good candidate
because this static method is executed well before a service this method is part of
is first time invoked. As such, it can be used to pull config data and assign it to class
it is a method of.

Again, remember that there is no guarantee with regards to the order in which
services are deployed on servers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

fromzato.server.serviceimportServiceclassMyConfigService(Service):# The config is initially empty but it will be populated in before_add_to_storeconfig={}classSimpleIO(object):response_elem='config'input_required=('key',)output_required=('value',)defhandle(self):self.response.payload.value=self.config.get(self.request.input.key,'err')@staticmethoddefbefore_add_to_store(logger):# Imagine LDAP or any other data source is queried here and it returns# a dictionary of configuration.external_config=get_config()# Set config to whatever was fetchedMyConfigService2.config.update(external_config)# Always return True if you want for the service to be deployedreturnTrue