conf/ ultra-root.xml - http-listener-8280 - https-listener-8443 - http-sender
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 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.
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.
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.
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.
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.
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
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 ? |