|
|
|
Global Context
The Global Context, as the name implies, provides a central construct for applications to store and retrieve environment information. Scripts in Project Zero run in the context of an HTTP request, the request zone therefore provides access to the HTTP request data. All the information the application has been configured with (including port numbers, directory locations and dependencies) is provided through the config zone. APIs for the Global Context are available for Java, Groovy and PHP. See the Global Context reference for a list of the attributes available, by default, in the Global Context. The following sections of this article provide information about Global Context and the APIs:
Note to M1 users: If you have been using the M1 build of Project Zero or the daily builds prior to the M2 build, the Global Context has changed. See the migration and other information about this change, provided in the Global Context changes for M2 article.
The Zones
Project Zero provides a default set of zone handlers for applications. Each zone handler provides different lifetime and scope behavior. The Global Gontext can be extended with additional zone handlers as described in the Extending the global context section.
Config zone
Data in the /config zone is generally loaded from configuration files. This data is globally visible and is available for the lifetime of the application.
App zone
Data in the app zone is globally visible and is available for the lifetime of the application.
Request zone
Data in the request zone is visible to the thread that is processing the HTTP request and is available for the duration
of request processing (until the response is sent back to the client).
User zone
Data in the user zone is visible to all threads that are processing requests belonging to the same HTTP session (determined by the zsessionid cookie).
At this time, the default user zone is based upon in-memory persistence. Data is available until the application is restarted.
Event zone
Data in the event zone is visible to the thread on which a handler was dispatched. Data is available for the duration
of the event handler procedure call. Changes made to the event zone by one handler are not visible to other
handlers of the same event.
Accessing the Global Context
The Global Context is available from all parts of a Zero application. How you access the Global Context varies depending on the language of the artifact.
Global Context APIs
Values in the GC are addressed with a "key" reference, which has the following syntax: /<zone>/<path>[#<value_path>].
Using Java syntax, the GC APIs are summarized as follows:
| GlobalContext APIs | Description |
V get(String key) | Returns the value stored at key (null is a valid value), if found; throws an IllegalArgumentException exception otherwise. |
V condGet(String key, V default) | Returns the value stored at key (null is a valid value), if found; returns default value otherwise. |
boolean containsKey(String key) | Returns true if the key is found; returns false value otherwise. |
List<String> list(String prefix) | Returns a list of defined keys that start with the specified prefix. |
List<String> list(String prefix, boolean includePrefix) | Returns a list of keys that start with the specified prefix. If includePrefix == false, then the keys are relative to the prefix (for example, list("/request", true) would return keys like /request/foo/bar; list("/request", false) would return /foo/bar ). |
T put(String key, V o) | Replaces a value, if present; otherwise it creates an entry. Returns the previous value associated with the key, or null if the key was not found. Throws an IllegalArgumentException exception if no zone handler is found. |
T post(String key, V o) | Appends o to the value, if present; otherwise it creates an entry. Returns previous value associated with the key, or null if the key was not found. Support for append is a function of the zone handler. Throws an IllegalArgumentException exception if no zone handler is found. |
void delete(String key) | Removes the entry. Equivalent to delete(key, false). |
void delete(String key, boolean deleteChildren) | If deleteChildren == true, then removes all entries that start with key; otherwise, removes just the entry at key. |
String dump(String key) | Returns a formatted string listing the Global Context content at and below the specified key. Throws an IllegalArgumentException exception if no zone handler is found. |
PHP API
The Global Context API for PHP consists of the following calls:
put(string $key, mixed $value)
mixed get(string $key)
mixed cond_get(string $key, mixed $defaultValue)
boolean contains(string $key)
mixed remove(string $key)
dump()
The keys in the PHP API are identical to those using the Java API and the elements of the key are slash (/) delimited.
Value "pathing"
Value pathing refers to sub-elements within a stored value. Value paths are specified by appending fragment identifiers to the key. Details about the fragment (syntax and meaning) are dependent on the type handler associated with the value.
Before we get into the details of type handlers, it may be useful to summarize the support for put and post within the GC APIs:
-
put() means create (if not defined) or replace (otherwise)
-
post() means create (if not defined) or append (otherwise)
Maps
| Java API | Groovy API | Description | Can create entry |
GlobalContext.put("/app/myMap", map) | app.myMap = map | Create/replace existing map | |
GlobalContext.put("/app/myMap#foo", "bar") | app.myMap['foo'] = 'bar' | Add/replace entry; map must exist | |
| | | | |
GlobalContext.post("/app/myMap", map) | app.myMap << map | Create/merge into existing map; replaces existing keys | |
| | | | |
GlobalContext.get("/app/myMap") | x = app.myMap.get() | Returns full map | |
GlobalContext.get("/app/myMap#foo") | x = app.myMap['foo'] | Returns entry at key foo | |
| | | | |
GlobalContext.delete("/app/myMap") | _gc.delete('/app/myMap') | Deletes map | |
GlobalContext.delete("/app/myMap#foo") | _gc.delete('/app/myMap#foo') | Removes entry | |
Note: The following example is not valid: GlobalContext.post("/app/myMap#foo", "bar").
The Map type handler supports the #<key> fragment. It refers to the value mapped to <key>.
Lists
| Java API | Groovy API | Description | Can create entry |
GlobalContext.put("/app/myList", list) | app.myList = list | Create/replace existing list | |
GlobalContext.put("/app/myList#0", "bar") | app.myList[0] | Set/replace list element; list must exist | |
| | | | |
GlobalContext.post("/app/myList", list) | app.myList << list | Create/append to list | |
GlobalContext.post("/app/myList", "bar") | app.myList << 'bar' | Append to list; list must exist | |
| | | | |
GlobalContext.get("/app/myList") | x = app.myList.get() | Returns full list | |
GlobalContext.get("/app/myList#0") | x = app.myList[0] | Returns 0th element | |
| | | | |
GlobalContext.delete("/app/myList") | _gc.delete("/app/myList") | Deletes list | |
GlobalContext.delete("/app/myList#0") | _gc.delete("/app/myList[0]") | Removes first entry | |
The List type handler supports the #<N> fragment. It refers to the N-th element in the list.
FirstElementList
FirstElementList is a variant of List that supports access to the first element as a simple object (without specifying the index). This simplifies handling of values, like query parameters, that are properly stored as lists but are most commonly retrieved as single values.
Within the default zones, only /request/params/<parmName> and /request/headers/in/<headerName> are instances of FirstElementList.
| Java API | Groovy API | Description | Can create entry |
GlobalContext.put("/app/myList", list) | app.myList = list | Create list; list does not exist | |
GlobalContext.put("/app/myList#*", list) | app.myList['*'] = list | Replace list; list must exist | |
GlobalContext.put("/app/myList", "bar") | app.myList = "bar" | Set/replace first element; list must exist | |
GlobalContext.put("/app/myList#0", "bar") | app.myList[0] | Set/replace list element; list must exist | |
| | | | |
GlobalContext.post("/app/myList", list) | app.myList << list | Create list; list does not exist | |
GlobalContext.post("/app/myList#*", "bar") | app.myList['*'] << "bar" | Append to list; list must exist | |
| | | | |
GlobalContext.get("/app/myList") | x = app.myList.get() | Returns first element | |
GlobalContext.get("/app/myList#0") |
|