Alternate service groups

Ronan edited this page Jun 26, 2013 · 11 revisions

in Umlaut 3.1 and following

This is a fairly new, somewhat experimental feature. Let us know if you run into any problems, or have any suggestions for improvements.

You have defined your Umlaut services in your ./config/umlaut_services.yml

By default, there's just one 'service group' in there, lableled with the key 'default'.

But you can optionally define multiple service groups, which can be activated or de-activated for any given request, letting you have different groups of services in play in different contexts.

By default, the service_group called 'default', as well as any other groups with key "default: true" will be activated.

# This group of services called 'default' is on by default
# because of it's name:
      type: SFX
# This group of services called 'group1' is on by default because
# it has "default: true" set. 
  default: true
      type: Something
      type: Other
# This group 'group2' is not activated by default
     type: Something

If you want different sets of services to apply to a given request, you can activate other groups, or turn default groups off, using a query parameter umlaut.service_group[]=group_name. Note that it is a Rails-style array param using square brackets; it is repeatable. In actual literal URLs, the square brackets need to be escaped as %5B%5D

You can add additional service_groups: &umlaut.service_group%5B%5D=group2 => Will run services in group2 for this request, not normally on by default, but turned on with the umlaut.service_group[] parameter.

You can turn off default service groups with a minus sign followed by the group name: &umlaut.service_group%5B%5D=-group1 => De-activates the group, ordinarily on by default.

And you can combine these: &umlaut.service_group%5B%5D=-default&umlaut.service_group%5B%5D=-group1&umlaut.service_group%5B%5D=group2. Turns off both the default groups, and turns on group2, so only services in group2 will be run for this request.

Umlaut request caching and umlaut.service_group

The umlaut.service_group parameter is taken account in Umlaut request caching. If a user requests /resolve?issn=12345678 and presses reload in their browser, they will generally see the already completed request again. However, if they request /resolve?issn=12345678&umlaut.service_group=something, the request will be re-run with the specified service_group parameter.

Permalinks and umlaut.service_group

The umlaut.service_group parameter is encoded in a permalink. If you make the request /resolve?issn=12345678&umlaut.service_group=foo, and receive for it the permalink http://umlaut.tld/go/873 -- requesting that permalink will redirect you to your complete original request, including the umlaut.service_group parameter.

Requesting a non-existing service group parameter

At the moment, if you issue a request for an umlaut.service_group=no_such_group value that does not exist in your umlaut_services.yml, umlaut will just silently ignore it. (Should it raise instead?)

Custom and implicit service_group lookup

The built-in feature supports explicitly specifying service groups in the URL.

However, you may want to calculate service_groups based on some other aspect of the request, such as IP address, or an app-specific logged in user's attributes. Or you may want to support URL query parameters that group different configuration-specified groups together in complicated ways.

It's a bit challenging to do this while maintaining proper functioning of umlaut's back-end caching and other functions. We have tested and recommend using a Rails before filter, to actually modify the params["umlaut.service_group"] value.

The easiest way to add a before_filter that will effect Umlaut's ResolveController, is to add it in your local ./app/umlaut_controller.rb. Here's an example that uses the ip_addr_range_set gem to add in a service_group called local only for coming from non-routable local IP addresses:

   # inside UmlautController
    prepend_before_filter :set_service_groups

    def set_service_groups
      if IPAddrRangeSet::LocalAddresses.include? request.remote_ip  
        params["umlaut.service_group"] ||= []
        params["umlaut.service_group"] << "exports" unless params["umlaut.service_group"].include? "exports"

When a service group is implicitly set like this, Umlaut will properly take account of this in it's back-end caching (if, say, someone's IP address changed such that set_service_groups made a different determination, and they re-loaded an Umlaut menu -- they'd get a refreshed umlaut page taking account of proper current services).

Umlaut will not encode such an implicitly set service group into a permalink -- if you have had the local service group added into your request, but then take the permalink and email it to someone else at a different IP address, Umlaut will still re-calculate for them.