The delegate system enables the use of custom code to customize the image server's behavior. It can be utilized in one of two ways:
The delegate script is a file containing a delegate class written in Ruby. The class is instantiated per-request, early in the request cycle, and disposed of at the end of the request cycle. At various points in the request cycle, its methods are called by the application to obtain information needed to service the request.
Before any other methods are called, the application will set the request context, which is a hash of request properties with perhaps some other helpful information mixed in. See the documentation of the context attribute (attr_accessor :context
) in the sample delegate script file for information about the keys that may be present in the context hash.
You can also use a statement like context.each{ |k,v| puts "#{k}: #{v}" }
in any method to print the context to the console.
The delegate script is reloaded whenever the script file changes. Be aware, though, that code that has already been loaded into the JRuby runtime cannot be unloaded. For example, when a class is changed, the new version will replace the old version; but constants within the class cannot be redefined.
The delegate script is disabled by default. To enable it, follow these steps:
delegate_script.pathname
configuration option.delegate_script.enabled
to true
.In version 5.0, a new method named pre_authorize()
was added. In many cases, the authorize()
implementation can simply be moved into this new method, unless it contains logic that depends on information read from the underlying source image. See the sample delegate script, as well as the Access Control section, for more information.
In version 4.1, the authorized?()
and redirect()
methods were merged into authorize()
. See the documentation in the sample delegate script file for more information.
See the 4.0 user manual.
JRuby can use most Ruby gems, except those that have been built with native extensions. To import a gem, use a require
statement:
require
searches for gems based on the $GEM_PATH
environment variable, falling back to $GEM_HOME
if that is not defined. If JRuby fails to find your gem, check your $GEM_PATH
. If you installed the gem using gem install
, check the output of gem env
(particularly the "gem paths" section) to see where it might have been installed, and ensure that those locations are present in $GEM_PATH
.
This example uses URLConnection, which is part of the JDK, to execute an HTTP request, as an alternative to other examples which use Ruby's Net::HTTP library.
See also: CallingJavaFromJRuby
The whole JDK is at your fingertips, and there's nothing to stop you from using third-party JARs and accessing their API from JRuby. Be careful, though, as JARs may contain code that conflicts with the application's dependencies—different versions of the same library, for example.
Several delegate methods will be called over the course of a single request, and making them as efficient as possible will improve response times. A couple of ways to improve efficiency are:
Some methods may need to do similar work, which may be expensive. To avoid having to do it twice, a useful technique is to cache the first result. So, rather than doing this:
You could do this:
Most HTTP clients maintain an internal connection pool, but JDBC adapters do not. When accessing a database via JDBC, consider using a connection pool to improve performance. As of now, there is no "official" provision for this, but some options include:
Delegate methods may access a logger that writes to the application log:
Error stack traces may also be logged:
Delegate methods can be tested by creating an instance of the CustomDelegate
class, setting its context to be similar to what the application would set it to, and calling a method:
This script can then be run on the command line with a command like: ruby test.rb
.
The ruby command will normally invoke the standard ("MRI") Ruby interpreter, and not the JRuby interpreter. While they mostly work pretty similar, gems with platform-native extensions won't work in JRuby. Consider installing a standalone JRuby interpreter and test with that instead. (A tool like RVM can make it easy to switch between different Ruby environments.)
The Java delegate system was introduced in version 5.0. It relies on a delegate class that is very similar to the one used in the delegate script system, but instead is written in Java (or some other JVM language), compiled, and packed into a JAR file. Cantaloupe relies on the JDK's ServiceLoader system to auto-discover the delegate class and then instantiate and use it in the same way its Ruby counterpart is used.
Unlike the delegate script, a sample Java delegate is not bundled with the application. Instead, refer to the sample Java delegate, which provides a minimal working example.