Skip to content

Configuration

Simon Oakes edited this page Feb 14, 2019 · 37 revisions

Contents

Directory layout

All configuration and template information for the registry is stored (by default) in the directory /opt/ldregistry.

Runtime information such as the internal triple store and record of uploaded files are in /var/opt/ldregistry.

Logging information is in /var/log. Most logging information recorded as part of the web app container and so appears in /var/log/tomcat7/catalina.out. There is a separate log file for the velocity template engine which appears in /var/log/ldregistry-velocity.log.

Note that this is a change from the proof-of-concept implementation which used /var/local/registry for everything. That does not follow linux file system layout conventions. Arguably the configuation information should be accessible in /etc/ldregistry, a deployment could use symbolic links to achive this. The use of ldregistry rather than registry is a prefix is to disambiguate against other registry-like software.

When a registry instance first starts up then each area of the configuration directory will be initialized if it does not exist. The only exception to this is that, for technical reasons with the Tomcat context definition, an empty ui/ directory should exist for successful start-up.

The default layout of /opt/ldregistry is summarized below:

Directory or file Purpose
boot/ Definitions of bootstrap registers used when starting a registry with no data.
boot/system The bootstrap definition of the system registers.
config/ Configuration and initialization files.
config/root-register.ttl RDF file describing the root register, used during bootstrapping only.
config/app.conf Configuration parameters for the software, defines the set of components that make up the registry and provides configuration parameters for them.
config/user.ini Initialization for the security database, provides OpenIDs and grant information for initial users. Not consulted once the userstore database exists.
config/oauth.conf Configuration of OpenID Connect provider
proxy-conf.sh Script used to trigger the nginx proxy to reconsult configuration information, should be set to be sudo executable by the tomcat user.
templates/ Set of templates defining the built in UI, written in Apache Velocity.
ui/ Resources (CSS, image and javascript files) which should be served from the /ui path of the registry URL.

The default layout of /var/opt/ldregistry is summarized below:

Directory or file Purpose
index/ Lucene free text index for the registry content.
logstore/ File copies of all uploaded registration and update payloads.
store/ The RDF data store (an Apache Jena TDB instance).
userstore/ Database holding security information (registrations and grants), an embedded instance of Apache Derby.
proxy-registry.conf Proxy configuration script generated by the registry. Other scripts with the naming pattern proxy-*.conf may be added here to support additional manual proxy rules.

Security configuration

Once the registry is running all security information is held in the database in the userstore directory. Configuration of user permissions is then done through the user interface.

If no userstore database exists then it will be initialized by loading the initial user information from config/user.ini. If no such configuration file exists then a null one will be created.

To set up an administrator for a new installation then the bootstrap userstore should be removed and the bootstrap config/user.ini should be edited to define the administrator.

The user.ini file comprises a set of declarations, one per line (lines beginning with # are comment lines).

User registration entries start with the user keyword and take the form:

user  id  "name" 

For example:

user https://me.yahoo.com/a/rb93y8N72dK9HoXHwgNqBKlikg-- "Alice"

Each OpenID or OpenID Connect provider has a different means of obtaining a user-specific OpenID. For example Yahoo! allows creation of an OpenID through http://openid.yahoo.com/ from which a user can determine (or create) an OpenID identity. A variant on this declaration is to specify a password for the user as a final entry on the user line:

user [email protected] "Dave" foobar

In this case the user identity can be any sufficiently unique string, such as an email address, and need not be an OpenID URL (though it can be). N.B. This password in clear text and so should be used for bootstrap only and changed as part of system commissioning.

There is a built in anonymous user with pseudo OpenID of http://localhost/anon. It is convenient to declare that user in the initialization file as well, so as to bind a visible name to that id. For example:

user http://localhost/anon "Any authenticated"

The second type of declaration line is used to grant permissions to a user. These take the form:

openid permission

For example:

https://myopenid      Update:/register/item
https://myotheropenid GrantAdmin

In particular the GrantAdmin permission makes the user an administrator.

Thus a minimal user.ini configuration looks something like:

user https://profiles.google.com/1147194443288764760228 "Alice" changeme
user http://localhost/anon "Any authenticated"
https://profiles.google.com/1147194443288764760228 GrantAdmin

OAuth Configuration

To use the OpenID Connect protocol for user authentication, the registry instance must be configured with app-wide OAuth settings, and must specify at least one OAuth provider. Note that you must set the config.passwordLoginOnly property to false in your app.conf to enable this feature.

App-wide settings should be configured in /opt/ldregistry/config/oauth2/oauth.conf. This includes the following properties:

Name Meaning Type Default
ldregistry.usehttps Toggle to force redirection to https for requests after successful authentication and back to https after logout when https is not being used by default. Boolean false
ldregistry.providers Comma separated list of names of OAuth providers with which users will be able to authenticate. Names should correspond to the name specified in the provider configuration. String

Provider settings should be configured in .properties files contained in the opt/ldregistry/config/oauth2/provider directory. You can specify any number of providers, but only those listed by the app-wide ldregistry.providers property will be enabled. Each file corresponds to one provider, and includes the following properties:

Name Meaning Type Default
name The uniquely identifying name for the provider. This should correspond to the values of the ldregistry.providers specified by the app-wide configuration. String
label The user friendly display name for the provider. String name
client.id The unique key that identifies the registry instance with the provider. String
client.secret The secret value which authenticates the registry instance with the provider. String
auth.endpoint The full URI of the authorization endpoint exposed by the provider. String
auth.scope The OpenID scope which defines what user information will be accessed. The default should not be overridden as long as the provider supports standard OpenID scopes. String openid email
token.endpoint The full URI of the access token endpoint exposed by the provider. String
userInfo.endpoint The full URI of the user info endpoint exposed by the provider. String
userInfo.key The name of the property, on the deserialized user info response, whose value is the unique ID of the authenticated user (this should usually be their OpenID identity). String
userInfo.name The name of the property, on the deserialized user info response, whose value is the user friendly display name for the authenticated user. String userInfo.key

The documentation for your specific provider's OAuth2 and OpenID Connect APIs should help you to configure these properties. If you choose to use an OAuth provider which does not support OpenID, make sure that the userInfo.key value is sufficiently unique, and be aware of the privacy implications of storing personal information such as email addresses as unique IDs.

Example

To use Google OAuth and identities provided by Google Plus then the steps are:

  1. Open https://console.developers.google.com
  2. Create a "project"
  3. Select APIs and Auth and enable the "Google+" API.
  4. Configure the "consent screen", which determines what users will be told about the registry application when granting permission to use their identity
  5. Under credentials use Create new Client ID. Select Web Application and provide the URIs which your registry instance will be based at (including localhost in these can be useful for development purposes). For the redirect URIs then append /system/security/responseoa to the base URI for your instance, for example http://location.data.gov.uk/registry/system/security/responseoa
  6. Copy the generated client id and client secret to a google.properties file under the oauth2/providers directory (the file name doesn't matter as long as the extension is properties).

An example Google+ Credentials configuration:

Client ID for web application

Client ID            ...
Email address        ...
Client secret        ...

Redirect URIs        http://localhost:8080/registry/system/security/responseoa
                     http://environment.data.gov.uk/registry/system/security/responseoa

Javascript Origins   http://localhost
                     http://localhost:8080
                     http://environment.data.gov.uk

An example Google+ provider configuration file:

name           = googleplus
label          = Google+
client.id      = ## your Client ID
client.secret  = ## your Client Secret
auth.endpoint  = https://accounts.google.com/o/oauth2/auth
token.endpoint = https://accounts.google.com/o/oauth2/token
userInfo.endpoint   = https://www.googleapis.com/oauth2/v3/userinfo
userInfo.key   = profile
userInfo.name  = name

An example app-wide configuration file:

ldregistry.usehttps = true
ldregistry.providers = googleplus

Note that users may only use Google to authenticate if their account has enabled Google+.

Example

An example GitHub provider configuration file:

name           = github
label          = GitHub
client.id      = ## your client id
client.secret  = ## your client secret
auth.endpoint  = https://github.com/login/oauth/authorize
token.endpoint = https://github.com/login/oauth/access_token
userInfo.endpoint   = https://api.github.com/user
userInfo.key   = url
userInfo.name  = login

Bootstrap registers

When a registry instance runs for the first time it needs to create an initial RDF description. There are two parts to this bootstrapping - the root register and all other registers (including the system registers and manager-supplied initial data).

Root register

The root register is a special case because of its different naming convention and because there is no register into which to add it. The root register is bootstrapped by loading an initial RDF file (/config/root-register.ttl) which must contain both the reg:Register declaration and an associated reg:RegisterItem. Each of these must meet minimum constraints for the versioning model (have an owl:versionInfo value and a version:currentVersion link, which can point to itself). The URI of the root register must match the declared base URI for the registry installation (see below).

System and other initial registers

Once the root register is in place then the normal API mechanisms for loading register declarations and registered items can function. In particular use of "relative" addresses is then possible so any such bootstrap files can be independent of the registry base URI.

The additional initial registers are loaded from the area boot/. Each directory in the boot area corresponds to a register and should contain a metadata.ttl defining it. It may also contain sub-directories for sub-registers and other *.ttl files defining items to be included in the register.

Initialization

When a registry first starts up, if the bootstrap files for either of these kinds of register do not exist then a default minimum set will be created. Then if the RDF data store does not exist (store/ and the associated free index in index/) then one will be created and initialized from the bootstrap files.

Thus if you start a blank registry installation that will create both a minimal set of bootstrap files and an initialized store. Normally you will then need to halt the registry, edit the bootstrap files to suit the deployment requirements and delete the initial store/ and index/ areas. Restarting the registry will then rebuild the store based on your customized bootstrap.

Base URI

The registry will create and serve all data relative to an assumed base URI. This needed not be the same as the URL at which the registry installation is hosted - either because this is a staging deployment or because some external proxy will map requests from the real URI to the hosting system.

The base URI can only be set at the time that a registry instance initially starts up. Once the initial store has been created all data in that store will hold absolute URIs which are based on the configured base URI.

There are two places where the base URI must be configured.

Firstly, the registry software itself is configured from the file config/app.conf, see below. In that file change the following line to give a suitable base URI:

registry.baseURI     = http://ukgovld-registry.dnsalias.net/

Secondly, the initial bootstrap RDF for the root register must be consistent with this. This is defined in config/root-register.ttl (see above).

General configuration

The registry software itself is configured through a single file config/app.conf. The file is used to configure a series of software components which together make up the registry. It is possible to provide alternative implementations of some of these components and configure them through this file. The configuration is a series of blocks, one for each component, which take the form:

component       = qualified.name.of.class
component.prop1 = value1
...
component.propN = valueN

In most cases the name of the component is arbitrary. The value may be a string, a long integer, a comma separated array of values or a reference to an earlier component (using the syntax $componentname).

The parameter string {webapp} can be used in configuration values and will be expanded with the location of the running registry application.

In normal use very few of these parameters should need customization, so we will only summarize the key ones.

Note. Prior to release 0.1.1 configuration was through config/services.conf and there are some syntax changes between the two files. These include use of $ for cross referencing components, use of {webapp} instead fo ${webwapp} to reference to files within the war and some differences in the specific java components used. In most cases porting from a prior release to the current release will simply mean taking the sample from src/main/webapp/WEB-INF/app.conf, customising the registry.baseURI setting and deploying this to /opt/ldregistry/config/app.conf.

registry

The registry service itself.

Key property Meaning
baseURI The base URI at which the registry is assumed to operate.
pageSize The number of items that should be returned by list views of collections (i.e. registers).
log Area used for recording registration/update payloads.
bootSpec A sequence of possible locations for the bootstrap root register, tried in order.
systemBoot The location of the boot areas for loading system and other registers.
store, forwarder, userStore References to the other required components
backupDir Directory where snapshot backups of the repository dataset will be saved
configExtensions Optional reference to a set of general configuration options used to customize UI behaviour

velocity

The template rendering system used the generate the default UI.

Key property Meaning
production If true then run in production mode where macros cannot be updated and templates, once cached in memory, are assumed not to change. If false then any change to a template will be detected and cause a change to the UI.
templates Directory where the template files are located.

basestore

The RDF data store for the registry.

Key property Meaning
location The directory where the RDF database is held.
textIndex Comma-separated list of predicates to include in the text index, can use prefixes from the default prefix set (rdf, rdfs, owl, xsd, dct, foaf, skos, ldp, void, prov, time, reg).
timeout A global timeout for queries to the store. Set to "first,all" where first is the time until first result and all is the total query time allowed, both in ms. Should be set high enough to allow normal operation but can be useful to block roque ad hoc query requests.

index

The (Lucene) free text index.

Key property Meaning
location The directory where the text index is held.

forwarder

Component used to manage forwarding/proxy configurations. This will handle redirects itself and will implement any proxy forwarding by dynamically configuring a separate nginx instance.

Key property Meaning
proxyConfDir Directory where nginx proxy scripts will be written.
proxyRestartScript Shell script which will be used to cause nginx to reconsult the configuration scripts.

General Config

This is a table containing abitrary key/value pairs, typically used to control external UI behaviour. It is possible to extend UI behaviour (though modification of the UI Velocity templates) and control those extensions by additions to this block. Additional configuration options can be added here without any change in the registry-core.war, they are simply passed through to the Velocity engine. The options supported by the current templates in registry-config-base are:

Property Meaning
suppressPasswordLogin If set to true this removes the option to login or register through a password, leaving only the option to register via OAuth/OpenID. See the documentation for how to configure OAuth support. If set to true this also enables an admin menu item to generate temporary API passwords.
suppressLinkView By default the item display shows two columns of information - item property/values and cross-item links. If this config property is set to true the links column is suppressed and the property/value table spans the whole display area.
showRegisterAsDatatable If set to true then the display of register contents is rendered using a client-side datatable component that supports paging, search and reordering. Since this is purely client-side so to be effective the pageSize property of the registry should be set large enough that most registers will fit within one page
registryName Provides a name for the registry that will be used in page titles. This avoids having to adapt the main.vm and header.vm templates when implementing a new registry instance.

Logging

Logging of accesses to the registry is done by the nginx front end proxy. See the nginx configuration documentation.

In addition all requests that reach the registry itself will be logged. For requests from authenticated users the user name and their OpenID will be included, for other requests the originating IP address is (should be, when that's fixed!) recorded. This log will also include messages from internal software components. The registry logging is configured by log4j.properties within the registry application itself. Currently this will log to file (log/registry.log) and to standard output (which means it will be captured by the velocity logging).

UI templates

The html styling for an registry pages requested in text/html format is handling by the velocity templating system. The builtin registry UI is implemented using these templates. The templates are all stored in the templates/ directory within the operating area. As usual, if this area does not exist at registry start up time then one will be created containing the default templates.

The key templates for customization are:

Template Use
main.vm The entry point, the registry will invoke main.vm in response to any request to a registry resource in text/html format.
header.vm Included in all top level templates to provide the HTML header information including page title and loading of style sheets.
navbar.vm Included in all top level templates to render the top level navigation bar.
footer.vm Included in all top level templates to provide the running foot, load all required javascript libraries and close the HTML page.
root.vm Called by the main.vm to render the home page of the registry (root register).

In addition to the calls of main.vm from the registry itself, requests to the /ui area of the registry are handled specially. They can either directly invoke a UI template or are served as files to provide the style sheets, images and javascript libraries needed for the UI.

Request URI Action
/ui/template If a template called template.vm exists then it will be used to render the response, examples include about.vm and login.vm.
/ui/* All other requests fall through to the underlying Tomcat engine, which in turn serves these files from the ui/ directory in the operating area.

Configuring the document base from which Tomcat will serve the plain UI files is currently done by setting an alias in a META-INF/context.xml file in the web app itself. The configuration of aliases is Tomcat specific so that switching to a different application server would require some minor modifications to the web app.

Template bindings

When a velocity template is invoked the following environment variables will be bound

Variable Bound to Instance of
$uri The relative path of the resource being requested String
$registry The Registry object, access configuration info and invoke API operations from here com.epimorphics.registry.core.Registry
$subject The security subject, can test if the user is authenticated and check permissions org.apache.shiro.subject.Subject
$requestor Name of the person making the current request String
$request The incoming HTTP request javax.servlet.http.HttpServletRequest
$language The language code for the user's locale String