Thanks to the work sponsored by Forbrugerrådet Tænk, Zato ESB and app server has grown additional means through which it is now even easier to invoke SOAP services.

Given an existing WSDL, all that is needed is filling out a couple of forms and a pool of SOAP clients is automatically generated and available in a cluster.

Built on top of Suds, the feature is available in git master and here's a preview showing how to consume SOAP services without any need for direct XML manipulations in order to build a RESTful service validating credit card numbers with JSON output.

First, let's upload the service that will connect to SOAP and produce JSON on output.

Note that the service doesn't really know what type of output it produces - this is configured from the GUI and no code changes are needed for the service to produce XML instead of JSON.

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class ValidateCreditCard(Service):

    class SimpleIO:
        input_required = ('number',)
        output_required = ('card_type', 'is_valid')

    def handle(self):
        conn = self.outgoing.soap['Credit Card Validator'].conn

        with conn.client() as client:

            # Invoke a SOAP service dynamically with no need for stub classes
            result = client.service.CheckCC(self.request.input.number)

            # Results are turned into Python objects automatically
            self.response.payload.card_type = result.CardType
            self.response.payload.is_valid = result.CardValid

While not strictly required, let's say we need to secure our REST service with Basic Auth:


Now a channel is created through which requests will flow in. Note that the URL path is a pattern - all named attributes, such as number here, are available as input to services.

And although it's not used in this example, both JSON or XML can be mixed on input with URL parameters with full control of what has priority over other parts.


Next an outgoing SOAP connection is needed. Note that its serialization type is Suds - this is the new feature. The WSDL points to a free SOAP service online courtesy of CDYNE.

In the example below, each server will be given a pool of 20 SOAP clients, each generated dynamically on fly from the WSDL provided on input.

If you're coming from Java or C# background you'll note that no stubs nor client classes need to be generated. This is all taken care of behind the scenes so one can focus on invoking SOAP services straightaway.


With all that in place, the Zato service can now be invoked. curl is used from command line in the examples below:

$ curl -u user:password localhost:17010/validate-cc/4111111111111111 {"response": {"card_type": "VISA", "is_valid": true}}
$ curl -u user:password localhost:17010/validate-cc/123456789 {"response": {"card_type": "NONE", "is_valid": false}}

What if the WSDL changes with time? You only need to click 'Reload WSDL' and a new pool of SOAP clients will be created using the newest contents.


The feature will be released in the upcoming 2.0 release and until then - please use git master version.

While Zato can support AMQP, WebSphere MQ, ZeroMQ or FTP as well, the majority of environments will use the ubiquituous HTTP protocol only and this post describes the traffic patterns within a typical HTTP-only cluster consisting of a load-balancer, web admin, Redis, SQL ODB and two servers, right after it's been installed without any user-specific customizations.

Please refer to the Zato's architecture overview for a refresher on what role each of the components fulfills.

A diagram

  • In order to ensure high-availability (HA), incoming HTTP traffic is always routed through a load-balancer that distributes the load in a fair manner across the servers so that outside client applications don't access the servers directly and are never concerned if any of the servers is unavailable.

  • Servers always invoke external HTTP resources directly, from the systems they are installed on.

  • Servers never communicate directly with each other. If any server needs to send a message to another one, it's always done in an indirect manner using publish/subscribe with Redis.

  • Redis is also used by servers to store volatile or highly dynamic data, such as usage statistics, frequently accessed runtime configuration or user caches.

  • SQL ODB (Operational Database), which as of Zato 1.1 needs to be either PostgreSQL or Oracle, stores information that benefits from being kept in a relational database, usually data that needs to be always saved on disk as promptly as possible and shouldn't be stored in RAM first, as with Redis.

  • Web admin is a GUI used to manage Zato environments. Being based on Django, it connects to SQL ODB in order to store a few parts of its configuration but the vast majority of its functionality is merely a frontend that connects to servers, through the load-balanacer, to invoke the public API servers expose.

    In other words, this is a frontend only. Users are encouraged to use the API to create their own alternative frontend apps.

  • Arrowheads in the diagram represent the exact directions the traffic will follow - for instance, servers don't send messages to the load-balancer nor the latter will invoke Redis thus the arrows don't point in these directions.

Linux Journal has just published a free version of the Zato article originally written for the November 2013 issue.

The article presents the project, introduces the IRA philosophy of designing services that are:

  • Interesting
  • Reusable
  • Atomic and goes through the process of developing a sample integration using financial APIs of

Please check it out here.

A diagram Cover Article

A Zato ESB and application server feature that has just been added on GitHub is an HTTP access log.

This is an additional log to what has been already available in regular server logs and keeps nothing but information regarding HTTP requests in a format used by Apache httpd. This makes it possible to use existing tools in order to parse and extract interesting information out of the logs.

The log is kept in each server's ./logs/http_access.log file. For instance, if a server is in /opt/zato/server1, the log will be in /opt/zato/server1/http_access.log.

Here's a sample entry and descriptions of all the default fields: K070053855728592769928224227915635470962 "" [12/Jan/2014:20:11:53 +0100] "GET /zato/ping HTTP/1.1" 200 141 "-" "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/ libidn/1.23 librtmp/2.3"
Field Sample value Description
Remote address Address of the application issuing the request, X-Forwarded-For is used, if present, otherwise IP address of the client application is used.
CID K070053855728592769928224227915635470962 Correlation ID assigned to the request
Channel name "" Name of the channel invoked, either plain HTTP or SOAP
Timestamp [12/Jan/2014:20:11:53 +0100] Timestamp of the request. In local timezone by default but can be changed to UTC if need be.
HTTP info "GET /zato/ping HTTP/1.1" HTTP method, URL path invoked and HTTP method
Status code 200 HTTP status code returned in response
Response size 141 Size of the response in bytes
Referer "-" HTTP referer (sic), currently not used
User agent "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/ libidn/1.23 librtmp/2.3" User agent issuing the request

A feature that has recently landed in git master on GitHub and will be released in 2.0 is the ability to log into Zato's web-admin using OpenID.

This lets one make use of an already existing Single Sign-On (SSO) infrastructure instead of requiring Zato admins to memorize additional credentials.

Here's how to enable it:

  • Open the config file at /path/to/web/admin/config/repo/web-admin.conf

  • Change the OPENID_SSO_SERVER_URL to a URL your SSO server uses

  • Stop and start the web admin

  • For each user in web admin:

    • Make sure the user has been already created, let's say it's 'myuser'
    • Issue the new zato update openid command, for instance % zato update openid /path/to/web/admin myuser https:// OK %


  • zato update openid - the command to invoke
  • /path/to/web/admin - path to web admin's top-level directory
  • myuser - username whose OpenID claimed ID should be set - claimed ID of the user

No restarts are needed after updating a given user's credentials.

Note that enabling SSO disables regular password based authentication. To revert to the latter, set OPENID_SSO_SERVER_URL to "" and restart web admin.