ORDS - Managing APEX static images

Submitted by jgraniec on
Blog article:

In today’s post, we’ll be talking about the possible ways to manage the static images/CSS/JS that come shipped with APEX, when running on ORDS. They are separate resources (not contained in the DB like some other APEX images) necessary for your APEX applications look and behave the way they’re intended to. If you and your users browse your internet using lynx (see image below) feel free to skip this one. Otherwise - dig in! 

 

The standard way

Normally, what you’d do is take the APEX images directory, pack them into a war and deploy the images in the /i/ context on the same app server that ORDS is deployed in (like it’s mentioned in the official installation guide. This is pretty straightforward and probably what will be sufficient for most. However, if you have multiple databases with APEX installed in them, possibly in different versions - this is where a problem arises.

Problem?

Well, the problem is that every APEX version has its version of the images. It may happen that from one version to the other some file are removed, some are added, a piece of JavaScript is changed, so as a result, you see some missing pictures, misaligned elements or just get served with a plaintext version of your site.

So we have to provide different versions of the images for APEX to choose from. How should we do it and how do we tell APEX which one to choose?

The multi-database way - using aliases

Let’s say you have 3 databases - db1, db2 and db3. Db1 and db2 running APEX 18.2  and db3 running APEX 19.2.

In your application server include 2 folders with APEX images -  apex_images1820 and apex_images1920. Then create 3 links - i_db1 and i_db2 pointing to apex_images1820 and i_db3 pointing to apex_images1920.

Then, for each of your APEX applications, you have to set the expected images’ context using the reset_images_prefix.sql script shipped with APEX.

SQL> @<apex directory>\utilities\reset_image_prefix.sql
Enter the Application Express image prefix [/i/] /i_db1/

For db1 we set it to i_db1, db2 -> i_db2, db3 -> i_db3.

This way during APEX upgrade the DBAs take care of upgrading the APEX version in the database and all has to be done is to change the link in the application server. So let’s assume we’re upgrading db1. Simply change i_db1 to link to point to apex_images1920 and you’re done.

The multi-database way with the help of your friendly neighborhood DBA

Another approach to this is to leave all the work to the DBA - instead of setting up those aliases, just deploy the images folders - apex_images1820 and apex_images1920 in our case. Then with each upgrade remember to launch the reset_image_prefix scripts and point to the right context. This may sound simpler, but one thing has to be kept in mind, to cite Joel Kallman from Oracle:

“You should not do this on a live system, as this process will invalidate many objects in the APEX schema and they will need to be recompiled. Again - don't do this on a live system.”.

On the other hand, you’re upgrading your APEX schema anyway, so that shouldn’t be a that big of a problem.

Using a static file server

What if you have multiple application servers running ORDS (either to provide high availability or to serve different environments) and don’t want to store a multiplicity of the APEX static files? Thankfully you can point APEX to use an outside URL for requesting the files. Actually, even Oracle started providing these resources in CDN.  You can either use the URLs provided by Oracle or, if you’d rather rely on your own infrastructure, create a static file server on your own - just be sure to include the

Access-Control-Allow-Origin: “*”

header to the responses, otherwise the browser will complain about CORS issues.

For example if you're running Apache HTTP Server, this small snippet may come in handy:

            Header append Access-Control-Allow-Origin * 
            Header merge Vary "Origin"

Use the same command as before to set the URL as image prefix. Like before, you have to take care of changing the prefix when upgrading.

Using the query parameter? Unfortunately not an option

One interesting thing that can be observed about the request made for the resource is a query parameter indicating a version, e.g.:

GET /i/libraries/apex/minified/chartBundle.min.js?v=18.2.0.00.12

if a request is made on behalf of APEX 18.2. This looks very promising - we could envision a simple mod_rewrite  or Tomcat’s adaptation to request the appropriate version of the resources automagically. Until it doesn’t - unfortunately some resources are requested without passing this parameter, for example:

GET /i/app_ui/font/apex-5-icon-font.woff2

If this one piece of the puzzle wasn’t missing, we would have a maintenance-free way of managing the APEX images - every APEX version would be directed to its corresponding resources.

Add new comment

CAPTCHA
Enter the characters shown in the image.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

Disclaimer

The views expressed in this blog are those of the authors and cannot be regarded as representing CERN’s official position.

CERN Social Media Guidelines

 

Blogroll