Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/
Table of
Contents...
Hide

Project Zero Developer’s Guide

Concepts and components
Basic concepts overview
Event processing
Writing Java handlers
Writing Groovy handlers
Firing events
Global Context
Global Context reference
Application directory layout
Virtualized directories
Assemble
PHP
Features and configuration
Configuration
Debugging
Dependencies
Packaging
Application classpath
Logging and tracing
RESTful resources
RESTful documentation
File serving
Response rendering
Validators and validation
HTTP error handling
Calling a remote resource
Using the Connection API
Sending an email using EmailConnection
Configuring destinations
Configuring protocols
Configuring connection handlers
Creating a connection handler
Creating a custom protocol transport
Simple logging connection handlers
Protocol reference
Client programming with Dojo
Runtime options
Deployment modifications
HTTP configuration
SSL configuration
Proxy configuration
Extending the CLI
Security considerations
Authentication
OpenID authentication
Extending security
Security tokens
CSRF prevention support
Extending token support
Leveraging TAI
User service
File based user service
LDAP user service
Extending user service
Security Utilities
Leveraging XOREncoder
Extensions
Atom support
RSS support
JSON support
XMLEncoder
REST to SOAP extension
URIUtils
Developer Web tools
Database setup tools
Configuring data access
Common query patterns
Advanced query patterns
Update patterns
Local database transactions
Extending data access
Configuration vendor differences
PHP data access
Resource model
Configuring ZRM
Resource model declaration
Programmatic model API
HTTP REST API
A ZRM mini tutorial
Active content filtering support
Default filters
Custom filters
Runtime management
Management commands
Zero socket opener
Other extension modules
Amazon E-commerce service
Flickr service
WeatherZero forecast service
Wikipedia service
Reference
Zero command line interface
JavaDoc - Public API
JavaDoc - Public SPI
JavaDoc - All Classes

 

Configuration

Properties and behavior of a Project Zero application may be specified in configuration files.

Zero configuration file: zero.config

The configuration of a Zero application is set in the config zone of the Global Context. Values are set into the config zone via configuration files. Configuration files for the application and its dependencies are processed at application startup.

Configuration files are effectively "scripts" that set and append values into the config zone. The syntax is based upon a simple grammar of GC URIs and JSON data structures.

While processing configuration files, entries in the config zone are handled with a "first one wins" strategy:

  • Values may be set once (subsequent attempts to set a value at an existent GC URI are denied)
  • Values may be appended to arrays
  • Key/value pairs may be appended to objects, provided that the key is not already set in that object

After processing the configuration files, the config zone should be considered read only. (Although the values could be changed by application code, not all changes affect the running application. For example, the application must be restarted for changes in /config/http/port to take affect.)

For example:

Example zero.config file

# Value set
/config/http/port = 8080

# List set
/config/resources/defaultExtensions = [".groovy"]

# List append
/config/bindings/.groovy += ["zero.core.groovysupport.bindings.DefaultBindings"]

# Map set
/config/test/map = { "a" : "b", "c" : "d" }

# Map append
/config/test/mapappend += { "a" : "b", "c" : "d" }
/config/test/mapappend += { "x" : "y", "w" : "z" }

# Event handler
/config/handlers += [{
  "events" : "GET",
  "handler" : "custom.Handler.class"
}]

# Value reference (insert value read at config-load time)
/config/property/myPrefix = "/foo/bar"
/config/test/value = "${/config/property/myPrefix}/bat"

# Variable set/value reference
myPrefix = "/foo/bar"
/config/test/value = "${myPrefix}/bat"

# Include
@include "${/config/dependencies/zero.core}/config/security/form.config"
{ "formLoginPage" : "/login" }

Config syntax

Syntax Description Example
GC_URI = JSON_value Set a value at GC URI
See zput for details
/config/http/port = 8080
GC_URI += JSON_value Set/append a value at GC URI
See zpost for details
/config/bindings/.groovy += ["zero.core.groovysupport.bindings.DefaultBindings"]
variable = JSON_value Variable set myPrefix = "/foo/bar"
${GC_URI} GC value reference
Value is read at configuration-load time
/config/longname = "Application:  ${/config/name}"
${variable} Variable value reference /config/contextRoot = ${myPrefix}
@include JSON_string [JSON_object] Process another configuration file, with optional variables specified as a JSON_object @include "${/config/dependencies/zero.core}/config/security/form.config"
{ "formLoginPage" : "/login" }
# comment Comments # This is a comment

JSON_value could be any of the valid JSON types: object, array, string, number, true, false, and null.

GC_URI is of the form /<zone>/<path>.

variable consists of alphanumeric characters (a-z, A-Z, 0-9) and underscore.

Value references (variable and GC) may be used anywhere a JSON object is expected (e.g. /config/contextRoot = ${myPrefix}). Value references that refer to string types may be embedded within a JSON string (e.g. /config/longname = "Application:  ${/config/name}").

Resolved dependency locations

Root directories of resolved dependencies are available as Global Context value references. The location is ${/config/dependencies/moduleName}, where the module name of the dependency matches the name specified in the corresponding ivy.xml files (e.g. zero.core).


HELP Advanced You can obtain the root directory for each dependency from the Global Context as follows:

List<String> listOfDependencies = zget("/config/dependencies");
for (String dependency : listOfDependencies) {
    String dependencyRoot = zget("/config/dependencies/" + dependency);
     // Operate on the dependencyRoot (e.g. load files)
}

Include

Example @include "${/config/dependencies/zero.core}/config/security/form.config"

Zero processes includeFile as a configuration file. includeFile may be an absolute or relative file reference. Relative references are relative to the including file. Included files are now virtualized, so the above could be rewritten as

Example @include "security/form.config"

This would resolve to form.config in the config/security sub-directory of a dependent project.

Optional arguments can be passed as a JSON_Object.

@include "${/config/dependencies/zero.core}/config/security/form.config"
{ "formLoginPage" : "/login" }

Configuration properties set within includeFile are scoped to that file and any files included by it. Properties are immutable within their scope, so "first one wins."

Comments

Lines that begin with a hash (#) are comments.

Storage formats

The following table describes how JSON types from configuration files are stored in the GC:

JSON type Stored in the GC as a Java instance of ...
JSON object Map<String, Object>
JSON array List
string String ('$' is reserved; literal value escaped as '$$')
number long or double
true true
false false
null null

Event-handler registration

HELP Note to M1/M2/M3 users: The Event handler registration has been changed in M4. Please update your configuration files to conform to the syntax below to allow applications to start up. For a summary of the changes in Event handler registration, refer to the Event handler registration changes article.

Event handlers are registered via configuration files. The complete syntax has the following form:

/config/handlers += [{
  "events" : JSON_string or JSON_array(JSON_string),
  "handler" : JSON_string,
  "conditions" : JSON_string,
  "instanceData" : JSON_object
}]

where

  • events is the name (or list of names) of the events handled by this handler
  • handler is the name of the handler, including a suffix that must match a registered Interpreter type. The default list of registered types is:
    • .class for Java (the value is the fully-qualified class name with a ".class" suffix, e.g. "your.pkg.Handler.class")
    • .groovy for Groovy scripts (searched in app/scripts; use slashes for path delimiters, e.g. "foo/bar/handler.groovy")
    • .gt for Groovy templates (searched in app/views; use slashes for path delimiters, e.g. "foo/bar/handler.gt")
    • .php for PHP scripts (searched in app/scripts; use slashes for path delimiter, eg "foo/bar/handler.php")
  • conditions is optional. The value of the conditions, computed at run time. If not specified, then the handler is always a match for the corresponding event.
  • instanceData is optional. This data is provided to the handler in the event zone.

Condition operators

Global Context URI
true only if the Global Context contains the specified key.
Example: "conditions" : "/request/status"

==
Selector pattern match. Named groups are specified as {name}; matches may be qualified, such as {name:any}. Values of named groups are set into the event zone for the handler.
Example: "/request/path == /foo/bar/{next}]; the value of next is available to the invoked handler in the Global Context at /event/next contains value.

Qualifiers:

any
Matches to the end.
Example: If /request/path == /a/b/c, then "/request/path == /a/{remainder:any}" evaluates to true and the handler will be invoked with /event/matchedURI == /a and /event/remainder == b/c.

The pipe character | will also match to the end of the URI and, additionally, set /event/pathInfo.
Example: If /request/path == /a/b/c, then "/request/path == /a|" evaluates to true and the handler will be invoked with /event/matchedURI == /a and /event/pathInfo == /b/c.

Note: | is only valid as the last character in the selector pattern or last except for right brackets. For example, "/request/path == /a/b|" and "/request/path == /a[/b|]" are valid; "/request/path == /a|/b" is not.

element
Matches to the next slash.

digit
Matches one or more digits: [0-9].

word
Matches one or more word characters: [a-zA-Z_0-9].

=~
Regex pattern match, based upon the regular expression support in the JDK.
Example: "/request/path =~ /foo/.*"
Example: "/event/resolvingEvent =~ (GET|POST|DELETE|PUT)"

!
Negates the condition value; placed before the operator it modifies.
Example: "!(/request/status)"

!=
Not URI matches
Example: "/request/path != /a/b"

!~
Not matches
Example: "/event/resolvingEvent !~ (GET|POST)"

&&
Logical AND
Example: "(/request/path != /a/b) && (/event/resolvingEvent !~ (GET|POST))"

||
Logical OR Example: "(/request/path == /a/b) || (/event/resolvingEvent =~ (GET|POST))"

Configuration templates

A combination of @include and configuration properties can be used to build configuration templates.

For example, security support in zero.core uses configuration templates.

Configuration template example: config/security/rule.config

authType=""
users=[]
groups=[]
roles=[]
requireSSL=false
csrfProtect=true


@include "requireSSL.config"{
   "conditions": ${conditions},
   "requireSSL": ${requireSSL}
}

csrfProtect=${csrfProtect}

/config/handlers += [{
   "events" : "secure",
   "handler" : "zero.core.security.SecurityHandler.class",
   "conditions": ${conditions},
   "instanceData" : {
                  "authType" : ${authType},
                  "groups" : ${groups},
                  "users" : ${users},
                  "roles" : ${roles},
                  "csrfProtect" : ${csrfProtect}
               }
}
]

/config/handlers += [{
   "events" : "retrieveCredentials",
   "handler" : "zero.core.security.${authType}UserInfoResolver.class",
   "conditions": ${conditions}
}]

/config/handlers += [{
   "events" : "authorize",
   "handler" : "zero.core.security.authorization.AuthorizationHandler.class",
   "conditions": ${conditions}
}]

Using a configuration template

@include "security/rule.config"{
   "conditions" : "(/request/path =~ /formauth/getonly(/.*)?) && (/request/method == GET)",
   "authType" : "Form",
   "groups" : ["ALL_AUTHENTICATED_USERS"]
}

Type-handler registration

Type handlers are registered via configuration files or programmatically. Each new type handler is registered by appending it to the list. For example:

/config/typeHandlers += {
   "zero.core.context.types.commands.Command" : "zero.core.context.types.CommandTypeHandler"
}

Order of processing

Zero enforces a "first one wins" strategy with configuration processing to ensure consistency throughout the application. As a result, you might need to understand the order in which configuration files are processed in cases involving overwrites.

By default, Zero first processes <apphome>/config/zero.config, then processes config/zero.config for each dependency. The order in which dependencies are processed is described in the Virtualized directories documentation. Although the config directory is not a virtualized directory, the order of processing configuration files is identical to the search order through dependencies within a virtualized directory.

Pre- and post-configuration files

Deployers may want to override application configuration settings without modifying any of the application files. This can be accomplished with pre- and post-configuration files. (Pre- and post- refer to the main configuration processing step: pre- happens before the main configuration processing; post- occurs after.)

In Eclipse, you specify an alternate configuration file by modifying the Run profile for that Zero application to set the Program Arguments to: [-pre <preConfigFile>] [-post <postConfigFile>] <applicationRootDirectory>

From the command line:

zero run [-args "-pre <preConfigFile>"]

<configFile> may be an absolute or relative file reference. Relative file references are relative to the current working directory.

r33 - 05 Feb 2008 - 08:16:59 - steveims
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site