JBoss.orgCommunity Documentation

Chapter 2. JBoss Communications Diameter Stack

2.1. Diameter Stack Design
2.1.1. Diameter Stack Extensibility
2.1.2. Diameter Stack Model
2.1.3. Application Session Factories
2.1.4. Session Replication
2.2. JBoss Communications Diameter Stack Setup
2.2.1. Pre-Install Requirements and Prerequisites
2.2.2. Source Code
2.3. Diameter Stack Configuration
2.3.1. Cluster configuration
2.4. Diameter Stack Source overview
2.4.1. Session Factory
2.4.2. Sessions
2.4.3. Application Session Factories
2.5. Diameter Stack Validator
2.5.1. Validator Configuration
2.5.2. Validator Source Overview

The Diameter Stack is the core component of the presented Diameter solution. It performs all necessary tasks to allow user interaction with the Diameter network. It manages the state of diameter peers and allows to route messages between them. For more details, refer to RFC 3588.

The Diameter Stack currently supports the following application sessions:

This section provides instructions on how to obtain and build the JBoss Communications Diameter Stack from source code.

  1. Downloading the source code

    Use SVN to checkout a specific release source, the base URL is ??, then add the specific release version, lets consider 1.4.0.CR1.

    [usr]$ svn co ??/1.4.0.CR1 jdiameter-1.4.0.CR1
  2. Building the source code

    Important

    Maven 2.0.9 (or higher) is used to build the release. Instructions for using Maven2, including install, can be found at http://maven.apache.org

    Use Maven to build the deployable unit binary.

    						[usr]$ cd jdiameter-1.4.0.CR1
    						[usr]$ mvn install
    					

    Once the process finishes you should have the JAR files deployed in maven archive.

Follow the process in Section 2.2.2.1, “Release Source Code Building”, replacing the SVN source code URL with ${THIS.JDIAMETER_TRUNK_SOURCE_CODE_URL}.

The stack is initially configured by parsing an XML file. The top level structure of the file is described below. Further explanation of each child element, and the applicable attributes, is provided later in this section.


<Configuration xmlns="http://www.jdiameter.org/jdiameter-server">

    <LocalPeer></LocalPeer>
    <Parameters></Parameters>
    <Network></Network>
    <Extensions></Extensions>

</Configuration>

<LocalPeer>
    <URI value="aaa://localhost:3868"/>
    <IPAddresses>
        <IPAddress value="127.0.0.1"/>
    </IPAddresses>

    <Realm value="mobicents.org"/>
    <VendorID value="193"/>
    <ProductName value="jDiameter"/>
    <FirmwareRevision value="1"/>

    <OverloadMonitor>
        <Entry index="1" lowThreshold="0.5" highThreshold="0.6">
            <ApplicationID>
                <VendorId value="193"/>
                <AuthApplId value="0"/>
                <AcctApplId value="19302"/>
            </ApplicationID>
        </Entry>
    </OverloadMonitor>
    <Applications>
        <ApplicationID>
            <VendorId value="193"/>
            <AuthApplId value="0"/>
            <AcctApplId value="19302"/>
        </ApplicationID>
    </Applications>
</LocalPeer>

The <LocalPeer> element contains parameters that affect the local Diameter peer. The available elements and attributes are listed for reference.

<LocalPeer> Elements and Attributes

<URI>

Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port".

<IPAddresses>

Contains one or more child <IPAddress> element, which contain a single, valid IP address for the local peer, stored in the value attribute of the IPAddress.

<Realm>

Specifies the realm of the local peer, using the value attribute.

<VendorID>

Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA.

<ProductName>

Specifies the name of the local peer product.

<FirmwareRevision>

Specifies the version of the firmware.

<OverloadMonitor>

Optional parent element containing child elements that specify settings relating to the Overload Monitor.

<Entry>

Supports <ApplicationID> child elements that specify the ID of the tracked application(s). It also supports the following properties:

<ApplicationID>

Parent element containing child elements that specify information about the application. The child elements create a unique application identifier. The child elements are:

<Applications>

Contains a child element <ApplicationID>, which defines the list of default supported applications. It is used for the server side, when the stack is configured to accept incoming calls and there is an empty list of preconfigured peers (server is configured to accept any connection).


<Parameters>

    <AcceptUndefinedPeer value="true"/>
    <DuplicateProtection value="true"/>
    <DuplicateTimer value="240000"/>
    <UseUriAsFqdn value="true"/> <!-- Needed for Ericsson SDK Emulator -->
    <QueueSize value="10000"/>
    <MessageTimeOut value="60000"/>
    <StopTimeOut value="10000"/>
    <CeaTimeOut value="10000"/>
    <IacTimeOut value="30000"/>
    <DwaTimeOut value="10000"/>
    <DpaTimeOut value="5000"/>
    <RecTimeOut value="10000"/>

    <Concurrent>
        <Entity name="ThreadGroup" size="64"/>
        <Entity name="ProcessingMessageTimer" size="1"/>
        <Entity name="DuplicationMessageTimer" size="1"/>
        <Entity name="RedirectMessageTimer" size="1"/>
        <Entity name="PeerOverloadTimer" size="1"/>
        <Entity name="ConnectionTimer" size="1"/>
        <Entity name="StatisticTimer" size="1"/>
        <Entity name="ApplicationSession" size="16"/>
    </Concurrent>

</Parameters>

The <Parameters> element contains elements that specify parameters for the Diameter stack. The available elements and attributes are listed for reference. If not specified otherwise, each tag supports a single property - "value", which indicates the value of the tag.

<Parameters> Elements and Attributes

<AcceptUndefinedPeer>

Specifies whether the stack will accept connections from undefined peers. The default value is false.

<DuplicateProtection>

Specifies whether duplicate message protection is enabled. The default value is false.

<DuplicateTimer>

Specifies the time each duplicate message is valid for. The default, minimum value is 240000 (4 minutes in milliseconds).

<UseUriAsFqdn>

Determines whether the URI should be used as FQDN. If it is set to true, the stack expects the destination/origin host to be in the format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". The default value is false.

<QueueSize>

Determines how many tasks the peer state machine can have before rejecting the next task. This queue contains FSM events and messaging.

<MessageTimeOut>

Determines the timeout for messages other than protocol FSM messages. The delay is in milliseconds.

<StopTimeOut>

Determines how long the stack waits for all resources to stop. The delays are in milliseconds.

<CeaTimeOut>

Determines how long it takes for CER/CEA exchanges to timeout if there is no response. The delays are in milliseconds.

<IacTimeOut>

Determines how long the stack waits to retry the communication with a peer that has stopped answering DWR messages. The delay is in milliseconds.

<DwaTimeOut>

Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. The delay is in milliseconds.

<DpaTimeOut>

Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. The delay is in milliseconds.

<RecTimeOut>

Determines how long it takes for the reconnection procedure to timeout. The delay is in milliseconds.

<Concurrent />

Controls the thread pool sizes for different aspects of the stack. It supports multiple Entity child elements. Entity elements configure thread groups. These elements support the following properties:

The default supported entities are:


<Network>

    <Peers>
        <!-- This peer is a server, if it's a client attempt_connect should be set to false -->
        <Peer name="aaa://127.0.0.1:3868" attempt_connect="true" rating="1"/>
    </Peers>

    <Realms>
        <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" dynamic="false" exp_time="1">
            <ApplicationID>
                <VendorId value="193"/>
                <AuthApplId value="0"/>
                <AcctApplId value="19302"/>
            </ApplicationID>
        </Realm>
    </Realms>

</Network>

The <Network> element contains elements that specify parameters for external peers. The available elements and attributes are listed for reference.

Below is an example configuration file for a server supporting the CCA, Sh and Ro Applications:


<?xml version="1.0"?>
<Configuration xmlns="http://www.jdiameter.org/jdiameter-server">

    <LocalPeer>
        <URI value="aaa://127.0.0.1:3868" />
        <Realm value="mobicents.org" />
        <VendorID value="193" />
        <ProductName value="jDiameter" />
        <FirmwareRevision value="1" />
        <OverloadMonitor>
            <Entry index="1" lowThreshold="0.5" highThreshold="0.6">
                <ApplicationID>
                    <VendorId value="193" />
                    <AuthApplId value="0" />
                    <AcctApplId value="19302" />
                </ApplicationID>
            </Entry>
        </OverloadMonitor>
    </LocalPeer>

    <Parameters>
        <AcceptUndefinedPeer value="true" />
        <DuplicateProtection value="true" />
        <DuplicateTimer value="240000" />
        <UseUriAsFqdn value="false" /> <!-- Needed for Ericsson Emulator (set to true) -->
        <QueueSize value="10000" />
        <MessageTimeOut value="60000" />
        <StopTimeOut value="10000" />
        <CeaTimeOut value="10000" />
        <IacTimeOut value="30000" />
        <DwaTimeOut value="10000" />
        <DpaTimeOut value="5000" />
        <RecTimeOut value="10000" />
        <Concurrent>
             <Entity name="ThreadGroup" size="64"/>
             <Entity name="ProcessingMessageTimer" size="1"/>
             <Entity name="DuplicationMessageTimer" size="1"/>
             <Entity name="RedirectMessageTimer" size="1"/>
             <Entity name="PeerOverloadTimer" size="1"/>
             <Entity name="ConnectionTimer" size="1"/>
             <Entity name="StatisticTimer" size="1"/>
             <Entity name="ApplicationSession" size="16"/>
        </Concurrent>
    </Parameters>

    <Network>
        <Peers>
            <Peer name="aaa://127.0.0.1:1218" attempt_connect="false" rating="1" />
        </Peers>
        <Realms>
            <!-- CCA -->
            <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" 
                dynamic="false" exp_time="1">
                <ApplicationID>
                    <VendorId value="0" />
                    <AuthApplId value="4" />
                    <AcctApplId value="0" />
                </ApplicationID>
            </Realm>
            
            <!-- Sh -->
            <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" 
                dynamic="false" exp_time="1">
                <ApplicationID>
                    <VendorId value="10415" />
                    <AuthApplId value="16777217" />
                    <AcctApplId value="0" />
                </ApplicationID>
            </Realm>

            <!-- Ro -->
            <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" 
                dynamic="false" exp_time="1">
                <ApplicationID>
                    <VendorId value="10415" />
                    <AuthApplId value="4" />
                    <AcctApplId value="0" />
                </ApplicationID>
            </Realm>
        </Realms>
    </Network>

    <Extensions />

</Configuration>

The following list defines the requirements for enabling stack cluster mode

Diameter stack is built with the following basic components:

SessionFactory provides the stack user with access to session objects. It manages registered application session factories in order to allow for the creation of specific application sessions. A Session Factory instance can be obtained from the stack using the getSessionFactory() method. The base SessionFactory interface is defined below:

package org.jdiameter.api;


import org.jdiameter.api.app.AppSession;
public interface SessionFactory {
    RawSession getNewRawSession() throws InternalException;
    Session getNewSession() throws InternalException;
    Session getNewSession(String sessionId) throws InternalException;
    <extends AppSession> T getNewAppSession(ApplicationId applicationId, 
        Class<? extends AppSession> userSession) throws InternalException;
    <extends AppSession> T getNewAppSession(String sessionId, ApplicationId
        applicationId, Class<? extends AppSession> userSession) throws InternalException;
}

However, since the stack is extensible, it is safe to cast the SessionFactory object to this interface:

package org.jdiameter.client.api;



public interface ISessionFactory extends SessionFactory {
    <extends AppSession> T getNewAppSession(String sessionId, 
        ApplicationId applicationId, java.lang.Class<? extends AppSession> 
        aClass, Object... args) throws InternalException;
    void registerAppFacory(Class<? extends AppSession> sessionClass, 
        IAppSessionFactory factory);
    void unRegisterAppFacory(Class<? extends AppSession> sessionClass);
    IConcurrentFactory getConcurrentFactory();
}
RawSession getNewRawSession() throws InternalException;

This method creates a RawSession. Raw sessions are meant as handles for code performing part of the routing decision on the stack's, such as rely agents for instance.

Session getNewSession() throws InternalException;

This method creates a session that acts as the endpoint for peer communication (for a given session ID). It declares the method that works with the Request and Answer objects. A session created with this method has an autogenerated ID. It should be considered as a client session.

Session getNewSession(String sessionId) throws InternalException;

As above. However, the created session has an ID equal to that passsed as an argument. This created session should be considered a server session.

<T extends AppSession> T getNewAppSession(ApplicationId applicationId, Class<? extends AppSession> userSession) throws InternalException;

This method creates a new specific application session, identified by the application ID and class of the session passed. The session ID is generated by implementation. New application sessions should be considered as client sessions. It is safe to type cast the return value to class passed as an argument. This method delegates the call to a specific application session factory.

<T extends AppSession> T getNewAppSession(String sessionId, ApplicationId applicationId, Class<? extends AppSession> userSession) throws InternalException;

As above. However, the session Id is equal to the argument passed. New sessions should be considered server sessions.

<T extends AppSession> T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class<? extends AppSession> aClass, Object... args) throws InternalException;

As above. However, it allows the stack to pass some additional arguments. Passed values are implementation specifc.

void registerAppFacory(Class<? extends AppSession> sessionClass, IAppSessionFactory factory);

Registers the factory for a certain sessionClass. This factory will receive a delegated call when ever the getNewAppSession method is called with an application class matching one from the register method.

void unRegisterAppFacory(Class<? extends AppSession> sessionClass);

Removes the application session factory registered for the sessionClass.



RawSessions, Sessions and ApplicationSessions provide the means for dispatching and receiving messages. Specific implementation of ApplicationSession may provide non standard methods.

The RawSession and the Session life span is controlled entirely by the application. However, the ApplicationSession life time depends on the implemented state machine.

RawSession is defined as follows:

public interface BaseSession extends Wrapper, Serializable {

 
    long getCreationTime();
    long getLastAccessedTime();
    boolean isValid();
    Future<Message> send(Message message) throws InternalException, 
        IllegalDiameterStateException, RouteException, OverloadException;
    Future<Message> send(Message message, long timeOut, TimeUnit timeUnit) 
        throws InternalException, IllegalDiameterStateException, RouteException, OverloadException;
    void release();
}
public interface RawSession extends BaseSession {
    Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);
    Message createMessage(int commandCode, ApplicationId applicationId, 
        long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);
    Message createMessage(Message message, boolean copyAvps);
    void send(Message message, EventListener<Message, Message> listener) 
        throws InternalException, IllegalDiameterStateException, RouteException, OverloadException;
    void send(Message message, EventListener<Message, Message> listener,
        long timeOut, TimeUnit timeUnit) throws InternalException, 
        IllegalDiameterStateException, RouteException, OverloadException;
}
long getCreationTime();

Returns the time stamp of this session creation.

long getLastAccessedTime();

Returns the time stamp indicating the last sent or received operation.

boolean isValid();

Returns true when this session is still valid (ie, release() has not been called).

void release();

Application calls this method to inform the user that the session should free any associated resource - it shall not be used anymore.

Future<Message> send(Message message)

Sends a message in async mode. The Future reference provides the means of accessing the answer once it is received

void send(Message message, EventListener<Message, Message> listener, long timeOut, TimeUnit timeUnit)

As above. Allows to specify the time out value for send operations.

Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);

Creates a Diameter message. It should be explicitly set either as a request or answer. Passed parameters are used to build messages.

Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);

As above. However, it also allows for the Hop-by-Hop and End-to-End Identifiers in the message header to be set. This method should be used to create answers.

Message createMessage(Message message, boolean copyAvps);

Clones a message and returns the created object. The copyAvps parameter defines whether basic AVPs (Session, Route and Proxy information) should be copied to the new object.

void send(Message message, EventListener<Message, Message> listener)

Sends a message. The answer will be delivered by the specified listener

void send(Message message, EventListener<Message, Message> listener, long timeOut, TimeUnit timeUnit)

As above. It also allows for the answer to be passed after timeout.

Session defines similar methods, with exactly the same purpose:

public interface Session extends BaseSession {

    String getSessionId();
    void setRequestListener(NetworkReqListener listener);
    Request createRequest(int commandCode, ApplicationId appId, String destRealm);
    Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost);
    Request createRequest(Request prevRequest);
    void send(Message message, EventListener<Request, Answer> listener) 
        throws InternalException, IllegalDiameterStateException, RouteException, OverloadException;
    void send(Message message, EventListener<Request, Answer> listener, long timeOut,
        TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, 
        RouteException, OverloadException;
}

Validator is one of the Stack features. The primary purpose of the Validator is to detect malformed messages, such as an Answer message containing a Destination-Host Attribute Value Pair (AVP).

The Validator is capable of validating multi-leveled, grouped AVPs, excluding the following content types:

The Validator is only capable of checking structural integrity, not the content of the message.

The Validator performs the following checks:

The Validator is called by the stack implementation. It is invoked after the message is received, but before it is dispatched to a remote peer.

The Validator is configured with a single XML file. This file contains the structure definition for both messages and AVPs.

Upon creation of the Diameter Stack, the validator is initialized. It performs the initialization by looking up the dictionary.xml file in classpath.

The configuration file has the following structure:



<dictonary>
    <validator enabled="true|false" sendLevel="OFF|MESSAGE|ALL" receiveLevel="OFF|MESSAGE|ALL" />
    <vendor name="" vendor-id="" code=""/>
    <typedefn type-name="" type-parent=""/>
    <application id="" name="">
        <avp ...>
            <type type-name=""/>
            <enum name="" code=""/>
            <grouped>
                <gavp name=""/>
            <grouped/>
        <avp/>
        <command name="" code="" request="true|false"/>
        <avp ...>
            <type type-name=""/>
            <enum name="" code=""/>
            <grouped>
                <gavp name=""/>
            <grouped/>
        <avp/>
    <application>
<dictionary/>

<typedefn>

Defines the simple Attribute Value Pair (AVP) types. The element supports the following required attributes:

type-name

Specifies a type name in accordance with the acceptable base types defined in RFC 3588. For example; "Enumerated", "OctetString", "Integer32".

type-parent

Specifies the parent type name used to define the base characteristics of the type. The values are restricted to defined <typedefn> elements. For example; "OctetString", "UTF8String", "IPAddress".


<application>

Defines the specific applications used within the dictionary. Two child elements are supported by <application>: <avp> and <command>.

The <application> element supports the following attributes:

id

Specifies the unique ID allocated to the application. The attribute is used in all messages and forms part of the message header.

name

Optional attribute that specifies the logical name of the application.

uri

Optional attribute that specifies a link to additional application information.


<avp>

Element containing information necessary to configure the Attribute Value Pairs. Table 2.2, “<avp> Attributes” contains the complete list of supported attributes, and their available values (if applicable).

The <avp> element supports a number of child elements that are used to set finer parameters for the individual AVP. The supported elements are <type>, <enum>, and <grouped>.

Note

Different sets of elements are supported by <avp> depending on its position in the dictionary.xml file.


<type>

Child element of <avp> that is used to match the AVP with the AVP type as defined in the <typedefn> element. The element supports the following mandatory attribute:

type-name

Specifies the type-name of the element. This is used to match the type-name value in the <typedefn> element.

Note

<type> is ignored if the <avp> element contains the <grouped> element.

<enum>

Child element of <avp> that specifies the enumeration value for the specified AVP. <enum> is used only when the type-name attribute of <type> is specified. The element supports the following mandatory attributes:

name

Specifies the name of a constant value that applies to the AVP.

code

Specifies the integer value associated with the name of the constant. The value is passed as a value of the AVP, and maps to the name attribute.

Note

<enum> is ignored if the <avp> element contains the <grouped> element.

<grouped>

Child element of <avp> that specifies the AVP is a grouped type. A grouped AVP is one that has no <typedefn> element present. The element does not support any attributes, however the <gavp> element is allowed as a child element.

The <gavp>, which specifies a reference to a grouped AVP, supports one mandatory attribute:

name

Specifies the name of the grouped AVP member. The value must match the defined AVP name.



<command>

Specifies the command for the application. The element supports the <avp> element, which specifies the structure of the command. The element supports the following attributes:

name

Optional parameter that specifies the message name for descriptive purposes.

code

Mandatory parameter that specifies the integer code of the message.

request

Mandatory parameter that specifies whether the declared command is a request or answer. The available values are "true" (request) or "false" (answer).

Note

If the <avp> element is specified in <command>, it does not support any child elements. The <avp> element only refers to defined AVPs when used in this context.


The Validator API defines methods to access its database of AVPs and check if the AVP and message have the proper structure.

The Validator is currently message oriented. This means that it declares methods that center on message consistency checks. The class containing all validation logic is org.jdiameter.common.impl.validation.DiameterMessageValidator. It exposes the following methods:

A simple example of a Validator use case is shown below: