Platform Development Studio - Developer’s Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Annotations, EDRs, Alarms, and CDRs

The following section describe aspects and generation of EDRs, alarms, CDRs, and statistics:

 


About aspects and annotations

Aspects allow developers to manage cross-cutting concerns in their code in a straight forward and coherent way. Aspects in Oracle Communications Services Gatekeeper (pointcuts, advice, etc.) are written in the AspectJ 1.5.3 annotation style. There is already support for editing annotations in many modern IDEs, and aspects are simply set up as annotated classes.

 


How aspects are applied

All aspects are applied at build time by weaving the byte code of previously complied Java packages. Minimal reflection is used at runtime to make aspect based decisions.

Different aspect types are applicable to different Oracle Communications Services Gatekeeper modules. In general there are two categories of aspects:

Note: In this case, traffic flow is defined to include only plug-in implementations.

Traffic aspects are subdivided into two categories:

Only statistics aspects are always applied because they are used to calculate usage costs. Traffic aspects are applied to North and South boundaries of a plug-in as well as to the internal processing of the plug-in.

Annotations are used to control the aspects that are not always applied for each plug-in. These annotations are defined as part of the functional areas that a given set of aspect implements. They allow the plug-in to communicate with the aspects as well as to customize their behavior.

 


Context Aspect

The Context aspect is woven at compile time, using PluginSouth as a marker.

While requests coming from the north interface have a valid context (with attributes like Service provider account ID, application Account ID, and so on) any events triggered by the network and entering a plug-in’s south interface do not have a valid context.

The Context aspect solves this problem by rebuilding the context as soon as a south interface method is invoked: after this aspect is executed, a valid context will be available for any subsequent usages, such as the EDR aspect. All methods inside a class implementing the interface PluginSouth are woven by the Context aspect.

The Context aspect requires the following in order to correctly weave the south interface methods and be able to rebuild the context:

The following rules apply for methods in classes that implement PluginNorth:

The following rule applies for methods in classes that implement PluginSouth:

The ways of doing this are plug-in-specific, but normally a network triggered request is tied to an application instance in a store that is managed by the plug-in. The store used for context mapping may be a local cache or a cluster wide store, depending on whether responses are known to always arrive on the same plug-in instance, or if they can arrive at a plug-in on another server in the cluster.

Example:

  1. An application sends a request to the network and an ID for this request is either supplied by the network or generated by the plug-in. At this point the originator of the requests, the application instance, is known since the request originated from an application.
  2. The plug-in puts the application instance ID and the ID for the request into a store.
  3. At a later stage, when a response to the original requests arrives at the plug-in, the method resolveAppInstanceGroupId() is called by aspects.
  4. In this method, the plug-in must perform a lookup in the store of the application instance related to that request and return the application instance ID to the aspect.
  5. The aspect authenticates the application instance with the container and puts the application instance ID in the RequestContext.
  6. The method in the plug-in receives the request from the network and the RequestContext contains the application instance ID.

In the example below the method deliver(...) is a request from the underlying network. The destinationAddress is annotated to be available to the aspect that handles network-triggered requests associated with this request, represented by constant C.

NotificationHandler handles the store for notifications and supplies all necessary parameters to the store.

Listing 9-1 Application initiated request
protected static final String C = "destinationAddress";
@Edr
  public void deliver(String data,
                      @ContextKey(EdrConstants.FIELD_DESTINATION_ADDRESS)
                      @MapperInfo(C) String destinationAddress,
                      @ContextKey(EdrConstants.FIELD_ORIGINATING_ADDRESS) String originatingAddress,
                      String nwTransactionId)
    throws Exception {
    notificationHandler.deliver(data, destinationAddress, originatingAddress, nwTransactionId);
  }

When a network triggered event occurs, the aspect calls resolveApplicationInstanceGroup(...) in PluginSouth and the plug-in looks up the application instance using any argument available in ContextMapperInfo that can help the plug-in to resolve this ID from ContextMapperInfo, using info.getArgument(C). The application instance ID is returned to the aspect and the execution flow continues in the plug-in, with a RequestContext that contains the application instance ID, session ID and so on.

Listing 9-2 Rebuilding RequestContext
protected static final String C = "destinationAddress";
public String resolveAppInstanceGroupdId(ContextMapperInfo info) {
    String destinationAddress = (String) info.getArgument(C);
    NotificationData notificationData = null;
    try {
      notificationData = StoreHelper.getInstance().getNotificationData(destinationAddress);
    } catch (StorageException e) {
       return null;
    }
    if (notificationData == null) {
      return null;
    }
    return notificationData.getAppInstanceGroupId();
  }

Below are the steps you have to take to make your plug-in compliant with the Context aspect:

 


EDR Generation

EDRs are generated in the two following ways:

EDRs should be generated at the plug-in boundaries (north and south), using the @Edr annotation to ensure that the boundaries are covered. Additional Edrs can be added elsewhere in the plug-in if needed: for example for CDRs.

For extensions, the EDR ID should be in the range 500 000 to 999 999.

EDRs are generated automatically by an aspect in the following locations in the plug-in:

Note: Note that aspects are not applied outside the plug-in.
Table 9-1 Manual annotation for EDRs
Trigger
When
Modifiers restrictions
What is woven
method
before executing
public method only
only in methods annotated with @Edr
method
after executing
public method only
only in methods annotated with @Edr
method-call
before calling
any method
only for method call to a class implementing the PluginNorthCallback interface (EJB callback)
method-call
after calling
any method
only for method call to a class implementing the PluginNorthCallback interface (EJB callback)
exception
after throwing
any method
any exception thrown except in methods annotated with @NoEdr

The following values are always available in an EDR when it is generated from an aspect:

Exception scenarios

Exceptions are automatically woven by the aspect.

Some limitations apply:

The diagram illustrates typical scenarios when a library (or core service) throws an exception in the plug-in.

Figure 9-1 Exception scenarios

Exception scenarios

Scenario 1:

The plug-in method in Stage 2 simply catches the exception but does not re-throw it or throw another exception. Since it just consume the exception, the aspect will not trigger an EDR.

Scenario 2:

The plug-in method in Stage 2 lets the exception A propagate (or re-throws exception A).

In this case, the aspect triggers an EDR after the method in stage 2. Since the same exception A (the same exception instance object) is propagated (or re-thrown), only the first method triggers an EDR.

Scenario 3:

This scenario is almost identical to scenario 2 except that the method in stage 1 is not throwing the exception A but another exception, named B. In this case, because B is not the same instance as A, the aspect will trigger another EDR after the method in stage 1.

Adding data to the RequestContext

In addition to the default values, an EDR also contains all the values put into the RequestContext using the putEdr() method.

Listing 9-3 Example to add values to and EDR using RequestContex
...
RequestContext ctx = RequestContextManager.getCurrent();
// this value will be part of any EDRs generated in the current request
ctx.putEdr("address", "tel:1234"); 
// this value will NOT be part of any EDRs since ctx.put(...) is used
ctx.put("foo", "bar");
...
Note: Common key names are defined in the class com.bea.wlcp.wlng.api.edr.EdrConstants.

Using translators

When a parameter is a more complex object, it is possible to specify a translator that will take care of extracting the relevant information from this parameter.

The annotation is @ContextTranslate.

For example, the following method declares:

The Translator is a class implementing the ContextTranslator interface.

Listing 9-5 Example of a Translator
  public class ACContextTranslator implements ContextTranslator {
    public void translate(Object param, ContextInfo info) {
      if(param instanceof PlayTextMessage) {
        PlayTextMessage msg = (PlayTextMessage) param;
        info.put("address", msg.getAddress().toString());
      } else if(param instanceof PlayTextMessageResponse) {
        PlayTextMessageResponse response = (PlayTextMessageResponse) param;
        info.put("correlator", response.getResult());
      } ...
    }
  }

The ContextTranslator class specified in the @ContextTranslate annotation is automatically instantiated by the aspect when needed. It is however possible to explicitly register it using the ContextTranslatorManager.

Listing 9-6 Example of registering a context translator
ContextTranslatorManager.register(ACContextTranslator.class.getName(), new ACContextTranslator());

Below is a summary of annotations to use.

Table 9-2 Annotations
Name
Type
Description
@ContextKey
Annotation
Specifies that an argument must be put into the current RequestContext under the name provided in this annotation
@ContextTranslate
Annotation
Same as @ContextKey but for complex argument that need to be translated using a translator (implementing the ContextTranslator interface).
ContextTranslator
Interface
Interface used by static translators to translate complex object.

Trigger an EDR programmatically

Oracle Communications Services Gatekeeper triggers EDRs automatically in all plug-ins where aspects have been applied. It is also possible to trigger EDRs explicitly. In this case, you will have to manually create and trigger the EDR by following these steps:

  1. Create an EdrData object
  2. Trigger the EDR using the EdrService instance

Below is an example of triggering an EDR from inside a plug-in.

Listing 9-7 Trigger an EDR programmatically
public class SamplePlugin {
   // Get the EdrDataHelper like a logger
   private static final EdrDataHelper helper = EdrDataHelper.getHelper(SamplePlugin.class);
   public void doSomething() {
      ...
      // Create a new EdrData using the EdrDataHelper class to allow 
      // Services Gatekeeper to automatically populate some fields
      EdrData data = helper.createData();
      // Since we are creating the EdrData manually, 
      // we have to provide the mandatory fields.
      // Note that the EdrDataHelper will provide most of them
      data.setValue(EdrConstants.FIELD_SOURCE, EdrConstants.VALUE_SOURCE_METHOD);
      data.setValue(EdrConstants.FIELD_METHOD_NAME, "doSomething");
      // Log the EDR
      EdrServiceFactory.getService().logEdr(data);
      ...
   }
}

EDR Content

The following table describes the content of an EDR. It describes which values are mandatory, who is responsible for providing these values, and other information.

Legends:

Note: EDRs triggered by aspects will have all the mandatory fields provided by the aspect.

Table 9-3 EDR content
Name
Description
Filter tag name
EdrId
To get the ID, use getIdentifier() in EdrConfigDescriptor.
This value is provided in the EDR descriptor.
Provider INSIDE plug-in: X
Provider OUTSIDE plug-in: X
Mandatory: Yes
C
ServiceName
The name (or type) of the service.
Fields in EdrConstants: FIELD_SERVICE_NAME
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: M
Mandatory: Yes
C
ServerName
The name of the Oracle Communications Services Gatekeeper server.
Fields in EdrConstants: FIELD_SERVER_NAME
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: H
Mandatory: Yes
C
Timestamp
The time at which the EDR was triggered (in ms since midnight, January 1, 1970 UTC)
Fields in EdrConstants: FIELD_TIMESTAMP
Provider INSIDE plug-in: A
Provider OUTSIDE plug-in: A
Mandatory: Yes
C
ContainerTransactionId
The WebLogic Server transaction ID, if available.
Fields in EdrConstants: FIELD_CONTAINER_TRANSACTION_ID
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: H
Mandatory: No
C
Class
Name of the class that triggered the EDR.
Fields in EdrConstants: FIELD_CLASS_NAME
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: H
Mandatory: Yes
<class>
Method
Name of the method that triggered the EDR.
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: Yes
<name> inside <method> or <method> inside <exception>
Source
Indicates the type of source that triggered the EDR.
Fields in EdrConstants: FIELD_SOURCE
Values in EdrConstants: VALUE_SOURCE_METHOD, VALUE_SOURCE_EXCEPTION
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: Yes
<method> or <exception>
Direction
Direction of the request.
Fields in EdrConstants: FIELD_DIRECTION
Values in EdrConstants:VALUE_DIRECTION_SOUTH, VALUE_DIRECTION_NORTH
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: No
<direction>
Position
Position of the EDR relative to the method that triggered the EDR.
Fields in EdrConstants: FIELD_POSITION
Values in EdrConstants: VALUE_POSITION_BEFORE, VALUE_POSITION_AFTER
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: No
<position>
Interface
Interface where the EDR is triggered.
Fields in EdrConstants: FIELD_INTERFACE
Values in EdrConstants: VALUE_INTERFACE_NORTH, VALUE_INTERFACE_SOUTH, VALUE_INTERFACE_OTHER
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: No
<interface>
Exception
Name of the exception that triggered the EDR.
Fields in EdrConstants: FIELD_EXCEPTION_NAME
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: No
<name> inside <exception>
SessionId
Session ID.
Fields in EdrConstants: FIELD_SESSION_ID
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: M
Mandatory: No
C
ServiceProviderId
Service provider account ID.
Fields in EdrConstants: FIELD_SP_ACCOUNT_ID
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: M
Mandatory: No
C
ApplicationId
Application account ID.
Fields in EdrConstants: FIELD_APP_ACCOUNT_ID
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: M
Mandatory: No
C
AppInstanceGroupId
Application instance ID.
Fields in EdrConstants: FIELD_APP_INSTANCE_GROUP_ID
Provider INSIDE plug-in: H
Provider OUTSIDE plug-in: M
Mandatory: No.
C
OrigAddress
The originating address with scheme included (for example “tel:1234”).
Fields in EdrConstants: FIELD_ORIGINATING_ADDRESS
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: No
C
DestAddress
The destination address(es) with scheme included (For example “tel:1234”). See Using send lists.
Fields in EdrConstants: FIELD_DESTINATION_ADDRESS
Provider INSIDE plug-in: M
Provider OUTSIDE plug-in: M
Mandatory: No
C
<custom>
Any additional information put into the current RequestContext using the putEdr() API will end up in the EDR.
Fields in EdrConstants: -
Provider INSIDE plug-in: -
Provider OUTSIDE plug-in: -
Mandatory: No
C

Using send lists

If more than one address needs to be stored in the DestAddress field, use the following pattern. Both patterns described below can be used.

Listing 9-8 Pattern to store one single or multiple addresses in field destination directly on EdrData.
EdrData data = ...;
// If there is only one address
data.setValue(EdrConstants.FIELD_DESTINATION_ADDRESS, address);
// If there are multiple addresses
data.setValues(EdrConstants.FIELD_DESTINATION_ADDRESS, addresses);

If you are using the current RequestContext object, simply store a List of addresses. The EdrDataHelper will automatically take care of converting this to a List of Strings in the EdrData.

Listing 9-9 Pattern to store one single or multiple addresses in field destination using RequestContext.
RequestContext ctx = RequestContextManager.getCurrent();
// If there is only one address
ctx.putEdr(EdrConstants.FIELD_DESTINATION_ADDRESS, address);
// If there are multiple addresses
URI[] addresses = ...;
ctx.putEdr(EdrConstants.FIELD_DESTINATION_ADDRESS, Arrays.asList(addresses));

RequestContext and EDR

The following diagram shows how and where information for the EDR is added to the RequestContext and how it finally ends up in the additional info column of the alarm and CDR databases.

Figure 9-2 RequestContext and EDR

RequestContext and EDR

There are 3 ways of putting information in the RequestContext that will end up in the EDR (more precisely in the EdrData object):

When an EDR is created, the EdrDataHelper (which is the recommended way to create the EDR) will populate the EdrData with all the key/value pairs found in the RequestContext.

When the EdrService writes the alarm or CDR additional information content into the database, it will use all the EdrData key/value pairs EXCEPT a set of well-known keys that are either not relevant or already included in other columns of the database, see Alarm content and CDR content.

 


Categorizing EDRs

Only one type of EDR exists: alarms and CDRs are subsets of this EDR type. In order to categorize the flow of EDRs as either pure EDRS, alarms or CDRs, the EDR service uses 3 descriptors:

These XML descriptors can be manipulated using the EDR Configuration Pane as described in Managing and Configuring EDRs, CDRs and Alarms in the System Administrator’s Guide. File representations of these must be included in edrjmslistener.jar if you are using external EDR listeners.

The EDR descriptor

Each descriptor contains a list of EDR descriptors that define an EDR as a pure-EDR, as an alarm or as a CDR.

Table 9-4 EDR descriptors.
Descriptor
Descriptor
Description
EDR
<edr...>
Defines which EDRs are pure EDRs
Alarm
<alarm...>
Defines which EDRs are alarms
CDR
<cdr...>
Defines which EDRs are CDRs

The descriptor is composed of two parts:

Table 9-5 describes the elements allowed in the <filter> part:

Table 9-5 Elements allowed in <filter> part of an EDR descriptor.
Source
Filter
Min occurs
Max occurs
Description
<method>
 
0
unbounded
Filter EDR triggered by a method
 
<name>
0
unbounded
Name of the method that triggered the EDR
 
<class>
0
unbounded
Name of the class that triggered the EDR
 
<direction>
0
2
Direction of the request
 
<interface>
0
3
Interface where the EDR has been triggered
 
<position>
0
2
Position relative to the method that triggered the EDR
<exception>
 
0
unbounded
Filter EDR triggered by an exception
 
<name>
0
unbounded
Name of the exception that triggered the EDR
 
<class>
0
unbounded
Name of the class where the exception was thrown
 
<method>
0
unbounded
Name of the method where the exception was thrown
 
<direction>
0
2
Direction of the request
 
<interface>
0
3
Interface where the EDR has been triggered
 
<position>
0
2
Position relative to the method that triggered the EDR
<attribute>
 
0
unbounded
Filter EDR by looking at custom attribute
 
<key>
1
1
Name of the key
 
<value>
1
1
Value

Table 9-6 describes the values allowed for each element of the <filter> part:

Table 9-6 Values allowed in each element of the <filter> part.
Source
Filter
Allowed values
Comment
<method>
<name>
“returntype nameofmethod([args])”
Method name. The arguments can be omitted with the parenthesis. See Special characters below.
 
<class>
“fullnameofclass”
Fully qualified class name. See Special characters below.
 
<direction>
“south”, “north”
 
 
<interface>
“north”, “south”, “other”
 
 
<position>
“before”, “after”
 
<exception>
<name>
“fullnameofexceptionclass”
Fully qualified exception class name. See Special characters below.
 
<class>
“fullnameofclass”
Fully qualified class name where the exception was triggered. See Special characters below.
 
<method>
“returntype nameofmethod([args])”
Method name. The arguments can be omitted with the parenthesis See Special characters below.
 
<direction>
“south”, “north”
 
 
<interface>
“north”, “south”, “other”
 
 
<position>
“before”, “after”
 
<attribute>
<key>
“astring”
 
 
<value>
“astring”
 

Special characters

The filter uses special characters to indicate more precisely how to match certain values.

Using * at the end of a method, class or exception name matches all names that match the string specified prior to the * (that is, what the string starts with).

Note: The usage of any of these characters disables the caching of the filter containing them. To avoid a performance hit, using the other way of matching is strongly encouraged.

Table 9-7 Example filters
To match on
Use the filter

All sendInfoRes methods with one argument of type int.

<method>
<name>void sendInfoRes(int)</name>
...
</method>

All methods starting with sendInfoRes regardless of the arguments.

<method>
<name>void sendInfoRes</name>
...
</method>
All methods starting with void sendInfo.
<method>
<name>void sendInfo*</name>
...
</method>
All class names beginning with com.bea.wlcp.wlng.plugin
<method>
<class>com.bea.wlcp.wlng.plugin*</class>
...
</method>

Values provided

The exact value in these fields depends on who triggered the EDR. If the aspect triggered the EDR, then the name of the method (with return type and parameters) or the fully qualified name of the class/exception is indicated. If the EDR is manually triggered from the code, it is up to the implementer to decide what name to use. Here are some examples of fully qualified method/class names as specified by the aspect:

Example methods:

SendSmsResponse sendSms(SendSms)
void receivedMobileOriginatedSMS(NotificationInfo, boolean, SmsMessageState, String, SmsNotificationRemote)
TpAppMultiPartyCallBack reportNotification(TpMultiPartyCallIdentifier, TpCallLegIdentifier[], TpCallNotificationInfo, int)

Example Class:

com.bea.wlcp.wlng.plugin.sms.smpp.SMPPManagedPluginImpl

Boolean semantic of the filters

The following diagram shows briefly how the filter works:

Example filters

Example 1: filter

Listing 9-10 categorizes EDRs as pure EDRs with an id of 1000 when the following conditions are met:

Example 2: Alarm filter

Listing 9-11categorizes EDRs as alarms when the following conditions are met:

The alarms descriptor has a <alarm-group> element that is used to group alarms by service/source: this group id and each individual alarm id is used to generate the OID of SNMP traps.

Listing 9-11 Example 2: filter
<alarm-group id="104" name="parlayX" description="Parlay X alarms">>
<alarm id="1000" severity="minor" description="Parlay X exception">
    <filter>
      <exception>
        <name>com.bea.wlcp.wlng.plugin.PluginException</name>
        <name>org.csapi*</name>
      </exception>
    </filter>
  </alarm>
</alarm-group>
Example 3: Alarm filter

Listing 9-12 categorizes EDRs as alarms when the following conditions are met:

If the filter determines that the EDR is an alarm, the following attributes are available to the alarm listener (they are defined in the <data> part):

Example 4: filter

Listing 9-13 (for example purposes only) categorizes EDRs as pure EDRs with the id 1002 when the following conditions are met:

Example 5: filter with corresponding code for manually triggering a matching EDR

Listing 9-14 shows a manually triggered EDR with its corresponding filter. The EDR is triggered using these lines.

Listing 9-14 Example 5: Trigger the EDR
  // Declare the EdrDataHelper for each class 
  private static final EdrDataHelper helper = EdrDataHelper.getHelper(MyClass.class);
  public void myMethodName() {
    ...
    // Create a new EdrData. Use the EdrDataHelper class to allow Services Gatekeeper to automatically populate some fields
    EdrData data = helper.createData();
        	
    // Because we are creating the EdrData manually, we have to provide the mandatory fields 
    data.setValue(EdrConstants.FIELD_SOURCE, EdrConstants.VALUE_SOURCE_METHOD);
    data.setValue(EdrConstants.FIELD_METHOD_NAME, "myMethodName");
    data.setValue("myKey", "myValue");
  
    // Log the EDR
    EdrServiceFactory.getService().logEdr(data);
    ...
  }

This EDR can be filtered using Listing 9-15 (note the various ways of identifying this EDR):

Listing 9-15 Example: Filter 5
  <edr id="1003">
    <filter>
      <!-- Match both method name and class name -->
      <method>
        <name>myMethodName</name>
        <class>com.bea.wlcp.wlng.myClassName</class>
      </method>
      <!-- OR match only the method name (looser than matching also the class name) -->
      <method>
        <name>myMethodName</name>
      </method>
      <!-- OR match only the classname (looser than matching also the method name) -->
      <method>
        <class>com.bea.wlcp.wlng.myClassName</class>
      </method>
      <!-- OR match only the custom attribute -->
      <attribute key="myKey" value="myValue"/>
    </filter>
  </edr>

 


Check-list for EDR generation

Below is a list of steps to take to make your plug-in able to use aspect EDRs:

 


Frequently Asked Questions about EDRs and EDR filters

Question: Is it possible to specify both exception and method name in the filter section?

Listing 9-16 Example: method name and exception in a filter.
<filter>
      <method>
        <name>internalSendSms</name>
      </method>
      <exception>
        <name>com.bea.wlcp.wlng.plugin.sms.smpp.TooManyAddressesException</name>
      </exception>
    </filter>

Answer

Yes, make sure that the <method> element is before the <exception> element. Otherwise the XSD will complain.

Q: Is it possible to specify multiple method names?

Answer

Yes.

Q: In some places I have methods re-throwing an exception. Is it possible to have only one of the methods generate the EDR and map that edr to an alarm?

Listing 9-17 Re-throwing an exception
myMethodA()throws MyException{
  myMethodB();
}
myMethodB()throws MyException{
  myMethodC();
}
myMethodC()throws MyException{
  ...
  //on error
 throw new MyException(“Exception text..”);
}

Answer

In this case, only the first exception will be caught by aspects. Or more precisely, they will all be caught by aspects but will only trigger an EDR for the first one, but not for the re-thrown ones (if they are the same, of course). So you don’t need to use the @NoEdr annotation for myMethodA and myMethodB.

Q: Will aspects detect the following exception?

Listing 9-18 Example exception
    try{
      throw new ReceiverConnectionFailureException(message);
    }catch(ReceiverConnectionFailureException connfail){
      //EDR-ALARM-MAPPING
    }

Answer

This exception will NOT be detected by aspects. If you need to generate an EDR you will have to either manually create an EDR or call a method throwing an exception.

Q: Will EDRs for exceptions also work for private methods?

Answer

Yes, EDRs can work for any method.

Q: Will exceptions be disabled with the @NoEdr annotation?

Answer

Yes, with the @NoEdr annotation you will not get any EDRs, not even for exceptions.

Q: How can data from the current context be included in an alarm?

For example, can an alarm be generated in a request with more than 12 destination addresses? How can information about how many addresses were included in the request be added to the alarm

It is possible to specify some info in the alarm descriptor with something like

<data>
      <attribute key="source" value="thesource"/>
</data>

Can something be put in the RequestContext using the putEdr method and then get it into the alarm in some way?

Answer

Yes, add custom information by putting this information into the current RequestContext, as show below.

RequestContext ctx = RequestContextManager.getCurrent();
ctx.putEdr("address", "tel:1234"); 

This value is part of any EDRs generated in the current request.

The information will be available in the database in the additional_info column. Make sure you are putting in only relevant information.

Q: Is it possible to specify classname in the filtering section?

Answer

Yes, use the <class> tag inside <method> or <exception> in the filter.

 <filter>
      <exception>
        <class>com.y.y.z.MyClass</class>
        <name>com.x.y.z.MyException</name>
      </exception>
</filter>

 


Alarm generation

An alarm is a subset of an EDR. To generate an alarm, generate an EDR, either using one generated in aspects or programmatically, and define the ID and the descriptor of the alarm in the alarm descriptor.

The alarm ID, severity, description and other kind of attributes are defined in the alarm descriptor, see The EDR descriptor. For extensions, the alarm ID shall be in the range 500 000 to 999 999.

Note: The alarm filter that provides the first match in the alarm descriptor is used for triggering the alarm.

There are two ways to trigger an alarm:

Trigger an alarm programmatically

Trigger an EDR as described in EDR Content. Then specify in the alarm descriptor the corresponding alarms.

Listing 9-19 Example code to trigger an alarm
private static final EdrDataHelper helper = EdrDataHelper.getHelper(MyClass.class);
...
EdrData data = helper.createData();
data.setValue(EdrConstants.FIELD_SOURCE, EdrConstants.VALUE_SOURCE_METHOD);
data.setValue(EdrConstants.FIELD_METHOD_NAME, "com.bea.wlcp.wlng.myMethod");
data.setValue("myAdditionalInformation", ...);
EdrServiceFactory.getService().logEdr(data);
...

The corresponding entry in the alarm descriptor that matches this EDR is shown below.

Listing 9-20 Alarm descriptor
  <alarm id="2006"
         severity="major"
         description="Sample alarm">
    <filter>
      <method>
        <name>com.bea.wlcp.wlng.myMethod</name>
        <class>com.bea.wlcp.wlng.myClass</class>
      </method>
    </filter>
  </alarm>

Alarm content

Below is a list of the information provided in alarms.

Table 9-8 Alarm information for alarm listeners, also stored in DB
Field
Comment
alarm_id
Unique ID for the alarm.
Automatically provided by the EdrService.
source
Service name emitting the alarm.
Automatically provided by the EdrService.
timestamp
Timestamp in milliseconds since midnight, January 1, 1970 UTC.
Automatically provided by the EdrService.
severity
Severity level.
Defined in the alarm. descriptor.
identifier
The alarm identifier.
Defined in the alarm descriptor.
The column in the database will always contain the identifier defined in the alarm descriptor.
alarm_info
The alarm information or description.
Defined in the alarm descriptor.
additional_info
Automatically provided by the EdrService.
Not valid for backwards compatible alarm listeners.
Each entry is formatted as:
key=value\n
Similar to the Java properties file.
All the custom key/value pairs found in the EdrData except these are present (EdrConstants if not specified):
  • FIELD_TIMESTAMP
  • FIELD_SERVICE_NAME
  • FIELD_CLASS_NAME
  • FIELD_METHOD_NAME
  • FIELD_SOURCE
  • FIELD_DIRECTION
  • FIELD_POSITION
  • FIELD_INTERFACE
  • FIELD_EXCEPTION_NAME
  • FIELD_ORIGINATING_ADDRESS
  • FIELD_DESTINATION_ADDRESS
  • FIELD_CONTAINER_TRANSACTION_ID
  • FIELD_CORRELATOR
  • FIELD_SESSION_ID
  • FIELD_SERVER_NAME
  • ExternalInvocatorFactory.SERVICE_CORRELATION_ID
  • FIELD_BC_EDR_ID
  • FIELD_BC_EDR_ID_3
  • FIELD_BC_ALARM_IDENTIFIER
  • FIELD_BC_ALARM_INFO

 


CDR generation

A CDR is a subset of an EDR. To generate a CDR, generate an EDR and define the ID of the EDR in the CDR descriptor.

Triggering a CDR

There are two ways to trigger a CDR:

Trigger a CDR programmatically

If none of the existing EDRs is appropriate for a CDR, you can programmatically trigger an EDR that will become a CDR. See the section, Trigger an EDR programmatically for information on how to create and trigger an EDR. Specify in the CDR descriptor the description necessary for this EDR to be considered a CDR.

Listing 9-21 Example, triggering a CDR
private static final EdrDataHelper helper = EdrDataHelper.getHelper(MyClass.class);
...
EdrData data = helper .createData();
data.setValue(EdrConstants.FIELD_SOURCE, EdrConstants.VALUE_SOURCE_METHOD);
data.setValue(EdrConstants.FIELD_METHOD_NAME, "com.bea.wlcp.wlng.myEndOfRequestMethod");
// Fill the required fields for a CDR
data.setValue(EdrConstants.FIELD_CDR_START_OF_USAGE, ...);
...
EdrServiceFactory.getService().logEdr(data);
...

The description, in the CDR descriptor, that matches this EDR is shown in Listing 9-22.

Listing 9-22 Filter to match the EDR
<cdr>
    <filter>
      <method>
        <name>com.bea.wlcp.wlng.myEndOfRequestMethod</name>
        <class>com.bea.wlcp.wlng.myClass</class>
      </method>
    </filter>
</cdr>

CDR content

In addition to the EDR fields, there are specific fields used only for CDRs. They are listed in Table 9-9.

Table 9-9 Fields in EdrConstants specific for CDRs.
Field in EdrConstants
Comment
FIELD_CDR_SESSION_ID
 
FIELD_CDR_START_OF_USAGE
 
FIELD_CDR_CONNECT_TIME
 
FIELD_CDR_END_OF_USAGE
 
FIELD_CDR_DURATION_OF_USAGE
 
FIELD_CDR_AMOUNT_OF_USAGE
 
FIELD_CDR_ORIGINATING_PARTY
 
FIELD_CDR_DESTINATION_PARTY
Same pattern applies as for send lists, see Using send lists.
FIELD_CDR_CHARGING_INFO
 

The structure of the CDR content is aligned toward the 3GPP Charging Applications specifications. As a result the database schema has been changed to accommodate these ends and to facilitate future extensions.

Legends:

Additional_info column

The EDR populates the additional_info column of the DB with all the custom key/value pairs found in the EdrData except the ones listed below.

Excluded keys (EdrConstants if not specified):

Two keys not present in the EdrData are added to additional_info.

Table 9-11 Keys not present in EdrData, but added in additional_info
Key
Description
destinationParty
If a send list is specified as the destination party, the first address will be written in the destination_party field of the DB and the remainder of the list will be written under this key name
oldInfo
Any backwards compatible additional info is available

The format of the additional_info field is formatted as:

key=value\n

similar to the Java properties file.

Out-of-the box (OOTB) CDR support

It is difficult to come up with a CDR generation scheme that fulfills the requirements of all customers. Oracle Communications Services Gatekeeper generates a default set of CDRs which can be customized by re-configuring the CDR descriptor.

The guiding principle for deciding when to generate CDRs is:

In other words, after the last method, in a potential sequence of method calls, returns.

For network-triggered requests this means that you should a trigger a CDR at the south interface after the method has returned back to the network. For application-triggered requests generate a CDR at the north interface after the method has returned to the Network Tier SLSB.


  Back to Top       Previous  Next