Runtime Updates

This article describes the features implemented in the UltraESB to support loading, unloading and reloading of configuration changes at runtime. These changes can be executed via UTerm command line client or via JMX (e.g. JConsole)

The UltraESB Configuration - Defined in one, two or more files?

The UltraESB configuration is driven by a standard Spring configuration file, with a few custom extension elements that defines Proxy Services, Sequences and Endpoints. You may notice that the default configuration shipped with the binary distribution has broken the configuration into two files and a deployment unit, namely the ultra-root.xml, ultra-custom.xml and the default deployment unit. This separation, was planned and introduced from the very first version of the UltraESB (The concept of deployment unit has been introduced in 2.0.0 release replacing the dynamic sub contexts), to allow configuration reloads at runtime.

Samples are static and flat
However, if you take any of the samples, you will notice that they consist of only one single configuration file - for simplicity; as we have no intention to update the configurations used in those samples at runtime.

Thus one may decide if he would like to keep the configuration in one, two or more files and deployment units - depending on his requirements. The elements in the root configuration and its static includes cannot be unloaded without shutting down or restarting the entire instance. Since transports are suggested to be defined in the root configuration (i.e. ultra-root.xml by default),  a change in a transport will require a complete re-start of the configuration - which will effectively shutdown and restart the UltraESB.

However, this restart does not need to be a cold restart - and could be triggered via UTerm or JMX; but it will cause system down time for changes to take effect. The root configuration is thus generally used to define the transports and the other more static aspects of the system - such as JMX connection configurations, cluster configuration, file caches and work managers etc.

Can elements of the root configuration be managed at runtime?

Yes, although completely reloading the root configuration will affect all services hosted on the instance, you can still manage most of the elements via JMX without causing downtime. For example, individual transports maybe stopped, paused, resumed etc without affecting other services that are not directly dependent on that transport. e.g. The http transports maybe shutdown and restartd, while file, JMS and email based services runs smoothly.

Using JMX for management

We fully believe that JMX is the way for management of a runtime instance, and thus have invested a lot of time to develop JMX support in the core itself. The built-in support uses newer MXBeans instead of MBeans. UTerm command line client is a JMX client that is able to interact with an UltraESB instance interactively or from within a script. The cluster management mechanism again uses the same JMX management beans to perform cluster wide operations.

Updates to the Configuration

Once the root configuration is loaded, one can load one or more deployment units that defines Proxy Services, Endpoints and Sequences along with any custom Spring beans. For example if one loads the default deployment unit at runtime, the proxy services, endpoints and sequences defined on it will become part of the running configuration. Similarly one can again specify a deployment unit by name (e.g. "default"), and ask it to be unloaded at runtime. Then all the elements that had been loaded from that deployment unit are stopped and removed. Its thus advisable that any dynamic related configuration elements are defined together in a single deployment unit - so that all of them can be loaded and unloaded together.

Managing dynamic elements with JMX / UTerm

No matter how Proxy Services, Sequences and Endpoints were deployed (i.e. via the root configuration or deployment units), they can be readily managed via JMX at runtime. Hence one could stop a running sequence, change its Java code,  or start it again without shutting down the server. Similarly, one may stop a Proxy service from serving clients. An endpoint maybe put into maintenance, or started, and a suspended Address made alive again, or a new address added to an existing endpoint altogether, via JMX and the web based console.

IDE driven development and UTerm driven management
We highly recommend to use your favorite IDE to develop proxy services, sequences etc and use UTerm for managing the production environment. Imagine whether you want to update a running proxy service configuration on production without testing etc? or use development environment to do it test it and deploy into production.

We also suggest that the conf directory containing the configuration be checked into a version control system or shared across within instances in a cluster via a shared mount, so that configurations can be easily managed across multiple nodes. Use of a version control system has the added advantage of rolling back a configuration anytime, and to allow a QA team to verify updates on a staging environment before being applied to production system, and to tag changes being deployed to a large cluster.

Creating an Updatable Configuration

Default Approach

If all your Proxy services, Endpoints and Sequences are developed and rolled out together, it would be easier to keep the configuration in just two files and the default deployment unit configuration.

Thus you will use the "conf/ultra-root.xml" to define the transports and other fairly static elements that are specific to the core UltraESB, and the "conf/ultra-custom.xml" to define custom beans and other customizations and Spring beans. You will then use the "conf/deployments/default/ultra-unit.xml" (default deployment unit configuration) to define Proxy Services, Endpoints, Sequences and any other custom Spring beans used by your services. To keep a large configuration in a manageable state, you may import other fragments from the "ultra-unit.xml" using the Spring "<import>" element. However, all these will be considered as parts of one single deployment unit (default in our case) which could be undeployed or redeployed. If you would like to be able to load another configuration - say a deployment unit named test1 separately, then you can include it as a separate deployment unit. If you are not familiar with the default configuration files conf/ultra-root.xml, conf/ultra-custom.xml and default deployment unit, please spend a few minutes to go through the documented defaults.

e.g. Assume you are using the default approach to define services to support reloadability. You could still use Spring "imports" from your ultra-unit.xml to import services defined in "internal-services.xml" and "external-services.xml" as shown in the snippet below within the default deployment unit. However, you cannot undeploy just the services of the "internal-servicex.xml" for example, as its statically imported from the ultra-unit.xml of the default deployment unit. In this example, the services are split into internal-services.xml and external-services.xml just to ease the development and management of the services - and not for hot deployment or update.

Root (Boot) Configuration

conf/
    ultra-root.xml
        - http-listener-8280
        - https-listener-8443
        - http-sender

Deployment Unit

conf/deployments/
    default/
        ultra-unit.xml
            - [SERVICE] authentication-service.xml
            --> Import internal-services.xml
                - [SERVICE] internal-service-1
                - [SERVICE] internal-service-2
            --> Import external-services.xml
                - [SERVICE] external-service-1
Approach for Hot Deployment

To support hot deployment, the above configuration maybe loaded as follows:

Root (Boot) Configuration

conf/
    ultra-root.xml
        - http-listener-8280
        - https-listener-8443
        - http-sender

Deployment Units

conf/deployments/
    default/
        ultra-unit.xml
            - [SERVICE] authentication-service.xml
    internal-services/
        ultra-unit.xml
            - [SERVICE] internal-service-1
            - [SERVICE] internal-service-2
    external-services/
        ultra-unit.xml
            - [SERVICE] external-service-1

When deployed as three separate deployment units, the deployment units "default", "internal-services", and "external-services" can be loaded, unloaded and reloaded independently of each other as desired at runtime. However, as usual the root configuration cannot be changed without a restart. With the above configuration, if internal-service-2 requires some changes, to its sequences and endpoints, one can unload the complete "internal-services" deployment unit (also unload and refresh internal-service-1 and 2 etc) and reload an updated configuration again from disk.

Refer to the UTerm documentation for resources on using the Runtime Configuration Management aspects and also connect via JMX (i.e. jconsole) to see the core management APIs that facilitates the run-time management behavior.

Technical Questions ?
You can log your technical questions at Stack Overflow
1. Login to Stack Overflow
2. Navigate to How to Ask page.
3. Search to see if a question relevant to your own has been asked.
4. If your search turned up nothing helpful or if it didn’t quite answer your question, we then suggest you ask a question yourself. Click on Proceed to navigate to Ask Question page.
5. Provide a descriptive title and describe the nature of your question. Please make sure to use the tag ultraesb when asking your question.

In this topic
In this topic
Contact Us