3.0 Web Scripts Framework

From alfrescowiki

Jump to: navigation, search


Back to Web Scripts.

NOTE: This document describes features found in Alfresco v3 onwards (Older versions: v2)


Introduction

The Web Script framework is the engine for the registration and execution of Web Scripts. This page describes the architecture of the engine and how it can be configured.

Web Script MVC

Before diving into the architecture of the framework it's worth reviewing the flow of execution when a Web Script is called.

WebOrientedRestStyleArchitecture.jpg

1. A request for a given URI arrives at the Web Script Runtime.

2. The Runtime finds the appropriate Web Script for the URI. If one is found, the Runtime executes the Web Script but only after successfully authenticating first, if required. The first step of execution is to invoke the JavaScript bound into the Web Script.

3. With JavaScript, you have access to a set of Alfresco services. When hosted within the Repository server you can search for information, navigate around the repository, modify information, create new documents, set properties on those documents, move data around, and delete data, plus access to all other Repository services. Outside of the Repository you can invoke remote services such as those by the Repository server.

4. The results from the JavaScript are rendered using FreeMarker response templates. The response format may be one of HTML, ATOM, XML, RSS, JSON, CSV, or any combination of these. You must provide the appropriate templates.

5. The Web Script Runtime sends the rendered results back via a response using the same protocol as the URI request.

6. The Web Script client receives the response in the requested format.

Architecture

In Alfresco v3, the Web Script framework architecture was refactored to allow the hosting of it in any environment, not just the Alfresco Repository server. This opens the door to applying Web Scripts to all sorts of problems (not just data services in the Repository) such as User Interface rendering in a presentation tier. In fact, the Alfresco SURF Platform, a web application framework hosts the Web Script framework for re-usable UI components.

Although Web Scripts are accessible via HTTP, their URI addressability means they can actually be hosted in a number of different environments (and therefore accessed via a protocol appropriate to the environment). The Web Script framework separates the notion of a Web Script (that is, a unit of work) and its environment (that is, the host within which the unit of work is executed), which is known as a Web Script Runtime. The most commonly used run-time is the Servlet run-time which supports the HTTP protocol for access.

Webscriptdeploy.jpg

A typical deployment includes an Alfresco Repository server hosting data Web Scripts with one or more Alfresco clients hosting presentation Web Scripts where communication between the two is over HTTP. The Alfresco Repository utilises the Servlet Run-time whereas a remote Web Client utilises the SURF Run-time for hosting Web Scripts. However, this is just one of many options given the following available Web Script Runtimes:

  1. Servlet Runtime (HTTP accessible)
  2. SURF Runtime (embed Web Script UI components in web-tier UI pages)
  3. JSR-168 Runtime (adapter between JSR-168 portlet API and Web Script)
  4. JSF Runtime (JSF tag to include Web Script)
  5. Facebook Runtime (access to Facebook API and Repository API within Web Script)

It's important to note that presentation Web Scripts may be hosted in multiple environments without code change. For example, a portlet style Web Script such as "My Tasks" which is self-contained from a user interface perspective may be developed once, but deployed as a Share Dashlet, JSR-168 portlet or URI addressable HTML page.

The Web Script framework is a Spring configured engine consisting of the following high-level components:

Webscriptdesign.jpg

Most components are an implementation of an interface. This allows alternative component implementations for each environment within which to execute Web Scripts. Responsbilities of each component are:

  • Runtime - entry point for execution; encapsulates the execution environment, in particular, requests, responses, authentication, and error handling.
  • Container - encapsulates the host within which the Web Script executes and has access to. In particular, is the central hook point for all other services, and is responsible for providing appropriate script & template root objects to Web Scripts.
  • Authenticator - responsible for authenticating requests.
  • Configuration Service - reads and parses all related XML configuration files.
  • Web Script Registry - maintains the index of all registered Web Scripts.
  • Web Script - the unit of work to execute.
  • Script Processor - responsible for executing JavaScript.
  • Template Processor - responsible for executing Templates.
  • Formats - registry of format to mimetype and vice-versa.
  • Store - an end point for loading Web Script files such as Description Documents, Javascript, Templates and Configuration.
  • Search Path - an ordered set (from highest to lowest precedence) of Stores for lookup of Web Script files.

We've already seen there are several types of Runtime available out-of-the-box. These Runtimes can be setup in conjunction with one the following out-of-the-box Containers:

  1. Presentation - a light-weight container for rendering User Interface components that can make service calls to remote data sources.
  2. Repository - a container for embedded use in the Alfresco Repository providing integration with transactions and direct access to content held in the Repository and services provided by the Repository.

All of these components are bound together via Spring configuration. The vanilla Web Script framework suitable for building User Interface components which can be housed in any environment is defined in

webscript-framework-application-context.xml

An extended version of the binding to support Repository embedding (and the Alfresco RESTful API) is defined in

web-scripts-application-context.xml

Finally, an Alfresco SURF binding to support web page rendering is defined in

web-framework-application-context.xml

Configuring the Framework

Logging

Web Scripts logging is controlled via the following log4j entries:

Web Script framework
log4j.logger.org.alfresco.web.scripts=debug
Repository Container
log4j.logger.org.alfresco.repo.web.scripts=debug

Web Server Host

To execute Web Scripts behind a firewall or proxy, you must first provide your public Web Server address, so that any links generated by Web Scripts refer back to the public server.

This is achieved by editing (or providing a custom):

webscript-framework-config.xml

and providing the host details in the following:

<config evaluator="string-compare" condition="Server">
  <!-- The public web server hosting this web client -->
  <server>
     <scheme>http</scheme>
     <hostname>anexample</hostname>
     <port>8080</port>
  </server>
</config>

HTTP Response Formats

All Web Script URLs support the format argument for specifying the response type.

Formats available "out-of-the-box" are:

  • html => text/html
  • text => text/plain
  • xml => text/xml
  • atom => application/atom+xml
  • atomentry => application/atom+xml;type=entry
  • atomfeed => application/atom+xml;type=feed
  • rss => application/rss+xml
  • json => application/json
  • opensearchdescription => application/opensearchdescription+xml
  • mediawiki => text/plain (Media Wiki markup)
  • portlet => text/html (head & tail chopped)
  • fbml => text/html
  • php => text/html
  • js => text/javascript
  • calendar => text/calendar

e.g.

GET http://<host>:<port>/<contextPath>/<servicePath>/helloworld?to=fred&format=xml
GET http://<host>:<port>/<contextPath>/<servicePath>/helloworld.xml?to=fred

New response formats may be supported by declaring a "Format Map" Spring Bean as follows where format short names are mapped to mimetypes

<bean parent="webscripts.formatmap">
  <property name="formats">
    <props>
      <prop key="wav">audio/x-wav</prop>
    </props>
  </property>
</bean>

Multiple beans may be declared.

A custom "Format Map" may be provided for a given user agent

<bean parent="webscripts.formatmap">
  <property name="agent"><value>MSIE</value></property>
  <property name="formats">
    <props>
      <prop key="atom">text/xml</prop>
    </props>
  </property>
</bean>

Valid agent values are (currently):

  • MSIE (Micrsoft Internet Explorer)

Available Runtimes

Servlet Runtime

The Servlet Runtime maps HTTP requests to Web Scripts.

It's configured just as any other servlet in web.xml:

<servlet>
  <servlet-name>WebScriptServlet</servlet-name>
  <servlet-class>org.alfresco.web.scripts.WebScriptServlet</servlet-class>
  <init-param>
     <param-name>authenticator</param-name>
     <param-value>webscripts.authenticator.basic</param-value>
  </init-param>
</servlet>

The following initialization parameters are supported:

authenticator 
the web script Authenticator as specified by its unique id

Multiple Web Script servlets may be configured, allowing multiple url mappings where each mapping may use a different authenticator.

<servlet-mapping>
  <servlet-name>WebScriptServlet</servlet-name>
  <url-pattern>/service/*</url-pattern>
</servlet-mapping>

The following pre-defined Web Script are available:

/alfresco/service or /alfresco/s 
mapped to HTTP Basic Authenticator
/alfresco/wcservice or /alfresco/wcs 
mapped to Web Client Authenticator
/alfresco/168service or /alfresco/168s 
mapped to JSR-68 Authenticator

Alfresco SURF Runtime

See Surf Platform for details.

JSR-168 Runtime

The JSR-168 Runtime maps a portlet to a Web Script.

A JSR-168 proxy portlet class is provided which may be configured as follows:

<portlet>
  <description>A Portlet</description>
  <portlet-name>Portlet Name</portlet-name>
  <portlet-class>org.alfresco.web.scripts.portlet.WebScriptPortlet</portlet-class>
       
  <init-param>
    <param-name>authenticator</param-name>
    <param-value>webscripts.authenticator.jsr168.webclient</param-value>
  </init-param>
  <init-param>
    <name>scriptUrl</name>
    <value>/alfresco/service/portlet/aportlet</value>
  </init-param>

  <supports>
    <mime-type>text/html</mime-type>
    <portlet-mode>VIEW</portlet-mode>
  </supports

  <portlet-info>
    <title>Portlet Title</title>
    <short-title>Portlet Short Title</short-title</short-title>
  </portlet-info>
</portlet>


Note: For versions beyond 3.3 the WebScriptPortlet class has been moved to Spring Surf. Instead use:

<portlet-class>org.springframework.extensions.webscripts.portlet.WebScriptPortlet</portlet-class> 

The following initialization parameters are supported:

authenticator (optional) 
the web script Authenticator as specified by its unique id. If not specified, the default JSR-168 authenticator (webscripts.authenticator.jsr168) is used.
scriptUrl 
the url to the web script

JSF Runtime

The JSF Runtime maps a JSF component to a Web Script.

It's configured as follows within a JSP:

<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>

...

<r:webScript scriptUrl="/wcservice/<web script url>" />

The following parameters are available:

scriptUrl 
the url of the Web Script

Authentication is handled by the Alfresco Web Client.

Available Authenticators

Alfresco is a secure server requiring authenticated access.

The Web Script framework defers authentication to a plug-in Authenticator. By default, Basic HTTP Authentication is activated. See available Runtimes for information on how to change the authentication mechanism in each runtime.

Other forms of authentication will also be considered:

  1. ATOM authentication mechanism (such as http://www.xml.com/pub/a/2003/12/17/dive.html)
  2. WSSE
  3. OpenID

HTTP Basic Authenticator

(id: webscripts.authenticator.basic)

This authenticator supports HTTP Basic Authentication. The authorisation header must contain either:

  • username & password
  • ticket

For restricted environments that do not allow the setting of HTTP Request Headers, a ticket may be passed via the URL argument 'alf_ticket'.

Alfresco Explorer Authenticator

(id: webscripts.authenticator.webclient)

This authenticator relies on the authentication mechanism configured into the Alfresco Explorer web client. If login is required, a redirect to the Alfresco Explorer login page is made.

JSR-168 Authenticator

(id: webscripts.authenticator.jsr168)

This authenticator relies on the user name setup by the JSR-168 runtime. It assumes the user has already been authenticated by the Portal. The Alfresco Repository executes in the context of the Portal user.

JSR-168 Authenticator with Alfresco Explorer support

(id: webscripts.authenticator.jsr168.webclient)

This authenticator ensures that the Alfresco Explorer web client user context is kept in sync with the Portal user. This allows Web Scripts that depend on Alfresco Explorer functionality to be used within the Portal.

Note: It is only possible to use this authenticator in the repository tier, not the presentation tier.

Available Containers

Presentation Container

The Presentation Container is a vanilla container which provides basic support to Web Scripts for calling remote data sources. Its simplicity makes it ideal for hosting Web Scripts in any environment.

Repository Container

The Repository Container is a specialised container for embedding only in the Alfresco Repository. It hooks directly into Alfresco Repository support for transactions and authentication. It also provides Repository specific root objects to Controller Scripts and Templates.

Extending the Framework (SPIs)

The Web Script Framework has several Service Provider Interfaces for extending or replacing the behaviour of the framework. You will need to understand how to configure Spring and develop Java code to carry out this kind of change.

Authenticator SPI

An Authenticator simply has to implement the interface:

org.alfresco.web.scripts.Authenticator

All context required by the implementation should be passed in at construction time. Note, the Authenticator is constructed by the Runtime. There's only method to implement.

/**
 * Authenticate Web Script execution
 * 
 * @param required  required level of authentication
 * @param isGuest  is Guest accessing the web script
 * 
 * @return true if authorised to execute the script, false otherwise
 */
 public boolean authenticate(RequiredAuthentication required, boolean isGuest);

The required parameter is an enumeration of the <authentication> value defined in the Web Script Description Document.

Runtime SPI

A Web Script Runtime is implemented by deriving a Java class from:

org.alfresco.web.scripts.Runtime

This is an abstract class requiring the following methods to be implemented:

/**
 * Get the web script method  e.g. get, post
 * 
 * @return  web script method
 */
protected abstract String getScriptMethod();

/**
 * Get the web script Url
 * 
 * @return  web script url
 */
protected abstract String getScriptUrl();
    
/**
 * Create a web script request
 * 
 * @param match  web script matching the script method and url
 * @return  web script request
 */
protected abstract WebScriptRequest createRequest(WebScriptMatch match);
    
/**
 * Create a web script response
 * 
 * @return  web script response
 */
protected abstract WebScriptResponse createResponse();
/**
 * Create a Web Script Authenticator
 * 
 * @return  web script authenticator
 */
protected abstract Authenticator createAuthenticator();

Implementations of:

org.alfresco.web.scripts.WebScriptRequest
org.alfresco.web.scripts.WebScriptResponse
org.alfresco.web.scripts.Authenticator

are also required as they are instantiated by createRequest, createResponse and createAuthenticator respectively. The helper class:

org.alfresco.web.scripts.WebScriptURLRequest

provides a skeleton implementation of WebScriptRequest given a URL string.

The following pattern is used to execute a Web Script via a Web Script Runtime:

WebScriptRuntime runtime = new CustomWebScriptRuntime(...);
runtime.executeScript();

Runtime context is passed in via the constructor, for example, for a servlet, the HttpServletRequest and HttpServletResponse.

A new Web Script Runtime must be instantiated for each invocation (where the context changes), for example, for each servlet request.

Container SPI

A Web Script Container is implemented by deriving a Java class from:

org.alfresco.web.scripts.RuntimeContainer

This is an abstract class requiring the following methods to be implemented:

/**
 * Execute the script in the context of the provided request and response
 * 
 * @param scriptReq
 * @param scriptRes
 */
public void executeScript(WebScriptRequest scriptReq, WebScriptResponse scriptRes, Authenticator auth)
  throws IOException;

Format Reader SPI

A Format Reader simply has to implement the interface:

org.alfresco.web.scripts.FormatReader

It has to implement the following methods:

/**
 * Gets the source mimetype to convert from
 * 
 * @return  mimetype
 */
public String getSourceMimetype();
   
/**
 * Gets the Java Class to convert to
 * 
 * @return  Java Clas
 */
public Class<? extends Type> getDestinationClass();
       
/**
 * Converts mimetype to Java Object
 * 
 * @param req  web script request
 * @return  Java Object
 */
public Type read(WebScriptRequest req);
   
/**
 * Create script parameters specific to source mimetype
 * 
 * @param req  web script request
 * @param res  web script response
 * @return  map of script objects indexed by name
 */
public Map<String, Object> createScriptParameters(WebScriptRequest req, WebScriptResponse res);

Format Reader implementations are registered via Spring configuration:

<bean id="..." parent="webscripts.adaptorset">
  <property name="readers">
     <list>
       <bean class="x.x.x.CustomFormatReader"/>
     </list>
  </property>
</bean>

Research

REST Resources
REST Blogs
Personal tools
© 2014 Alfresco Software, Inc. All Rights Reserved. Legal | Privacy | Accessibility