8 Extending UIM Through Rulesets

This chapter provides information about extending Oracle Communications Unified Inventory Management (UIM) by using rulesets.

About Using Rulesets to Extend UIM

A ruleset is a file containing custom code that extends existing UIM code at a specified point. The UIM extensibility framework supports the use of rulesets and is built upon the open source project of AspectJ. Ruleset code is written using either Drools or Groovy, both of which are also open source projects.

AspectJ is an Eclipse open source project that enables aspect-oriented programming (AOP). AOP provides the ability to insert code at various points across a code base. For example, when UIM is started, the AspectJ engine weaves (interlaces) custom extension points into the UIM code stream. The AspectJ engine is called the Weaver.

Drools and Groovy are open source projects that enable accessing, changing, and managing business rules. Both enable you to view business rules because they are completely decoupled from the code. This allows for greater flexibility in changing, adding, or removing rules as business needs change.

About Rules

Rules are written using either Drools or Groovy. A ruleset contains one or more rules. The following sections describe rules in terms of Drools and Groovy.

Using Drools to Define Rules

A Drools rule is a two-part structure that defines a condition and an action. When the condition evaluates to true, the action occurs. While the entire rule is custom code, the action is the business-specific custom code. This chapter uses the term custom code to refer to the business-specific custom code.

Example 8-1 shows the structure of a Drools rule:

Example 8-1 Structure of a Drools Rule

rule "RuleName"
    salience 0
when
    condition
then
    action
end

Note:

You do not need to specify a condition in the rule. If no condition is specified, the condition is assumed to be true and the action occurs.

The custom code may reside:

  • In the action

  • In a function within the ruleset that the action calls

  • In a separate Java class that the action calls

If the custom code is short and simple, you can place it in the action, or within a function in the ruleset. If the custom code is even slightly complex, Oracle recommends that you place it in a separate Java class. The advantage of placing custom code in a separate Java class is that you can use the use of the Java features. For example, the Java editor catches syntax errors, creates import statements, and provides a list of method names when you type a class name.

Note:

A ruleset always runs, but this does not mean that the custom code always runs. Whether or not the custom code runs depends on the outcome of the rule conditions.

A rule can optionally define soft keywords, one of which is salience. Example 8-1 includes the salience soft keyword, which is commonly used.

Salience defines the priority of when a rule runs, which is necessary when multiple rules run at the same time. Salience is a numeric value that defaults to zero; the higher the number, the higher the priority. The rule with the highest priority runs first.

For more information about soft keywords, see the topic of keywords on the Drools Documentation website:

http://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html_single/

Using Groovy to Define Rules

Unlike Drools rules that define a condition and an action, a Groovy rule defines only an action (the business-specific custom code). You define Groovy rules in Groovy scripts.

Example 8-2 shows the structure of a Groovy script:

Example 8-2 Structure of a Groovy Script

def x = "World"println "Hello, $x"
if (condition) action
 

The custom code may reside:

  • In the rule (action)

  • In a function within the ruleset that the rule (action) calls

  • In a separate Groovy script that the rule (action) calls

If the custom code is short and simple, you can place it in the rule, or within a function in the ruleset. If the custom code is even slightly complex, Oracle recommends that you place it in a separate Groovy script. The advantage of placing custom code in a separate Groovy script is having the full use of the Eclipse debugging functionality. For example, the debugger may not stop on a breakpoint in the rule Groovy code itself, but will stop on a breakpoint within a Groovy script that the parent script calls. See "Debugging Custom Groovy Rulesets" for more information.

About Rulesets and Extension Points

A ruleset is a file that contains one or more rules. UIM provides several base rulesets in the ora_uim_baserulesets cartridge and also provides a framework that enables you to create custom rulesets. Each base ruleset provides a Drools version and a Groovy version of the ruleset. See "About Base Rulesets" for more information.

In addition to rules, a ruleset may also contain:

  • A package statement

  • Import statements

  • Global and local variables

  • Functions (similar to Java methods)

The content of a ruleset file is similar to the content of a Java source file (.java), but a ruleset is either a Drools file (.drl) or a Groovy file (.groovy).

Example 8-3 shows a ruleset that contains a package statement, import statements, a global variable, a function, and a Drools rule. Within a ruleset, functions must be defined prior to the rule so the rule can recognize the function when compiling. When a ruleset runs, execution begins at the rule; it does not begin at any functions that may be defined prior to the rule.

Example 8-3 Drools Ruleset

package oracle.communications.inventory.rules
 
import oracle.communications.inventory.api.entity.TelephoneNumberSpecification;
import oracle.communications.inventory.extensibility.extension.util.
ExtensionPointRuleContext;
import oracle.communications.inventory.api.framework.logging.Log;
 
global Log log;
 
//--------------------------------------------------------------------
// FUNCTIONS
//--------------------------------------------------------------------
function String getEditMask(TelephoneNumberSpecification tnSpec) 
{
    // Set the default edit mask.
    String editMask = "##########";
    if ( tnSpec == null )
        return editMask;
     
    // Set the edit mask based on specification name
    if(tnSpec.getName().equals("US TN Spec NPA-NXX"))
        editMask = "###-###-####";
    return editMask;
}
 
//--------------------------------------------------------------------
// RULES
//--------------------------------------------------------------------
rule "Get TN Edit Mask"
    salience 0
        when
            telephoneNumberSpecification : TelephoneNumberSpecification()
            context : ExtensionPointRuleContext()
        then
            String editMask = getEditMask(telephoneNumberSpecification);
            context.setReturnValue(editMask);  
end

Example 8-4 shows a ruleset that contains a package statement, import statements, a global variable, a function, and a Groovy rule. Example 8-3 and Example 8-4 provide the same functional result, but one was written using Drools and the other using Groovy.

Example 8-4 Groovy Ruleset

package oracle.communications.inventory.rules
 
import oracle.communications.inventory.api.entity.TelephoneNumberSpecification;
import oracle.communications.inventory.extensibility.extension.util.
ExtensionPointRuleContext;
import oracle.communications.inventory.api.framework.logging.Log;
 
global Log log;
 
//--------------------------------------------------------------------
// RULE CODE
//--------------------------------------------------------------------
String editMask = getEditMask(telephoneNumberSpecification);
context.setReturnValue(editMask);  
 
//--------------------------------------------------------------------
// FUNCTION
//--------------------------------------------------------------------
def String getEditMask(TelephoneNumberSpecification tnSpec)
{
    // Set the default edit mask.
    String editMask = "##########";
    if ( tnSpec == null )
        return editMask;
     
    // Set the edit mask based on specification name
    if(tnSpec.getName().equals("US TN Spec NPA-NXX"))
        editMask = "###-###-####";
    return editMask;
}

Rulesets enable you to run custom code that extends UIM code at specified points called extension points.

Rulesets:

  • Use Drools or Groovy rules and are enabled by AspectJ

  • Functionally extend UIM through custom code

  • Dynamically extend UIM through additions, changes, or deletions to rulesets without rebuilding or restarting UIM

  • Are provided in the ora_uim_baserulesets cartridge (base rulesets)

  • Can be created in Oracle Communications Design Studio within an Inventory project (custom rulesets)

  • Are deployed into UIM as part of a cartridge

To understand how custom rulesets work, you must understand the following concepts:

Extension Points

An extension point defines a UIM API method signature to establish a specific point in the code at which to call a ruleset. UIM provides several base extension points in the ora_uim_baseextpts cartridge and also provides a framework that enables you to create custom extension points.

Custom extension points are created in Design Studio in the Extension Point editor and in a corresponding custom aop.xml file. See "Creating Extension Points" for more information.

An extension point is defined as specification-based or global, based on the Design Studio Extension Point editor Global check box. If the Global check box is not selected, the extension point is specification-based. If the Global check box is selected, the extension point is global.

Specification-based extension points pertain to a particular specification, and global extension points do not.

Specification-Based Extension Points

The signature argument for specification-based extension points must define a specific UIM entity object, such as TelephoneNumber, Equipment, or Pipe, or define a generic object, such as a java.util.Collection that can contain specific UIM entity objects. For example, the TelephoneNumberManager_createTelephoneNumbers base extension point defines the following signature:

public abstract interface java.util.List oracle.communications.inventory.api.number.TelephoneNumberManager.
createTelephoneNumbers(java.lang.String, java.lang.String,
                       oracle.communications.inventory.api.entity.TelephoneNumber)
 

The signature defines TelephoneNumber as the method argument. This indicates that the extension point is intended to be used with the Telephone Number specification.

Global Extension Points

The signature argument for global extension points is not restricted; it may define any type of argument, or no argument at all. For example, the TimeoutEventListener_timerExpired base global extension point defines the following signature, which includes no argument:

public void oracle.communications.inventory.api.common.TimeoutEventListener.timerExpired()

Extension Point Types

Extension points also define a type, which dictates how the extension point is weaved into the UIM code stream. There are two extension point types:

  • Execution

  • Call

To understand extension point types, you must first understand ruleset extension points. See "Ruleset Extension Points".

Ruleset Extension Points

A ruleset extension point configures a ruleset to run at an extension point and configures the placement of the ruleset with respect to the method signature defined by the extension point. UIM provides no ruleset extension points, but it does provide a framework that enables you to create ruleset extension points.

Through a ruleset extension point, you can configure:

  • A base ruleset to run at a base extension point

  • A base ruleset to run at a custom extension point

  • A custom ruleset to run at a base extension point

  • A custom ruleset to run at a custom extension point

  • Whether to run the rule set:

  • Before the method

  • After the method

  • Instead of the method

Ruleset extension points are created in Design Studio in the Ruleset Extension Point and Ruleset Extension Point - Global editors. See "Creating Ruleset Extension Points" for more information.

Understanding Extension Point Type and Ruleset Placement

An extension point defines a type of execution or call, and a ruleset extension point defines where and when the ruleset is run (before, after, or instead of the method defined by the extension point). Together, this information dictates how the extension point is weaved into the UIM code stream, as explained using the following figures.

Figure 8-1 represents the UIM code stream. Within the UIM code stream, method a() is shown, as well as calls to UIM method a() from various places within the UIM code stream. The dots within method a() represent executable lines of code.

Figure 8-2, Figure 8-3, and Figure 8-4 show an extension point type of execution, which dictates the extension point is weaved within the method defined by the extension point. For this type, the extension point is weaved in only one place: within the method itself.

Figure 8-2 represents a ruleset configured to run before the method. For this type of configuration, the extension point is weaved into the method, immediately prior to the first line of the method's executable code. The result is that the ruleset custom code runs before the method runs.

Figure 8-2 Type Execution, with Placement Before

Description of Figure 8-2 follows
Description of "Figure 8-2 Type Execution, with Placement Before"

Figure 8-3 represents a ruleset configured to run after the method. For this type of configuration, the extension point is weaved into the method, immediately following the last line of the method's executable code. The result is the ruleset custom code runs after the method runs.

Figure 8-3 Type Execution, with Placement After

Description of Figure 8-3 follows
Description of "Figure 8-3 Type Execution, with Placement After"

Figure 8-4 represents a ruleset configured to run instead of the method. For this type of configuration, the extension point is weaved into the method, and the method's executable code does not run. The result is the ruleset custom code runs instead of the method.

Figure 8-4 Type Execution, with Placement Instead

Description of Figure 8-4 follows
Description of "Figure 8-4 Type Execution, with Placement Instead"

Figure 8-5, Figure 8-6, and Figure 8-7 show an extension point type of call, which dictates the extension point is weaved at the call to the method defined by the extension point. For this type, the extension point may be weaved in multiple places: at each place from where the method is called.

Figure 8-5 represents a ruleset configured to run before the method. For this type of configuration, the extension point is weaved into the UIM code stream, immediately prior to the method call. The result is the ruleset custom code runs before the method runs.

Figure 8-5 Type Call, with Placement Before

Description of Figure 8-5 follows
Description of "Figure 8-5 Type Call, with Placement Before"

Figure 8-6 represents a ruleset configured to run after the method. For this type of configuration, the extension point is weaved into the UIM code stream, immediately after the method call. The result is the ruleset custom code runs after the method runs.

Figure 8-6 Type Call, with Placement After

Description of Figure 8-6 follows
Description of "Figure 8-6 Type Call, with Placement After"

Figure 8-7 represents a ruleset configured to run instead of the method. For this type of configuration, the extension point is weaved into the UIM code stream, and the method is not called. The result is the ruleset custom code runs instead of the method.

Figure 8-7 Type Call, with Placement Instead

Description of Figure 8-7 follows
Description of "Figure 8-7 Type Call, with Placement Instead"

Runtime performance is not affected by extension point type; however, server startup performance is affected because that is when custom extension points are weaved, and there is more to weave for type call. For this reason, Oracle recommends that extension points be defined as type execution.

Based on this recommendation, you cannot specify extension point type in the Design Studio Extension Point editor; all extension points default to type execution. However, there are cases when you may need to use type call. For example, if your custom code needs to know the calling class for processing reasons, or needs to know if the call originated from a web service for processing reasons. In such cases, you must define type call, and there is a way to do this: see "Creating Extension Points" for more information.

Note:

Base extension points are all defined as type execution. Base extension points are part of the UIM code base, so they are not weaved into the UIM code stream when UIM is started. Only custom extension points are weaved into the UIM code stream when UIM is started.

The benefit of specifying type call is the ruleset can retrieve the caller through the ExtensionPointRuleContext.getCaller() method. The drawback of specifying type call is the ruleset does not run if the method the extension point defines is called by a method defined in the same class or subclass.

For example, Figure 8-8 shows ClassA, which defines methods x() and y(), and y() calls x(). ClassB extends ClassA and defines method z(), and z() also calls x(). The aop.xml file defines an extension point for method x() of type call. The ruleset runs when method x() is called from anywhere outside ClassA or ClassB, but the ruleset does not run when method x() is called from y() or z() because x() is called from within the same class or subclass.

Figure 8-8 Type Call Drawback

Description of Figure 8-8 follows
Description of "Figure 8-8 Type Call Drawback"

Enabled Extension Points

Note:

Enabled extension points are used only with specification-based extension points; they are not used with global extension points.

An enabled extension point enables a specification-based extension point for a particular specification. UIM provides several base enabled extension points in the ora_uim_baseextpts cartridge and also provides a framework that enables you to create enabled extension points.

Enabling a specification-based extension point for a particular specification is accomplished by associating an entity specification Java class to a specification-based extension point. To understand an enabled extension point, you must first understand that, for specification-based extension points, you must configure the specification for a ruleset extension point. This configuration is done on the Rules tab of any specification editor, where you select a ruleset extension point from a list. The list is populated for the specification, based on extension points that are enabled for the specification. If no extension points are enabled for the specification, no ruleset extension points are available for selection on the Rules tab of the specification.

For example, if 10 extension points are defined, along with 10 ruleset extension points, and no enabled extension points are defined, the Equipment Specification editor Rules tab lists no ruleset extension points from which to choose. However, if 10 extension points are defined, along with 3 ruleset extension points, and 3 of these extension points are enabled for the EquipmentSpecification Java class through enabled extension points, the Equipment Specification editor Rules tab lists 3 ruleset extension points from which to choose.

Enabled extension points are created in Design Studio in the Enabled Extension Point editor. See "Creating Enabled Extension Points" and "Configuring a Specification for a Ruleset Extension Point" for more information.

About the UIM Extensibility Framework

The extensibility framework supports the functionality that rulesets and extension points provide. The following sections describe various parts of the extensibility framework that are critical to understanding how rulesets work.

RulesExecutor Class

Package: oracle.communications.inventory.extensibility.rules

This class defines the following methods:

  • load()

  • execute()

  • unload()

You use these methods to load, execute, and unload rulesets. The extensibility framework enables you to automatically run rulesets at extension points. However, you can also write custom code that directly runs a ruleset by calling the execute() method on the RulesExecutor class. See the Javadoc for information about this class. For instructions on how to access the Javadoc, see "Javadoc Documentation".

ExtensionPointContext and ExtensionPointRuleContext Class

Package: oracle.communications.extensibility.extension.util

ExtensionPointRuleContext extends ExtensionPointContext.

For any given extension point, ExtensionPointRuleContext is constructed and made available to the ruleset as an argument. The extensibility framework adds the ExtensionPointContext as an argument, following any arguments defined by the extension point signature.

For extension points of type call, the context contains the calling class. This is provided so custom code can process differently based on the caller. For example, the custom code may need to perform a different process if called from the UI, versus being called from a web service. In this scenario, the custom code can use the context's getCaller() method to make the determination. For extension points of type execution, the context does not contain the calling class. So, the getCaller() method should not be used for extension points of type execution because the return is always null.

Regardless of type, the context contains the target class and method arguments. Method arguments are placed into the argument collection in left-to-right parameter order. Integral types are placed in the corresponding wrapper object. For example, int arguments are passed by reference using an Integer.

ExtensionPointRuleContext.returnValue

Data is returned to a ruleset in the returnValue attribute defined in the ExtensionPointRuleContext class. For example, you use the ExtensionPointRuleContext.setReturnValue(Object) method to set the returnValue attribute. The placement of the ruleset affects the use of the returnValue attribute as follows:

  • Before

    If the ruleset populates the returnValue attribute, the intercepted method removes any returnValue set by the ruleset.

  • After

    Data in ExtensionPointRuleContext is available to the ruleset to manipulate. The ruleset can change the returnValue attribute either by setting a new return object in the context or by changing attribute values of the return object already in the context. For this scenario, the return value type must match the value type that is normally returned by the intercepted method or an exception is thrown.

  • Instead

    The ruleset completely controls what is returned to the caller by setting the returnValue attribute. For this scenario, the return value type must match what is normally returned by the intercepted method or an exception is thrown.

For an example of the use of ExtensionPointRuleContext, view the TELEPHONE_NUMBER_FORMATTING ruleset that is provided in the ora_uim_baserulesets cartridge.

aop.xml File

The UIM_Home/config/extensibility/META-INF/aop.xml file is provided as an example to follow when creating custom extension points, which is a two-part process: Creating the extension point in the Design Studio Extension Point editor, and creating a custom aop.xml file. Both are deployed into UIM as part of a cartridge.

The custom aop.xml file must reside in the cartridge's model/aspects directory. When UIM is started, the aop.xml file is used to weave custom extension points into the UIM code stream.

Example 8-5 is an excerpt from the provided aop.xml file, and shows all of the XML elements that the file defines, as well as several of the example extension points that the file defines. (Many of the extension point definitions were removed for readability.)

Example 8-5 aop.xml File

<aspectj>
<!--
  <aspects>
    <concrete-aspect name=
"oracle.communications.inventory.extensibility.extension.SpecAsTarget"
    extends=
"oracle.communications.inventory.extensibility.extension.SpecTargetExtension">
      <pointcut name="ruleExtensionPoint" expression="execution(public * oracle.communications.inventory.api.impl.entity.SpecificationDAO.getName(..) )"/> 
    </concrete-aspect>
    <concrete-aspect name=
"oracle.communications.inventory.extensibility.extension.SpecBasedAsArgument" 
    extends=
"oracle.communications.inventory.extensibility.extension.SpecBasedArgumentExtension" >
      <pointcut name="ruleExtensionPoint" expression=" 
        call(public * oracle.communications.inventory.api.number.TelephoneNumberManager.createTelephoneNumbers(String, String, oracle.communications.inventory.api.entity.TelephoneNumber, java.util.Set, java.util.List))
        || call(public * oracle.communications.inventory.api.number.TelephoneNumberManager.deleteTelephoneNumbers(oracle.communications.inventory.api.entity.TelephoneNumber...))
        || call(public * oracle.communications.inventory.api.number.TelephoneNumberManager.updateTelephoneNumbers(java.util.List, java.util.Set, java.util.List))"/>
    </concrete-aspect>
 
    <concrete-aspect name=
"oracle.communications.inventory.extensibility.extension.SpecAsArgument" 
    extends=
"oracle.communications.inventory.extensibility.extension.SpecArgumentExtension">
      <pointcut name="ruleExtensionPoint" expression="
        call(public * 
oracle.communications.inventory.api.consumer.ReservationManager.extendReservation(oracle.communications.inventory.api.entity.ServiceSpecification, java.util.List, java.lang.String, oracle.communications.inventory.api.entity.ReservedForType))
        || call(public * oracle.communications.inventory.api.consumer.ReservationManager.reserveResource(oracle.communications.inventory.api.entity.ServiceSpecification, java.util.Collection, oracle.communications.inventory.api.entity.common.Reservation))
        || call(public * oracle.communications.inventory.api.service.ServiceManager.createService(oracle.communications.inventory.api.entity.Service, oracle.communications.inventory.api.entity.ServiceSpecification))"/>
    </concrete-aspect>
 
    <concrete-aspect name=
"oracle.communications.inventory.extensibility.extension.GlobalRule" 
    extends=
"oracle.communications.inventory.extensibility.extension.GlobalRuleExtension" >
      <pointcut name="ruleExtensionPoint" expression="
           call(public * oracle.communications.inventory.api.common.TimeoutEventListener.timerExpired())
        || call(public * oracle.communications.inventory.api.admin.SecurityManager.handleSecurityViolation(..))
        || call(public * oracle.communications.inventory.api.common.AttachmentManager.createAttachment(oracle.communications.inventory.api.entity.common.Attachment...))
        || call(public * oracle.communications.inventory.api.common.AttachmentManager.updateAttachment(oracle.communications.inventory.api.entity.common.Attachment...))
        || call(public * oracle.communications.inventory.api.common.AttachmentManager.deleteAttachment(oracle.communications.inventory.api.entity.common.Attachment...))"/>
    </concrete-aspect>
 
    <concrete-aspect name="oracle.communications.inventory.extensibility.extension.SecurityValidation" 
      extends="oracle.communications.inventory.extensibility.extension.SecurityValidationExtension" >
      <pointcut name="securityExtensionPoint" expression="
           call(public * oracle.communications.inventory.api.group.InventoryGroupManager.createInventoryGroup(oracle.communications.inventory.api.entity.InventoryGroup))
        || call(public * oracle.communications.inventory.api.group.InventoryGroupManager.deleteInventoryGroup(oracle.communications.inventory.api.entity.InventoryGroup))
        || call(public * oracle.communications.inventory.api.group.InventoryGroupManager.updateInventoryGroup(oracle.communications.inventory.api.entity.InventoryGroup))"/>
    </concrete-aspect>
  </aspects>
 
  <weaver>
    <include within=
"oracle.communications.inventory.api.number.impl.TelephoneNumberManagerImpl"/>
    <include within=
"oracle.communications.inventory.api..*"/>   
  </weaver>
 
-->
</aspectj>

The provided aop.xml file defines the following:

  • aspects

    This element defines the concrete extensions through the <concrete-aspect> element. The implemented aspects are:

    • SpecAsTarget

      Defines extension points for method signatures defined on a specification object. An example of a specification object is a specification itself, such as EquipmentSpecification. For example, when the EquipmentSpecification.setModelNumber(String modelNbr) method is called, EquipmentSpecification is the target of the invocation.

      Oracle recommends that you not use this type of aspect.

    • SpecBasedAsArgument

      Defines extension points for method signatures that define specification-based arguments. An example of a specification-based argument is an instance of an entity, such as Equipment. For example, the Equipment.createPhysicalPorts(Equipment equip, List physPorts) method defines an argument of Equipment.

    • SpecAsArgument

      Defines extension points for method signatures that define specification arguments. An example of a specification argument is a specification itself, such as TelephoneNumberSpecification. For example, the SpecManager.getEditMask(TelephoneNumberSpecification) method defines an argument of TelephoneNumberSpecification.

    • GlobalRule

      Defines global extension points for method signatures that define arguments that are neither a specification nor specification-based. For example, ReservationManager.expireReservation(boolean) is a method defined as a global extension point.

    • SecurityValidation

      Defines extension points for APIs that require authorization to access. Extension points defined in this element are neither specification-based nor global because they are not part of the extensibility framework. Rather, they are part of the Security Validation Extension framework, and the execution of the APIs defined for these extensions go through UIM logic authorization.

  • weaver

    Defines the Java packages the extensibility framework is to search for classes in which to weave any custom extension points. The weaving of custom extension point is done when UIM is started.

  • There are five aspects defined, and each aspect defines several extension points.

  • Extension points are defined, including type of call or execution.

  • The argument for the deleteTelephoneNumbers() method uses a notation of “..." to represent an array of TelephoneNumber objects. This notation is used in the aop.xml method signature, but not in the Design Studio method signature. See "Creating Extension Points" for more information.

  • All of the method signatures in the SpecBasedAsArgument aspect define at least one argument that is specification-based (TelephoneNumber, an Array of TelephoneNumber objects, and a java.util.Collection of TelephoneNumber objects).

  • All of the method signatures in the SpecAsArgument aspect define at least one argument that is a specification (ServiceSpecification).

  • The method signatures in the GlobalRule aspect may define specification-based arguments, specification arguments, generic arguments, or no arguments at all. There are no restrictions on these arguments. So, regardless of the arguments defined, a ruleset configured to run at a global extension point always runs because it is defined within the <GlobalRule> element.

  • The method signatures defined in the SecurityValidation aspect control access to the API methods of createInventoryGroup, deleteInventoryGroup, and updateInventoryGroup.

  • The <weaver> element tells the extensibility framework what packages to search when looking to weave any custom extension points.

Turning the Weaver On

When UIM is started, the custom aop.xml file is used to weave custom extension points into the UIM code stream. To initiate this weaving of custom extension points, the Weaver must be turned on. UIM_Home/Domain_Home/bin/startUIM.cmd is the script that starts UIM, and it calls UIM_Home/Domain_Home/bin/setUIMEnv.cmd. The setUIMEnv.cmd script sets the UIM environment, and includes the following lines. To turn the Weaver on or off, uncomment or comment the following lines in the setUIMEnv.cmd file.

     set JAVA_OPTIONS=%JAVA_OPTIONS% -javaagent:%UIM_HOME%\lib\aspectjweaver.jar
        set JAVA_OPTIONS=%JAVA_OPTIONS% -Daj.weaving.verbose=false

About Base Rulesets

This section provides information on base rulesets, and on base extension points and base enabled extension points that can be used call a base ruleset or custom ruleset.

Note:

See Base Rulesets for detailed information about each base ruleset, including a description of what the base ruleset does and step-by-step instructions for running it.

UIM provides several base rulesets in the ora_uim_baserulesets cartridge. Base rulesets are called by UIM code and provide examples for creating custom rulesets. Each base ruleset provides a Drools version and a Groovy version of the ruleset. You can find the base rulesets in the UIM_Home/cartridges/base/ora_uim_baserulesets.jar file.

Base rulesets can be viewed in Design Studio or in UIM:

  • To view base rulesets in Design Studio, import the ora_uim_baserulesets cartridge into Design Studio. After you import the base cartridge, you can view the base rulesets in the Design perspective Studio Projects view.

    For instructions on how to import a cartridge into Design Studio, see the Design Studio Help.

  • To view base rulesets in UIM, deploy the ora_uim_baserulesets cartridge into UIM. After you deploy the base cartridge, you can view the rulesets in UIM by clicking the Rulesets link in the Tasks panel of the UIM Home page.

    See UIM Cartridge Guide for information about deploying cartridges and cartridge packs.

About Base Extension Points and Base Enabled Extension Points

UIM provides numerous base extension points and base enabled extension points in the ora_uim_baseextpts cartridge. You can use the base extension points to call base rulesets or custom rulesets. You can find the base extension points and base enabled extension points in the UIM_Home/cartridges/base/ora_uim_baseextpts.jar file.

Base extension points and base enabled extension points can be viewed in Design Studio. To do so, import the ora_uim_baseextpts cartridge into Design Studio. After you import the base cartridge, you can view the base extension points and base enabled extension points in the Design perspective Studio Projects view.

For instructions on how to import a cartridge into Design Studio, see the Design Studio Help.

See UIM Cartridge and Technical Pack Guide for more information on the ora_uim_base_extpts cartridge.

About Naming Conventions

Understanding the naming convention used for the base extension points and base enabled extension points helps you readily locate them within the ora_uim_baseextpts cartridge, which is important because there are hundreds of them. Within the base cartridge, the base extension points are grouped together alphabetically, and the base enabled extension points are grouped together alphabetically.

The naming convention for base extension points is ClassName_methodName. For example, the TelephoneNumberManager_createTelephoneNumbers.

The naming convention for base enabled extension points is SpecificationName_ClassName_methodName. For example, the TelephoneNumberSpecification_TelephoneNumberManager_createTelephoneNumbers.

There are often multiple base extension points defined per class. For example, Figure 8-9 is an excerpt of the ora_uim_baseextpts cartridge expanded in Design Studio that shows several base extension points defined for several entity manager classes. Specifically, IPAddressManager, IPNetworkManager, IPv4AddressManager, and IPv6AddressManager each define extension points for their respective create(), delete(), and update() methods.

Figure 8-9 IP Address Entity Manager Classes

Description of Figure 8-9 follows
Description of "Figure 8-9 IP Address Entity Manager Classes"

Note:

The naming convention used for these extension points indicates that these are global extension points. However, this naming convention is not always employed. So, when working with base extension points, be sure to look at the extension point definition to determine whether the Global check box is selected, indicating that the extension point is a global extension point.

Working with Rulesets

Before reading this section:

  • Read the preceding sections of this chapter and have an understanding of rules, rulesets, extension points, and ruleset extension points.

  • You should understand what a cartridge is, how to create one in Design Studio, and how to deploy one into UIM.

  • You should understand Design Studio perspectives and views, and how to switch between them.

When working with rulesets to extend UIM:

  1. Determine the functionality that you plan to extend and how you plan to extend it.

    See UIM Concepts to learn about existing UIM functionality. See the UIM Javadoc to learn about specific classes or methods you plan to extend. For information on accessing the Javadoc, see "Javadoc Documentation".

  2. Configure Design Studio. When working with rulesets, it is important that you configure your environment correctly to avoid errors later in the process.

    See "Configuring Design Studio".

  3. In Design Studio, install, configure, and learn how to use one of the following:

  4. Create an Inventory project.

    See the Design Studio Help.

  5. Create a ruleset.

    See "Creating Rulesets".

  6. Create an extension point, or use an existing base extension point.

    See "Creating Extension Points".

  7. Create a ruleset extension point to configure the ruleset to run at the extension point.

    See "Creating Ruleset Extension Points".

  8. For specification-based extension points, create an enabled extension point to enable the extension point for the specification.

    See "Creating Enabled Extension Points".

  9. For specification-based extension points, configure the specification for the ruleset extension point.

    See "Configuring a Specification for a Ruleset Extension Point".

  10. Validate and compile the ruleset, and build the project to create the cartridge.

    See "Validating and Compiling Rulesets" and the Design Studio Help.

    If your ruleset custom code is dependent upon third-party code for successful compilation, see "Compiling Rulesets with Third-Party Dependencies".

  11. Deploy the cartridge into UIM.

    See "Deploying Cartridges Containing Rulesets".

  12. If you created an extension point (as opposed to using a base extension point), make sure the Weaver is turned on and restart UIM.

    See "Turning the Weaver On".

  13. Run the ruleset.

    See "Running Rulesets".

  14. If problems are encountered, debug and troubleshoot.

    See "Debugging Custom Groovy Rulesets".

Installing, Configuring, and Using the Drools Eclipse Plug-ins

Installing, configuring, and using the Drools Eclipse plug-ins are described in the following sections:

Installing the Drools Eclipse Plug-ins

To install the Drools Eclipse plug-ins:

  1. From the Design Studio Help menu, select Install New Software.

    The Install window appears.

  2. Click Add.

    The Add Repository window appears.

  3. In the Name field, enter an arbitrary name, such as “Drools."

  4. Copy the following URL and paste it into the Location field:

    http://downloads.jboss.org/drools/release/6.5.0.Final/org.drools.updatesite/
    
  5. Click OK.

    The Add Repository window closes.

  6. From the Work with list, select the name of the repository you just added.

  7. Select the Group items by category check box, if it is not already selected.

  8. Expand Drools and jBPM.

  9. Select Drools and jBPM, which automatically selects following plug-ins to install:

    • JBoss Drools Core

    • JBoss Drools Guvnor

    • JBoss iBPM Core

  10. Click Next twice, accept the license agreement, and click Finish.

    A security warning response window appears.

  11. Click OK.

    A prompt to restart Eclipse appears.

  12. Click Yes.

    You must restart Eclipse for the installed plug-ins to work.

Configuring the Drools Eclipse Plug-ins

After you install the Drools Eclipse plug-ins in Design Studio, you must configure Design Studio to recognize them. Configuring the Drools Eclipse plug-ins is described in the following sections:

Configuring the Drools Runtime Preference

To configure the Drools runtime preference:

  1. Within your Eclipse_Home directory, create a new folder and name it myDroolsRuntime.

  2. In Design Studio, from the Window menu, select Preferences.

    The Preferences window appears.

  3. In the navigation panel, expand Drools and select Installed Drools Runtimes.

  4. Click Add.

    The Drools Runtime window appears.

  5. Click Create a new Drools Runtime.

    The Browse For Folder window appears.

  6. Navigate to the Eclipse_Home/myDroolsRuntime folder and click OK.

    The Browse For Folder window closes.

    The Name and Path fields are now populated on the Drools Runtime window.

  7. Click OK.

    The Drools Runtime window closes.

  8. Select the check box located to the left of the Drools Runtime you just added, and click OK.

    The Preferences window closes.

Configuring the File Associations Preference

To configure the File Associations preference:

  1. In Design Studio, from the Window menu, select Preferences.

    The Preferences window appears.

  2. In the navigation panel, expand General, then Editors, and then select File Associations.

  3. In the File types section, select .drl.

  4. In the Associated editors section, select Rule Editor and click Default.

  5. Click OK.

    The Preferences window closes.

Configuring the Cartridge for Drools Files

To configure the .project and .classpath files, perform the following steps for each cartridge in which you plan to create rulesets:

  1. In Design Studio, open the Java perspective, and open the Navigator view.

  2. Expand the cartridge in which you will create rulesets with Drools files.

  3. Open the cartridge's .project file by double-clicking the file name.

  4. In the .project file editor, click the Source tab located at the bottom of the editor.

  5. Within the XML, create a new <buildCommand> element by copying and pasting one of the existing <buildCommand> elements.

  6. Change the copied <buildCommand> element to the following value:

    <buildCommand>
        <name>org.drools.eclipse.droolsbuilder</name>
        <arguments>
        </arguments>
    </buildCommand>
    
  7. Save the .project file.

  8. In the Navigator view, open the .classpath file by double-clicking the file name.

  9. In the .classpath file editor, click the Source tab located at the bottom of the file editor.

  10. Within the XML, create a new <classpathentry> element by copying and pasting one of the existing <classpathentry> elements.

  11. Change the copied <classpathentry> element to the following value:

    <classpathentry kind="con" path="DROOLS/Drools"/>  
     
    

    Note:

    When specifying the path, the case matters: it must be as shown above.

  12. Save the .classpath file.

Configuring the Project Builders

To configure the project builders:

  1. In Design Studio, open the Java perspective, and open the Navigator or Package Explorer view.

  2. Select the cartridge.

  3. From the Project menu, select Properties.

  4. In the navigation panel, select Builders.

  5. Select Drools Builder and click Down as needed to place Drools Builder at the end of the list.

Using the Drools Eclipse Plug-ins

The Drools Eclipse plug-ins provide a Drools rule editor and several Drools-specific menu options.

Drools Rule Editor

After you install and configure the plug-ins, the Drools rule editor works in a Drools file opened within Design Studio. The editor catches syntax errors when you are writing a ruleset. The rule editor also provides the ability to compile a ruleset prior to deploying the cartridge containing the ruleset.

Drools-Specific Menu Options

To access the Drools-specific menu options:

  1. In Design Studio, from File menu, select New, then select Other.

  2. Expand Drools.

    The Drools-specific menu options are:

    • Decision Table

    • Domain Specific Language

    • Drools Project

    • Flow File

    • Knowledge Base

    • Rule Resource

For information on using the Drools-specific menu options, see the Drools Documentation website:

http://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html_single/

Installing, Configuring, and Using the Groovy Eclipse Plug-ins

Installing, configuring, and using the Groovy Eclipse plug-ins is described in following sections:

For more information on installing Groovy plug-ins, see the Groovy Eclipse Wiki website:

https://github.com/groovy/groovy-eclipse/wiki

Installing the Groovy Eclipse Plug-ins

To install the Groovy Eclipse plug-ins:

  1. From the Design Studio Help menu, select Install New Software.

    The Install window appears.

  2. Click Add.

    The Add Repository window appears.

  3. In the Name field, enter an arbitrary name, such as “Groovy."

  4. Determine the appropriate update site URL from the list provided in the Groovy Eclipse Wiki website.

    See "Software Requirements" for information on the required Groovy version.

  5. Paste the update site URL into the Location field.

  6. Click OK.

    The Add Repository window closes.

  7. From the Work with list, select the name of the repository you just added.

  8. Select the Group items by category check box, if it is not already selected.

  9. Expand and select the Groovy-Eclipse plug-in feature, and follow the prompts to install.

  10. Accept the license agreement, and click Finish and OK.

  11. Click Yes to agree to restart Eclipse.

    You must restart Eclipse for the installed plug-ins to work.

Configuring the Groovy Eclipse Plug-ins

After you install the Groovy Eclipse plug-ins in Design Studio, you must configure Design Studio to recognize them. Configuring the Groovy Eclipse plug-ins is described in the following sections:

Configuring the Groovy Compiler Version

To configure the Groovy compiler version:

  1. In Design Studio, from the Window menu, select Preferences.

    The Preferences window appears.

  2. In the navigation panel, select Groovy to expand the list and select Compiler. By default the highest compiler version is selected.

  3. Click the appropriate Groovy version for UIM.

  4. Click Yes to confirm the change.

  5. Click OK.

    The Preferences window closes.

  6. Restart Eclipse for the compiler setting to take effect.

  7. Verify that the Groovy compiler version is set correctly:

    1. From the Design Studio Window menu, select Preferences.

    2. In the navigation panel, select Groovy to expand the list and then select Compiler.

    3. Verify that the compiler version is set to the appropriate version.

See "Software Requirements" for the Groovy version information.

Configuring File Associations for Groovy

To configure File Associations for Groovy:

  1. In Design Studio, from the Window menu, select Preferences.

    The Preferences window appears.

  2. In the navigation panel, expand General, then Editors, and then select File Associations.

  3. In the File types section, select .groovy.

  4. In the Associated editors section, select Groovy Editor and click Default.

  5. Click OK.

    The Preferences window closes.

Configuring the Cartridge for Groovy Files

To configure the .project and.classpath files, perform the following steps for each cartridge in which you plan to create rulesets:

  1. In Design Studio, open the Java perspective, and open the Navigator view.

  2. Expand the cartridge in which you will create rulesets.

  3. Open the cartridge's .project file by double-clicking the file name.

  4. In the .project file editor, click the Source tab located at the bottom of the editor.

  5. Within the XML, create a new <nature> element by copying and pasting one of the existing <nature> elements.

  6. Change the copied <nature> element to the following value:

        <nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
    
  7. Save the .project file.

  8. In the Navigator view, open the cartridge's .classpath file by double-clicking the file name.

  9. In the .classpath file editor, click the Source tab located at the bottom of the editor.

  10. Within the XML, create a new <classpathentry> element by copying and pasting one of the existing <classpathentry> elements.

  11. Change the copied <classpathentry> element to the following value:

    <classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>     
    

    Note:

    The path value is case-sensitive and must be entered as shown above.

  12. Save the .classpath file.

Using the Groovy Eclipse Plug-ins

The Groovy Eclipse plug-ins provide a Groovy editor and several Groovy-specific menu options.

Groovy Editor

After you install and configure the plug-ins, the Groovy editor works in a Groovy file opened within Design Studio. The editor catches syntax errors when you are writing ruleset code. The Groovy editor also enables you to compile a ruleset prior to deploying the cartridge containing the ruleset.

Groovy-Specific Menu Options

To access the Groovy-specific menu options:

  1. In Design Studio, from the File menu, select New, and then Other.

  2. Select Groovy.

    The Groovy-specific menu options are:

    • Groovy Class

    • Groovy DSL Descriptor

    • Groovy Project

    • Groovy Test Case

For information about using Groovy, see the Groovy documentation at the following website:

http://www.groovy-lang.org/documentation.html

Creating Rulesets

For instructions on how to create a ruleset in Design Studio, see the Design Studio Help. When creating a ruleset, use the following information.

Name Field

When entering the name of the ruleset in the Name field, the text editor forces you to enter all capitals. Oracle recommends that you use underscores for readability, such as MY_RULE_SET.

DRL File or Groovy File

A ruleset resides in a .drl file or in a .groovy file, both of which you access from the Ruleset editor. These files are saved in the inventory project's model directory.

When writing a custom ruleset, Oracle recommends that you:

Creating Extension Points

This section applies to specification-based and global extension points.

Note:

Before creating a custom extension point, check the UIM_Home/cartridges/base/ora_uim_baseextpts cartridge to see if a base extension point already exists that defines the UIM API method you need to use.

Before you create an extension point, you must first determine the UIM API method signature that you want the extension point to define. For example, you may want to create an extension point that deals with disassociating a telephone number from an inventory group. To determine the UIM API method signatures you need to use the Javadoc and search for the manager class using *Manager.class as search criterion to return a list of all manager classes such as TelephoneNumberManager, EquipmentManager, and PipeManager. After locating the appropriate manager class, search the list of methods for the most likely method, such as the TelephoneNumberManager.disassociateTN() method.

For instructions on how to access the Javadoc, see "Javadoc Documentation".

Creating an extension point is a two-part process:

Both are deployed into UIM as part of a cartridge.

Creating the Extension Point in Design Studio

For instructions on how to create an extension point in Design Studio, see the Design Studio Help. When creating an extension point, use the following information.

Name Field

When entering a name, Oracle recommends that you follow the same naming convention used in the ora_uim_baseextpts cartridge, which is ClassName_methodName. For example TelephoneNumberManager_disassociateTN.

Point Name Field

When entering a point name, Oracle recommends that you follow the same naming convention used in the ora_uim_baseextpts cartridge, which is ClassName.methodName. For example, TelephoneNumberManager.disassociateTN.

Signature Field

Correctly entering the method signature in the Signature field is critical for the ruleset to run. An exact signature match is required. For example, spacing errors result in the ruleset not executing, as well as using a class interface hierarchy supertype. Oracle recommends that you copy the signature from the UIM_Home/lib/uim-core-interfaces.txt file and paste it into the Signature field. The uim-core-interfaces.txt file provides a generated listing of all API method signatures. Copy the text from public abstract interface through the end of the line.

Example 8-6 shows a typical signature definition:

Example 8-6 Signature

public abstract interface java.lang.String oracle.communications.inventory.api.businessinteraction.BusinessInteractionManager.getEntityAction(oracle.communications.inventory.api.entity.common.RootEntity, oracle.communications.inventory.api.entity.BusinessInteraction, java.lang.String)

A signature requires the following:

  • Visibility modifier (public, private, protected)

    The visibility modifier must be defined as public abstract interface, as shown in Example 8-6. The existence of the Javadoc for the method indicates that the method is a public interface. AspectJ requires that all methods defined for an extension point be declared as abstract, even if the method in the Java code is not defined as abstract.

  • Return

    This part of the signature defines the return values. In Example 8-6, getEntityAction() returns java.lang.String.

  • Fully qualified method call, which includes:

    • Package

      In Example 8-6, the package that contains the BusinessInteractionManager class is oracle.communications.inventory.api.businessinteraction.

    • Class

      In Example 8-6, the class is BusinessInteractionManager.

    • Method

      In Example 8-6, the method is getEntityAction().

    • Arguments

      In Example 8-6, the arguments are the fully qualified objects of RootEntity, BusinessInteraction, and String.

Putting all parts together results in the signature being defined as shown in Example 8-6.

When entering the signature:

  • Characters that define the signature are case sensitive.

  • No extra spaces can exist within the signature.

  • If the signature defines multiple arguments, the arguments are separated by a comma followed by a space.

  • Signatures that define arrays must use [] to represent an array of objects.

  • Signatures that define an array of objects as a parameter must contain the transient keyword. The AspectJ framework requires this keyword to retrieve the extension point, as shown in Example 8-7.

Example 8-7 Signature with Transient and Array

public abstract transient interface oracle.communications.inventory.api.entity.BusinessInteraction oracle.communications.inventory.api.businessinteraction.BusinessInteractionManager.transferItems(oracle.communications.inventory.api.entity.BusinessInteraction, oracle.communications.inventory.api.entity.BusinessInteraction, oracle.communications.inventory.api.entity.BusinessInteractionItem[])

Note:

Do not copy the signature from the Javadoc and paste it into the Signature field: Copying from an HTML file results in spacing errors. Avoiding these spacing errors is critical because the ruleset does not run and you do not get an error, so it is difficult to determine the problem.

Creating the aop.xml File

To create an aop.xml file:

  1. In Design Studio, create an Inventory project.

  2. Switch to the Java perspective.

  3. Expand the inventory project, and expand the model directory. (The model directory gets created when the inventory project is created.)

  4. Create a new directory named aspects within the model directory.

  5. Create a new file named aop.xml in the model/aspects directory.

  6. Model the contents of the custom aop.xml file after the UIM_Home/config/extensibility/ META-INF/aop.xml file. See "aop.xml File" for more information on the aop.xml file.

  7. Determine the aspect of the extension point, which is based on the method signature defined by the extension point. See "aop.xml File" for more information on aspects.

  8. Define the extension point within the determined aspect. See "aop.xml File" for more information.

  9. Delete any <concrete-aspect> elements that do not define any extension points.

  10. Ensure that the <weaver> element is not commented out.

  11. Update the <weaver> include elements to reflect the correct package or packages that are applicable to your custom extension point. See "aop.xml File" for more information.

  12. Save the aop.xml file.

  13. Open the UIM_Home/Domain_Home/bin/startUIM.cmd file.

  14. Verify that the following lines are uncommented:

         set JAVA_OPTIONS=%JAVA_OPTIONS% -javaagent:%UIM_HOME%\lib\aspectjweaver.jar
            set JAVA_OPTIONS=%JAVA_OPTIONS% -Daj.weaving.verbose=false
    

    See "Turning the Weaver On" for more information.

  15. Save the startUIM.cmd file.

Note:

The concrete-aspect name must be unique across all extension points installed on your application server or the following error appears on server startup: "Error Attempt to concretize but chosen aspect name already defined: name in aop.xml warning register definition failed."

To fix this error, change the concrete-aspect name. Do not change the extends portion of the concrete-aspect. Example 8-8 shows the before and after reflecting this change.

Example 8-8 Concrete-Aspect Name

// Before
<concrete-aspect name="oracle.communications.extensibility.extension.SpecBasedAsArgument"
        extends="oracle.communications.extensibility.extension.SpecBasedArgumentExtension">
<pointcut name="ruleExtensionPoint" expression="
call (public abstract interface java.util.List oracle.communications.inventory.api.connectivity.PipeManager.updatePipes(java.util.Collection))"/>

// After
<concrete-aspect name="oracle.communications.extensibility.extension.SpecBasedAsArgumentXyz"
        extends="oracle.communications.extensibility.extension.SpecBasedArgumentExtension">
<pointcut name="ruleExtensionPoint" expression="
call (public abstract interface java.util.List oracle.communications.inventory.api.connectivity.PipeManager.updatePipes(java.util.Collection))"/>

Creating Ruleset Extension Points

Note:

This section applies to ruleset extension points and global ruleset extension points.

Note:

No base ruleset extension points are provided. If you want to use a base ruleset and a base extension point, you must create a ruleset extension point to configure the base ruleset to run at the base extension point.

The ruleset extension point configures a ruleset to run at a specification-based extension point and configures the placement of the ruleset.

For instructions on how to define a ruleset extension point, see the Design Studio Help.

Creating Enabled Extension Points

Note:

This section applies only to specification-based extension points.

Note:

Before creating a custom enabled extension point, check the ora_uim_baseextpts cartridge to see if a base enabled extension point already exists for the specification and extension point that you need to enable.

Create an enabled extension point for every specification-based extension point you create. For instructions on how to create an enabled extension point, see the Design Studio Help. When creating an enabled extension point, use the following information.

Name Field

When entering a name, Oracle recommends that you follow the same naming convention used in the ora_uim_baseextpts cartridge, which is SpecificationName_ClassName_methodName. For example, usTelephoneNumber_TelephoneNumberManager_disassociateTN.

Specification Class Name Field

You must select a value from the Class Specification Name list, which is preloaded with the fully qualified entity specification Java class names.

Nearly all of the Studio Inventory entities are recognizable by their Java class name. For example, the Telephone Number Specification entity appears in the list as oracle.communications.inventory.api.entity.TelephoneNumberSpecification, and the Equipment Specification entity appears in the list as oracle.communcations.inventory.api.entity.EquipmentSpecfication.

The only exceptions to this recognizable naming convention are the configuration specifications:

  • Logical Device Configuration Specification

  • Network Configuration Specification

  • Pipe Configuration Specification

  • Place Configuration Specification

  • Service Configuration Specification

To enable an extension point for a configuration specification, you must select the oracle.communications.inventory.api.entity.InventoryConfigurationSpec class, which enables the Configuration Version Instance Type field. See "Configuration Version Instance Type Field" for more information.

Configuration Version Instance Type Field

The Configuration Version Instance Type field is enabled only when you select oracle.communications.inventory.api.entity.InventoryConfigurationSpec for the Specification Class Name field.

When enabled, you may select a value for Configuration Version Instance Type, which is preloaded with the available entity configuration specification Java class names. The selection list displays the following fully qualified Java class names:

  • oracle.communications.platform.entity.impl.LogicalDeviceConfigurationVersionDAO

  • oracle.communications.platform.entity.impl.NetworkConfigurationVersionDAO

  • oracle.communications.platform.entity.impl.PipeConfigurationVersionDAO

  • oracle.communications.platform.entity.impl.PlaceConfigurationVersionDAO

  • oracle.communications.platform.entity.impl.ServiceConfigurationVersionDAO

If you select a value for Configuration Version Instance Type, the extension point is enabled for the selected entity configuration specification. If you do not select a value for Configuration Version Instance Type, the extension point is enabled for all of the entity configuration specifications.

Configuring a Specification for a Ruleset Extension Point

Note:

This section applies only to a ruleset extension points; it does not apply to global ruleset extension points.

To run a ruleset that is configured to run at a specification-based extension point, you must also configure the specification for the ruleset extension point. This configuration is done in Design Studio, on the Rules tab of any Specification editor. For example, Figure 8-10 shows that, when you click Select to select a ruleset extension point, only the ruleset extension points that are enabled for the Equipment Specification appear.

For instructions on how to configure a specification for a ruleset extension point, see the Design Studio Help.

Figure 8-10 Specification Editor Rules Tab

Description of Figure 8-10 follows
Description of "Figure 8-10 Specification Editor Rules Tab"

Validating and Compiling Rulesets

Rulesets are validated:

Rulesets are compiled:

  • When UIM is started and there are uncompiled rulesets (such as after an upgrade). The serialized compilation is stored in the database. If compilation errors are encountered, the startup fails and the errors are cited.

  • When a cartridge that contains rulesets is deployed. The serialized compilation is stored in the database. If the compilation errors are encountered, the deployment fails and the errors are cited.

Note:

When compiling rulesets or building cartridges that contain rulesets, it is important that you configure your environment correctly to avoid errors later in the process.

See "Configuring Design Studio" for more information.

Compiling Rulesets with Third-Party Dependencies

If your ruleset custom code is dependent upon third-party code for successful compilation, you must add the third-party JAR files containing the code upon which your custom code is dependent to the Inventory project. The third-party JAR files must be included in the Inventory project so when the resultant cartridge is deployed into UIM, the third-party code is available to the ruleset at runtime.

Note:

Adding third party JAR files to the Eclipse project library list successfully compiles dependent custom code, but if compiled in this manner, third party code is not part of the Inventory project and is not available at runtime.

To add third-party JAR files to your Inventory project:

  1. In Design Studio, within the Studio Design perspective, open the Package Explorer view.

  2. In the Package Explorer view, expand your Inventory project containing your ruleset and third party-dependent custom code.

  3. Under the model directory, create the following directory structure: content/inventory.ear/APP-INF/lib.

  4. Copy any required third-party JAR files into the model/content/inventory.ear/APP-INF/lib directory.

  5. Build the project.

Deploying Cartridges Containing Rulesets

Deploying cartridges containing rulesets and extension points is no different than deploying other cartridges. See UIM Cartridge Guide for information about deploying cartridges and cartridge packs.

Running Rulesets

Rulesets can be run manually or automatically.

Manually Running Rulesets

Rulesets can be run manually from within UIM by clicking the Execute Rule link in the Tasks panel. Manually running rulesets is commonly used to manage UIM data. For example, you can manually run the SYSTEM_EXPORT base ruleset in one environment to export data, and manually run the SYSTEM_IMPORT base ruleset in another environment to load the exported data. See "About Base Rulesets" for more information.

Automatically Running Rulesets

Rulesets can be run automatically after they are deployed into UIM: When an event occurs that runs an existing UIM method that was defined as an extension point, the extensibility framework calls the RulesExecutor.execute() method, which runs the ruleset associated with the extension point.

Debugging Custom Drools Rulesets

For information on debugging custom rulesets (DRL files), see the Drools Documentation website:

http://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html_single/

Note:

The Drools documentation describes debugging rulesets within Eclipse, within the context of a Drools project, not within the context of a UIM server.

Note:

The Drools documentation on debugging states you must install the Eclipse Graphical Editing Framework (GEF) to debug rulesets. However, the Design Studio Inventory feature plug-in contains the GEF, so it is already installed.

For information on turning on debugging in UIM (to debug anything other than DRL files), see UIM System Administrator's Guide.

Debugging Custom Groovy Rulesets

This section provides information on debugging custom Groovy rulesets and extension points. Ensure that the steps for installing and configuring the Groovy Eclipse plug-ins are completed prior to setting up debug. See "Installing, Configuring, and Using the Groovy Eclipse Plug-ins" for more information.

Converting Inventory Projects to Groovy Projects

To convert an Inventory project to a Groovy project, perform the following steps before the project is deployed to the UIM server for the first time:

  1. In the Design Studio Package Explorer view, right-click the desired Inventory project, and select Configure.

    A submenu for the Configure action appears.

  2. Select Convert to Groovy Project.

    The project is converted.

Setting Up Debug Configurations

To set up a debug configuration to allow debugging of the project:

  1. Ensure the UIM server is running so that a debugger can be connected. See the UIM System Administrator's Guide for more information.

  2. In the Design Studio Project Explorer view, select your project.

  3. From the Run menu, select Debug Configurations.

    The Debug Configurations window appears.

  4. Click Remote Java Application, and then the New icon.

    A new remote java application is created with prompts for the settings.

  5. Click Browse and select your project.

  6. Click the Connect tab and enter the host and port information for the UIM server on which the cartridge with the custom rulesets is located.

  7. On the Common tab, under the Display in favorites menu, select the Debug check box.

  8. Click Apply to save the configuration.

  9. Click Close.

    The Debug Configurations window closes.

Debugging Groovy Rules

To debug your Groovy rule code:

  1. Set a breakpoint on at least one line of your code that is enabled. You can set a breakpoint by a double-click on a line of code, or right-click on the line of code and select Toggle Breakpoint.

  2. In the Design Studio Project Explorer view, select your project.

  3. From the Run menu, select Debug Configurations.

    The Debug Configurations window appears.

  4. Under Remote Java Application, select your application.

  5. Click Debug.

    The application is launched in debug mode and the debug perspective is displayed. The Eclipse debugger stops on the line of code where the breakpoint is set.

    Note:

    Only the secondary level of scripts can be debugged. The parent-level rule code does not recognize breakpoints; and only a breakpoint in a script that is called from the parent is recognized.

Troubleshooting Rulesets and Cartridge Deployment

This section provides information on troubleshooting problems you may encounter when working with custom rulesets, extension points, and cartridge deployment.

Troubleshooting Custom Rulesets

When troubleshooting custom rulesets, check the following:

  • Does the ruleset compile?

    • Use the Drools or Groovy Eclipse plug-in editor.

    • Check the import statements.

    • Check the project library list.

  • Does the cartridge build and deploy successfully?

    • Check the UIM application server log.

  • If using Drools, does the ruleset condition ever evaluate to true?

    • Debug to find out.

  • Are the ruleset argument values and return values correct?

    • Debug to find out.

Troubleshooting Custom Extension Points

When troubleshooting custom extension points, check the following:

  • Is the extension point defined in both Design Studio and in a custom aop.xml file?

  • Is the signature defined correctly in both places?

    • Check spacing.

    • Check spelling of package and class names.

  • Regarding the weaver section in the custom aop.xml file:

    • Did you include it?

    • Are the package names correct?

  • Did the cartridge build and deploy successfully?

    • Check the UIM application server log.

  • Is the Weaver turned on?

    • Check the UIM_Home/Domain_Home/bin/setUIMEnv.cmd file.

  • After deploying a cartridge containing custom extension points, did you restart the UIM application server?

    • Check the UIM application server log to see if the custom extension point was successfully weaved into the UIM code stream.

Troubleshooting Configuring a Ruleset to Run at an Extension Point

When using base rulesets and base extension points, base ruleset extension points are not provided. You must configure base rulesets, and custom rulesets, to run at extension points.

  • Did you create a ruleset extension point to configure the ruleset to run?

  • Did you select the correct ruleset?

  • Did you select the correct extension point?

  • Did you select the correct placement of the rule to run before, after, or instead of the method?

    Be mindful of the rule placement. For example, if you are expecting your ruleset custom code to perform a process based on something the extension point method does, and you configure the ruleset to run before or instead of the method, you will not get the results you are expecting.

Troubleshooting Using Timing Events

If you set up rulesets based on timing events, be sure the UIM_Home/config/timers.properties file has the timing event you are using turned on. For example, if you configure a ruleset to run based on the timing of telephone number aging, and the timing event for this is not turned on, your ruleset will never run. For more information on the timers.properties file, see UIM System Administrator's Guide.

Troubleshooting Cartridge Deployment

When deploying a cartridge from Design Studio, you check the following items to ensure you can successfully deploy a cartridge.

Base Cartridges are Deployed

All required base cartridges are deployed into UIM before deploying other cartridges. Oracle recommends that you deploy all base cartridges even if they are not immediately required. See the UIM Cartridge Guide for more information on base cartridges.

Java JDK Version

If you encounter the Design Studio error shown in Example 8-9, the build of your project may be picking up an incorrect version of the Java. (In Example 8-9, cartridgeName is the name of the cartridge you are attempting to deploy, and releaseNumber_buildNumber is the release number and build number of the cartridge you are attempting to deploy.)

Example 8-9 Design Studio Error

Error installing cartridges: {<Cartridge cartridgeName releaseNumber_buildNumber>=java.io.IOException: The model data cannot be imported. Please verify logs for more information.}

In the server log, this error may appear as shown in Example 8-10. In this example, MySampleManager is a Java file in a cartridge that is trying to import MyHelper, which is another file in the same cartridge. However, MySampleManager cannot find MyHelper because MyHelper.java and the other files in the cartridge have inadvertently been compiled with the incorrect version.

Example 8-10 Server Log

2013-09-25 11:30:45,910 ERROR [] [[ACTIVE] ExecuteThread: '11' for queue: 'weblogic.kernel.Default (self-tuning)'] [RulesExecutor] [INV-180014] 
A JBoss Rules compilation error occurred in: SAMPLE_DEVICE_ASSIGN 
Error importing : 
'oracle.communications.inventory.techpack.sample.MyHelper'
java.lang.Exception
at oracle.communications.inventory.extensibility.rules.impl.RulesExecutorImpl.
    getRuleBase(RulesExecutorImpl.java:151)
at oracle.communications.inventory.extensibility.rules.impl.RulesExecutorImpl.
    compileRules(RulesExecutorImpl.java:200)
at oracle.communications.inventory.extensibility.rules.RuleCompiler.run
    (RuleCompiler.java:128)
at weblogic.work.j2ee.J2EEWorkManager$WorkWithListener.run
    (J2EEWorkManager.java:184)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

To resolve this error, verify that you have configured Design Studio correctly, as described in "Configuring Design Studio". In particular, pay close attention to "Configuring the eclipse.ini File" because even though you may have your Eclipse compiler compliance level set correctly, Eclipse can still pick up an incorrect Java JDK if you have more than one Java version installed on your machine. You can also use a decompiler on your class files to verify the correct version of the Java JDK is being used.

Maximum Characteristics for a Table and Required Privileges

While deploying a cartridge, you can need create table privileges on the UIM database schema. Characteristics within a cartridge can require additional database tables by UIM core. This user privilege is required when the number of characteristics per entity exceeds the maximum number of columns (1000) in the table.

The error returned for this situation has the following text:

Error installing cartridges: ...
org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: java.sql.SQLSyntaxErrorException: 
ORA-01031: insufficient privileges 
ORA-06512: at "U734B383.CREATE_CHAR_EXT_TABLE", ...
ORA-06512: at "U734B383.ADD_CHAR_COLUMN_TRIGGER", ... 
ORA-04088: error during execution of trigger 'U734B383.ADD_CHAR_COLUMN_TRIGGER'

If you encounter this error, ensure the user deploying the cartridge has create table privileges for the database.

Existing Custom Extensions Overwritten

This section describes options to resolve the issue when a cartridge deployment is overwriting existing custom extensions. For a cartridge that has a custom aop.xml file, it is possible to overwrite another cartridge's aop.xml file. Try one of the following resolution options:

  • Post-deployment option: Rename the mslv-aop-filter-aop.jar in the custom library before deploying another cartridge having a custom aop.xml file. This custom library resides in the uim_custom_lib.ear file in the UIM_Home/Domain_Home/UIM/app/uim_custom_lib/uim_custom_lib_releaseNumber.version directory, where releaseNumber is the UIM software release and version is the sequential number of changes to the library. You must select the highest existing version. Figure 8-11 shows a sample directory with four versions of the custom library. For this example, the correct directory to select is uim_custom_lib_releaseNumber.0.4 directory.

    Within the EAR file, the JAR file is located in the APP-INF/lib directory.

    Figure 8-11 Sample Directories of Custom Library

    Description of Figure 8-11 follows
    Description of "Figure 8-11 Sample Directories of Custom Library"
  • Pre-deployment option: When you can make the change before deployment, this is a more desirable option that the post-deployment option. Before deploying the cartridge, rename the aop.xml for every custom cartridge that has the XML file in the model/aspects folder to the filename:

    prefixAop.xml

    where prefix is any string value that makes the filename unique. This generates a mslv-aop-filter-prefixAop.jar when the cartridge is built successfully.

  • Clean-up option: To delete or disable a previously deployed ruleset, redeploy the same cartridge with an empty aop.xml file.

See "Creating the aop.xml File" for more information on creating custom aop.xml files.

Upgrading or Converting Rulesets

Rulesets may be written using either Drools or Groovy. The following sections further describe upgrading or converting rulesets in terms of Drools and Groovy.

Note:

This section assumes that you have already upgraded UIM, so have already deployed the base cartridges for the current release, and deployed any applicable cartridge packs for the current release. See UIM Installation Guide for ore information on upgrading UIM.

Upgrading Drools Rulesets

Note:

This section is only applicable if you:

  • Plan to use Drools in this release

  • Are upgrading from a previous release of UIM to UIM 7.2.3 or later

  • Have existing custom rulesets written using Drools

If you plan to use Drools in this release and are new to UIM, this section is not applicable. If you plan to use Groovy in this release, see "Converting Drools Rulesets to Groovy Rulesets".

Previous versions of UIM (before 7.2.3) used Drools 3.0.4, and UIM 7.2.3 and forward uses a later Drools release. The Drools upgrade requires that you upgrade custom rulesets, which may reside in custom cartridges or in extended cartridge packs. See UIM Cartridge Guide for more information on extended cartridge packs.

See "Software Requirements" for information on the Drools version for UIM.

To upgrade custom rulesets:

  1. Configure Design Studio. When upgrading custom rulesets, it is important that you configure your environment correctly to avoid errors later in the process.

    See "Configuring Design Studio".

  2. In Design Studio, recompile all custom rulesets and all custom code your rulesets call.

    See "Validating and Compiling Rulesets" for more information.

  3. If compilation errors are encountered, update custom rulesets and custom code as follows:

    1. Refer to Table 8-1 and update all occurrences of these commonly used 3.0.4 Drools methods to the newer Drools methods.

      Table 8-1 Upgraded Drools Methods

      3.0.4 Drools Method Updated Drools Method

      assert()

      insert()

      assertObject()

      insert()

      assertLogical()

      insertLogical()

      assertLogicalObject()

      insertLogical()

      modify()

      update()

      modifyObject()

      update()

    2. If compilation errors remain, refer to the Drools Knowledge API Javadoc to determine if your custom code calls any other Drools methods that have changed. You can access the Drools Knowledge API Javadoc at the website:

      http://docs.jboss.org/drools/release/5.5.0.Final/knowledge-api-javadoc/index.html

      Then select the Drools version, and knowledge-api-javadoc directory.

  4. Deploy all cartridges containing recompiled custom rulesets and custom code.

    See "Deploying Cartridges Containing Rulesets" for more information.

  5. Test your changes by running the rulesets.

    See "Running Rulesets" for more information.

Converting Drools Rulesets to Groovy Rulesets

Note:

This section is only applicable if you:

  • Plan to use Groovy in this release

  • Are upgrading from a previous release of UIM to UIM 7.3.0 or later

  • Have existing custom rulesets written using Drools that you want to convert to Groovy

If you plan to use Groovy in this release and are new to UIM, this section is not applicable. If you plan to use Drools in this release, see "Upgrading Drools Rulesets".

To convert existing custom rulesets from Drools to Groovy:

  1. In Design Studio, open the Studio Design perspective and the Studio Projects view.

  2. Import the following base cartridges:

    • ora_uim_baserulesets

    • ora_uim_mds

    • ora_uim_model

  3. Import your custom cartridge containing the custom ruleset you are converting.

  4. Expand your custom cartridge that contains the custom ruleset you are converting, and open the custom ruleset.

    The Ruleset editor opens.

  5. Click Browse Drools Code.

    The DRL file opens.

  6. Copy all of the content and close the DRL file.

  7. In the Ruleset editor, click Browse Groovy Code.

    The GROOVY file opens.

  8. Update the rule section of the code.

    Note:

    All of the base rulesets provide both a DRL file and a GROOVY file. Look at the base rulesets for examples of how the code needs to change.

  9. Save and close the GROOVY file.

    When the cartridge is deployed, both the DRL and the GROOVY files are updated in the RULESET database table in UIM.

  10. In the Ruleset editor, click the Run Extension Language list arrow and select GROOVY.

    When the cartridge is deployed, this indicator is updated in the RULESET database table in UIM. At runtime, this indicator tells UIM which file to run; the DRL file or the GROOVY file.

  11. Save and close the Ruleset.

  12. Rebuild the cartridge that contains the ruleset.

  13. Redeploy the cartridge that contains the ruleset into UIM.

Handling Concurrent Scenarios

Sometimes you may be required to concurrently update the entity relationships in the ruleset. For example, for an existing network, there may be a need to add nodes and edges concurrently. Typically, when you concurrently add nodes and edges in a network, there is a possibility of the network getting updated resulting in an Optimistic Locking exception.

To avoid this situation, add the following code in the ruleset to not update the network when nodes and edges are concurrently added to the network:

(NetworkNodeBaseDAO)ntwkNode1).setNetwork(net,false) 

The above code adds the network node to the network without updating the network; however, it is possible that the network in the Eclipselink cache may get out of synch and not contain the newly added node/edge.

To clear the Eclipselink cache, add the following code at the end of the ruleset:

EntityManager em =  PersistenceHelper.makePersistenceManager().getPersistenceManager();
EntityManagerImpl emImpl = (EntityManagerImpl)  JpaHelper.getEntityManager(em);
Cache cache = ((EntityManagerFactoryDelegate)  emImpl.getEntityManagerFactory()).getCache();
cache.evictAll();