2. Application Configuration

 Documentation Summary
 Page Summary

Basic Configuration

As the most basic level, GraniteDS is a simple servlet (more precisely a servlet and a filter). In a first step, enabling GraniteDS for an application consists in adding the libraries in WEB-INF/lib and adding the necessary configuration in web.xml.

The necessary Java libraries depend on the various server integrations you will use but at least include granite.jar that can be found in the build folder of the distribution.

Following is a configuration in web.xml suitable for most use cases :

    <filter>
        <filter-name>AMFMessageFilter</filter-name>
        <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AMFMessageFilter</filter-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>AMFMessageServlet</servlet-name>
        <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AMFMessageServlet</servlet-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </servlet-mapping>

This configuration defines the GraniteDS servlet/filter mapped to the /graniteamf/* uri.

Once this is done, GraniteDS needs its own configuration files, that are generally WEB-INF/flex/services-config.xml and WEB-INF/granite/granite-config.xml.

services-config.xml should be relatively familiar if you have already used Flex remoting. It contains the definitions of the AMF channels and destinations that will be exposed by GraniteDS.

Here is a simple example :

<services-config>

    <services>
        <service id="granite-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">

            <destination id="example">
                <channels>
                    <channel ref="graniteamf"/>
                </channels>
                <properties>
                    <factory>ejbFactory</factory>
                </properties>
            </destination>
        </service>
    </services>

    <factories>
        <factory id="ejbFactory" class="org.granite.messaging.service.EjbServiceFactory">
            <properties>
                <lookup>graniteds-ejb3/{capitalized.destination.id}ServiceBean/local</lookup>
            </properties>
        </factory>
    </factories>

    <channels>
        <channel-definition id="graniteamf" class="mx.messaging.channels.AMFChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

</services-config>

This configuration file declares 3 differents things, let's list them in the reverse order :

  • Channel endpoint : this defines the uri on which the remote service can be accessed though Flex remoting. This should match the servlet mapping defined previously in web.xml. Note that the server-name, server-port and context-root are placeholders that are automatically replaced when running the application in the Flash Player. To run the application on the AIR runtime you will have to specify the real name and port of the server.
  • Service factories : here the configuration defines an EJB3 factory, meaning that destinations using this factory will be interpreted as EJB3 calls. GraniteDS provides factories for all usual server frameworks. Most factory require specific properties, here for example the JNDI format for EJB lookup.
  • Service/destinations : this section defines a remoting service (described by its class and message type) and one destination interpreted as an EJB3 as indicated by the factory property.

The last part of the configuration is the WEB-INF/granite/granite-config.xml file. It contains all other properties specific to GraniteDS. A DTD helping in completing this file is provided and the following paragraphs describe in details what can be found in this file.
The minimal file should be :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN"
    "http://www.graniteds.org/public/dtd/2.1.0/granite-config.dtd">

<granite-config>
</granite-config>

You have probably noted that all this stuff is relatively verbose, in particular the services-config.xml and granite-config.xml. GraniteDS provides many ways to reduce or even remove the need for these files, that will be described in more details in the next parts. With most frameworks (Spring, Seam, JEE6, it's also possible to include the configuration in the framework configuration itself instead of these GraniteDS-specific files.

It's important to note that if you use this services-config.xml file, the Flex application has to be compiled statically with the option -services services-config.xml.

Autoscan Functionality

The following configuration activates the automatic configuration scanner:

granite-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE granite-config PUBLIC
    "-//Granite Data Services//DTD granite-config internal//EN"
    "http://www.graniteds.org/public/dtd/2.1.0/granite-config.dtd">

<granite-config scan="true">
    <!-- Other explicit configuration settings -->
</granite-config>

This scanner has two functionalities : GraniteDS configuration and services configuration.

GraniteDS Configuration:

First, the scan="true" attribute instructs the GraniteDS startup class to scan all jars containing a META-INF/granite-config.properties and to look for configurable classes. This includes:

  • Externalizers
  • Exception converters
  • Custom type converters
  • Class getter
  • Message interceptor

Externalizers and exception converters are automatically registered in GraniteDS; that is, all classes implementing respectively org.granite.messaging.amf.io.util.externalizer.Externalizer or org.granite.messaging.service.ExceptionConverter are handled.

Class getter, type converters, and message interceptor have to be defined in granite-config.properties:

granite-config.properties
classGetter=path.to.my.ClassGetter
amf3MessageInterceptor=path.to.my.Amf3MessageInterceptor
converter.1=path.to.my.Converter1
converter.2=path.to.my.Converter2
converter.3=path.to.my.Converter3
...
converter.(n)=path.to.my.Converter(n)

In most cases, this means that no particular configuration is needed in granite-config.xml, other than putting the library-specific granite jars in the server classpath. For example, granite-hibernate.jar already defines standard Hibernate externalizers, exception converters, and class getter.

Of course, it is also possible to use this for custom configuration. Just put a META-INF/granite-config.properties in the jar containing your custom externalizers and converters, and make sure this jar is accessible in the same class loader used by the standard granite.jar package (i.e., the classpath where granite.jar is declared must also contain your custom jar).

Automatic configuration is always overriden by anything defined in the granite-config.xml file.

Flex Services Configuration:

Secondly, and most importantly, the scanner will scan jars containing META-INF/services-config.properties. It will look for classes annotated with @RemoteDestination, and automatically register them as GDS services. As this depends on each server framework, more details are provided in the Integration with Server Frameworks section, mainly for EJB 3 and Spring.

Note that automatic configuration only works with RemoteObject(s) that are dynamically configured in your MXML or ActionScript3 code. For example, you may not use this kind of MXML declaration, because the Flex compiler won't be able to match the myDestination attribute against any services-config.xml declaration:

<mx:RemoteObject id="srv" destination="myDestination" />

Instead, you should create your RemoteObject this way:

[Bindable]
private var srv:RemoteObject = null;

private function init():void {
    srv = new RemoteObject();

    // This line is required for Flex 2 only (may be skipped with Flex 3+)
    srv.endpoint = ServerConfig.getChannel("my-graniteamf").endpoint;
    
    srv.destination = "myDestination";
    srv.channelSet = new ChannelSet();
    srv.channelSet.addChannel(ServerConfig.getChannel("my-graniteamf"));
    ...
}

Note that you still need a services-config.xml with a valid service, factory, and channel declaration at compilation time. For example, with an EJB 3 factory:

services-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<services-config>

    <services>
        <service id="granite-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
            <!-- No destination configuration needed -->
        </service>
    </services>

    <factories>
        <factory id="ejbFactory" class="org.granite.messaging.service.EjbServiceFactory">
            <properties>
                <lookup>myApplication/{capitalized.destination.id}ServiceBean/local</lookup>
            </properties>
        </factory>
    </factories>

    <channels>
        <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

</services-config>

 


Browse Space

- Pages
- Blog
- Labels
- Attachments
- Bookmarks
- Mail
- Advanced

Explore Confluence

- Popular Labels
- Notation Guide

Your Account

Log In

Other Features

Add Content


Copyright © 2011 Granite Data Services S.A.S. All Rights Reserved.