Murali Kaundinya

Subscribe to Murali Kaundinya: eMailAlertsEmail Alerts
Get Murali Kaundinya: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn

Related Topics: Java Developer Magazine

Java Developer : Article

Edge Computing with Java Edge Side Includes

An end-to-end architectural illustration

Content Delivery Networks (CDNs) have been used commercially to cache static content across a distributed network. Edge Side Includes is a W3C-acknowledged submission that supports the fragment assembly model. It provides the semantics on how to assemble dynamic content at the edge, when to cache content, when to expire content, etc. Java Edge Side Includes (JESI) provides extensions to Java that make it easy to program JSPs through a custom JSP tag library that will generate ESI markup. In this article we'll describe how to develop applications using JESI and show its impact on the end-to-end architecture.

A typical Web application may be browsed more often for its nontransactional static content than for its business transactions that require a trip to its back-end systems. In such a scenario it's cost-effective to serve some of the content on multiple low-cost edge servers and preserve the back-end compute and network resources for business operations that have transactional requirements.

Standard caching mechanisms, be it on the edge or near the enterprise, are designed to operate with minimal dependency on the back-end enterprise application. The caching entity caches a whole HTTP object and refreshes it based on its cache life properties specified through HTTP headers. This works well for "static" content that can be treated as indivisible objects. There is no mechanism, excluding a few proprietary ones, for applying caching to dynamic content. Edge Side Includes (ESI) was born out of the need for filling this void.

Edge Side Includes is a simple markup language that developers can use to identify content fragments for dynamic assembly at the network edge. ESI defines three main elements:

  • A markup language for delimiting content into fragments for deferred assembly
  • An extension of the traditional Web/caching architecture that assembles fragmented content
  • A way to invalidate the content at the edge
The ability to assemble dynamic pages from individual page fragments means that only noncacheable or expired fragments need to be fetched from the origin Web site, decreasing the need to retrieve complete pages and alleviating the load on the Web site's content-generation infrastructure.

Figure 1 shows a comparison of ESI before and after. Without ESI, client browsers from the Internet issue requests to access content from a particular site hosted in a data center. These requests funnel into the many Web and application servers. Every request that comes from client browsers gets serviced by both the Web and application servers and eventually database servers. With ESI, it's possible to offload the burden from the Web server and application server to "Edge Servers" deployed close to the consumers. The requests from client browsers get serviced by these edge servers, which serve cached content a lot faster. Every now and then, when the cached content expires, it results in a trip to the origin server to update the ESI fragment. With such architecture, the burden on the "Content Generation" infrastructure is drastically reduced.

Java Edge Side Includes
ESI is an XML-style specification for subdividing a page into component parts with individual cache-control properties. An HTML page from the enterprise (business) server could contain ESI tags to be processed by an Edge component termed ESI processor en route to the client. The ESI processor, as part of the content delivery network, could be embedded in a Web server or application server and use the ESI markup to control caching characteristics of page requests. Java Edge Side Includes (JESI) is the specification of ESI for Java and is a natural fit for JSP-based Web development.

JESI Architecture
JESI Architecture involves the configuration of a JESI tag library to the Web container, as shown in Figure 2. The JSP programmer develops JSP pages using JESI tags. These JESI tags get processed and result in HTML pages with embedded ESI tags. An ESI processor sitting between the client and the server, typically on the CDN, processes these ESI tags that indicate which of the page fragments need to be served from the ESI Processor's cache and which need to be fetched from the origin server. If the page is not in the ESI processor's cache, it sends a request to the origin server for the page. It stores it in its cache and sends an aggregated response to the user. If the page is in cache, the ESI processor evaluates the cache properties of the components of the page. This determines the list of cache components in the page that need to be refreshed. This may necessitate sending a request to the source to fetch the expired components. Finally, it processes the response, caches the refreshed component, assembles the page from the components, and sends it to the client.

Though JESI resembles "JSP include", the two have entirely different operational characteristics. A JESI include generates an ESI positional marker for ESI processors to construct the page. Construction of a page will involve hits to only those JESI include pages that have expired or are not in cache. Further, each JESI include page is fetched by a separate HTTP request. Hence, a JSP page should not assume that the HTTP request object passed to an include page will be the same as that passed to the containing JSP page. This should be bourne, especially when migrating an old Web page to JESI technology.

While Web designers can directly embed pages with ESI tags in JSP, JESI offers a better alternative for several reasons:

  • It's natural to express new markup using custom tags.
  • JESI is convenient to use as it internally generates verbose ESI markup.
  • ESI configuration options and deployment parameters can be naturally specified in application configuration files to be picked up by JESI.
  • Installation and maintenance is through the familiar tag library management process.
JESI comes as a JAR file containing the tag library and an associated Tag Library Definition (.tld) file. The application server can be enabled to use JESI merely by configuring the system with these files.

Before describing JESI tags, we must delineate two models of usage of JESI tags. There's a template/fragment model and a control/include model. It's important that JESI be flexible enough to be easily used with old Web pages and at the same time provide richer control for new Web page development. It's difficult to convert old Web pages into component Web pages to be "included" into the main composite Web page. The template/fragment model is used to convert old applications to JESI with relatively little effort. In this model a page is broken up into cacheable fragments, each fragment with its own cache properties, and the page outside of the fragments is marked up with the "template" tag. The "control/include" model is recommended for creating new Web pages. The Web page's cache control properties are provided under the "control" tag and other pages are included with the "include" tag. As with fragments, an included page has its own cache properties.

Listing 1 illustrates the syntax of some of the JESI tags. The JESI specification in the reference section provides comprehensive coverage of all the tags. <jesi:control> sets the caching characteristics of a page composed of "include" pages. It should be placed to surround the cacheable content of the page. The properties of the tag affect the content within the control tag but outside of the "include" tags. The properties of the tag in a page do not apply to the included pages. <jesi:include> is used to include cacheable resources identified by a URL. The JESI include tag, which is similar to a JSP include tag, is different in that JESI include tags are fetched by the ESI processor with separate HTTP requests.

The consequences of this provide a key to when it is appropriate to replace a JSP include with a JESI include. The include tag can be used in a template/fragment model as well. <jesi:template> tag, like the control tag, affects the HTTP headers only and does not generate HTML tags. The template tag is intended to be used with JESI fragments and controls cache characteristics of content in the page outside of fragments but within the template tag. In other words, the content outside the fragments but within the template tag is one cacheable object.

The main intent of the template tag is for the conversion of existing pages to the JESI model. In this model, the ESI processor's defaults will not apply to the page in the absence of a template tag. <jesi:fragment> tag is a cacheable object to be used in the template/fragment model to divide pages into individual cacheable components. Fragments have the same cache properties as template or control tags. Just like the template tag, a fragment has its own cache control and cannot inherit properties from the template or from the ESI processors. <jesi:codeblock> tag is used to conditionally execute code outside of fragments in the template/fragment model. The conditions specify if the code is to be executed when a template or a fragment is fetched by the ESI processor. <jesi:invalidate> allows the JSP programmer to invalidate cache objects. If a prefix is specified, the directive applies to all objects with the specified prefix. The username/ password attributes provide an authentication mechanism for logging into the cache server to execute the directive. Invalidate uses ESI's invalidation protocol, which is executed over HTTP. The optional "cookie" and "header" information can be used to determine what to invalidate. The <jesi:personalization> tag allows the ESI processor to set cookie values in responses, thus saving a trip to the origin Web server. If the cookie was found in the request header and has a non-null value, that value is used. If the cookie is not found in the header or the value is null, the value specified in the tag is used.

The source JSP processor processes the refresh requests from the ESI processor as follows (see Figure 3).

Request for a Template
The template content outside of the fragments is processed. Content in the codeblock tag whose execute property specifies "template" or "all" is processed. The JSP processor assembles the resulting content, inserts placeholder fragment tags at the specified location in the content, and sends the page to the ESI processor.

Request for a Fragment
First the JSP processor processes the template content outside of the fragment to initiate any side effects of the processing used in the fragment. All codeblock tags preceding the requested fragment whose execute property specifies "fragment" or "all" are processed followed by the fragment itself. The resultant page contains the processed fragment and placeholder tags for fragments not processed. The template content is discarded.

Request for an Include Page
This is a request to the origin Web/application server that generates the included page that follows the usual Web page service path.

JESI-ESI Example
Consider a "home" page of a company. It consists of a basic template that defines the presentation of most of the Web pages in the Web site. There is both static content, such as the company logo, banners, footers, etc., and dynamic content. There is an external business news section that changes several times a day, an overview section that changes once a week, a product outline section that changes once every 10 days, and a map to the rest of the Web site, which rarely changes. Content like business news that changes often is expensive to obtain and is well suited to be cached at the edge server. It's best to be modeled as a JESI fragment as part of a JESI template.

Also assume that a blood donation campaign is in progress and that the organizers want to display a bar chart showing their goal regarding the number of donors and the number of people signed up so far as part of all corporate pages. This information is stored in a special database table and is updated four times a day. The chart is a good candidate to be an additional JESI fragment. Therefore, you would add a JESI template tag at the top of the page and use JESI fragment tags to enclose the fragments that are to be cached as separate entities.

Assume that the URL to the corporate page is Figure 4 shows the JSP code snippet and the ESI-embedded response beginning with the header.

The ESI processor is alerted by the Surrogate-Control response header. Note the no-store directive, generated because of the cache="no" setting in the JESI template tag. The ESI processor makes two additional requests, where it fetches and caches the two fragments. After that, the composite page is returned to the employee. When the employee works with the page again, the dynamic content will be newly generated but the chart and the footer will be served from the cache.

Without JESI and ESI, you can at best cache static content on a surrogate (reverse proxy) and force the enterprise server to generate the dynamic content for each request without consideration of the dynamicity of the various parts. The only alternative would be to let the application be aware of the cache life of the various parts and cache internally, though this is hardly a recommended or practiced option as it makes both development and maintenance complex and error prone.

Using JESI and ESI, however, the page could naturally be broken down into component parts based on the life of each part and let the ESI processor orchestrate composition of the page to be served up.

Web content can be classified into static content, transactional noncacheable content, and content that has both. Efforts to reduce round-trip latency have been attempted from the advent of HTTP 1.1. These efforts have been to cache content either at the browser or at the various hopping points of the content's path. Caching should be transparent to the developer and if at all exposed should be at coarse granularity. JESI provides for fine-grain control and this can result in additional complexity if not architected carefully. Caching and JESI introduces an additional, orthogonal characteristic for page composition, namely the cache life of the components. Too small a cache time will defeat the purpose of ESI caching and too large a cache time has the danger of stale data (with more impact as some of the related content may have different cache characteristics). Web pages with dynamic content that necessitate fetching dynamic data from a back end may offset the benefits of caching.

In summary, JESI will be effective when effort is spent on optimally designing Web pages with careful consideration to the cache-life of the components. This will require careful thought as to content regeneration policies.


  • JESI - JSP Tag Library for Edge Side Includes (ESI):
  • IBM's WebSphere APIs for Edge Side Includes:
  • JESI Tags for Edge Side Includes:
  • Akamai ESI:
  • More Stories By Murali Kaundinya

    Murali Kaundinya is a Senior Enterprise Architect with Sun Software Services. At Sun, he helps customers with strategy for enterprise software architecture and delivers standards-based solutions.

    More Stories By Srinivasan Muralidharan

    Srinivasan Muralidharan is an advisory engineer at IBM in RTP, North Carolina. He works on host integration, emerging technologies.

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.