Best Practices

Before reading this chapter, review the design questions in Starting Your Model Design to help you identify best practices that are relevant to your Oracle Configurator project.

Applying the following best practices in various combinations will improve the performance, usability, maintenance, and scalability of your configuration models.

Many of these best practices include detailed instructions. You can gain useful information by reading all of them, even though some are not directly connected to a design question. To understand these best practices, you must be familiar with the specifics of creating configuration models. See the Oracle Configurator Developer User’s Guide for details.

This chapter covers the following topics:

Explicit Model Structure Versus Abstractions

Abstraction is a design approach used to optimize performance and usability of a configuration model by reducing many related products or product elements to generic elements and eliminating repetition. Abstraction may also be as simple as merging overlapping sets of data, as described in Are the Same Product Elements Repeated in Separate Models.

Many companies define BOM Models as an explicit representation of their products with no abstractions to streamline the structure or volume of items. (See the graphic Explicit Structure for an example.) Loading all BOM Models and presenting entire product lines to end users for selection may result in poor performance and usability. An alternative approach transforms many explicit BOMs into one root BOM referencing a smaller number of configurable components that are abstractions of related structure. Such a model loads faster, thereby improving performance. Configurator usability is also improved by confining end-user access to only those optionally added instances of the configurable components that are needed in the configuration.

Explicit Structure

Explicit Model structure contains no abstractions and no References. The graphic Explicit Model Structure shows a series of explicit Models, each containing the same BOM Option Class.

The graphic shows a simple Model repeated 1,000 times. Each version consists of a BOM Option Class with a large number of the same Options and another BOM Option Class containing a few unique Options.

Explicit Model Structure

the picture is described in the document text

Explicit Model Structure illustrates 1,000 Models repeating explicitly, each containing repeating elements. One BOM Option Class in each Model contains Options that repeat across the 1,000 BOM Option Classes, while another BOM Option Class contains Options unique to each of the 1,000 BOM Model.

Duplicate structure or common elements that are explicitly repeated in hundreds or thousands of Models do not scale well as your business grows. Many explicit Models with repetitive structure require repetitive maintenance.

It may not be possible or necessary to change your explicit Models to take advantage of abstractions and references, for any of the following reasons:

Permutation

The term permutation refers to a poor modeling practice that adversely affects runtime performance and significantly adds to how much effort is required to maintain a configuration model. This practice can be avoided using the abstraction technique described later in this section.

For example, an end user can select from the following characteristics when configuring a hypothetical product:

Based on these options, there are 240 permutations available to the end user (4 x 20 x 3 = 240). If your solution to this configuration problem is to construct a single Model with Standard Items for each permutation, then the configuration will contain every possible orderable item, although the user will never pick more than one. Such a configuration model will scale very poorly when new items are added in the future. For example, adding a single item (such as a new service level) increases the number of permutations from 240 to 320.

Constructing a Model as an abstraction with 3 Option Classes (one each for Type, Speed, and Service Level) and 27 Standard Items is preferable and will scale much better than the previous example (that is, defining 240 Standard Items). However, downstream applications for manufacturing or provisioning the product or service will require different setups for such a modeling approach. This is one of the trade-offs to consider when evaluating modeling styles.

Another approach is to create a single Model with three attributes that collect information about the Type, Speed, and Service Level that the end user requires. Using configuration attributes is also preferable to the first example, but adds difficulty to the implementation and increases the reliance of downstream applications to process the information that is passed from Oracle Configurator. Configuration attributes are explained in Oracle Configurator Methodologies.

Abstractions

An abstraction is a generic part that expresses all the essential characteristics of a specific part. For example, the related models shown in Explicit Model Structure can be redefined as one top-level root Model containing a BOM Option Class or BOM Model submodel whose contents is M1 through M1,000 redefined as ATO Items. Abstraction of Related Products shows M1 through M1,000 each containing their unique elements as BOM Standard Items. The repeating elements occur only once as a child BOM Option Class under the top-level root Model.

The following graphic shows a top-level root Model abstraction of the 1,000 Models presented in Explicit Model Structure. The repetitive BOM Option Class with the large number of the same Options occurs only once, and another BOM Option Class containing a few unique Options.

Abstraction of Related Products

the picture is described in the document text

The redesign with abstractions shown in Abstraction of Related Products is easier to maintain than the Models in Explicit Model Structure. The number of nodes (per the graphic) has been reduced from 40 to 23, a reduction of 42.5%. See Downstream Consequences in Other Oracle Applications for a discussion of the possible trade-off when choosing this kind of redesign.

Together with optional instantiation and referencing, abstractions perform and scale better than structure containing explicit, related product definitions. For details about referencing and optional instantiation, see Optional and Multiple Instantiation and Explicit Model Structure Versus References. Additionally, turning non-orderable items into alternatives such as Features could further optimize the structure. For details about alternatives to items, see Items Versus Alternatives to Items.

Downstream Consequences in Other Oracle Applications

A separate, explicit ATO Model is sourced from only a single organization or supplier. Multiple sources and option-dependent sourcing are not supported. In the Abstraction of Related Products graphic, all the configured items M1 to M1000 are sourced in the same organization. If you need configurations of these Models to come from different organizations, you need to use an explicit structure such as shown in Explicit Model Structure.

In Abstraction of Related Products, all the configured items M1 to M1000 are built on the same flow line defined in Flow Manufacturing. If you need configurations of these Models to be built on different flow lines, you need to use an explicit structure such as shown in Explicit Model Structure.

Models M1 to M1000 are unique because they contain components (such as Options X1, X2, and so on) available only to one of the Models (M1). The abstraction of Models M1 to M1000 as ATO items in Abstraction of Related Products must include those components as BOM Standard Items under the Option Classes M1 to M1000. For a configuration to contain selections from Options A to ZZ, as well as one of the ATO items, change the BOM Models so Options X1, X2, and so on do not appear under an Option Class. In configurator, you would only see options M1 to M1000 and A to ZZ. All mandatory components (X1, X2, X3 and so on) just appear on the BOM under M1.

Each configuration of the explicit Models M1 to M1000 results in one bill of material and routing definition to build the entire configuration. After moving the abstract top-level root Model, each configuration receives its own bill of material and routing, and each of the ATO item options (M1-M1000) maintains its own bill of material and routing. This can be avoided if M1 to M100 are defined as phantom items. However, phantom items do not participate in Available To Promise (ATP) and Advanced Planning.

Related Best Practices and Relevant Case Studies

Top-level root Models typically access abstract structure through referencing. See Explicit Model Structure Versus References.

Referencing and abstractions alone do not address performance and memory issues associated with instantiating many components at runtime. See Optional and Multiple Instantiation and Grouped Versus Ungrouped Items. See also Items Versus Alternatives to Items.

The case study described in Many Large BOM Models illustrates the use of redesigning explicit structure as abstractions.

Explicit Model Structure Versus References

It is good modeling practice to use referencing instead of explicit structure if your configuration models contain:

Explicit Structure

Explicit Model Structure shows examples of many related products defined explicitly in Models.

Model References

Models with References are easier to maintain and require less memory to load than structure containing explicit common product definitions.

When importing BOMs, all submodels in the top-level root BOM Model are imported as references. See the Oracle Configurator Implementation Guide for information about BOM structure after it has been imported into the CZ schema.

Referencing BOM Option Classes

BOM Option Classes cannot be shared by reference. Redesigning the BOM Option Class in M1 through M1,000 in Explicit Model Structure so that it can be referenced requires turning it into a phantom ATO model containing Option A through Option ZZ. Another Possible Abstraction of Related Products shows the BOM Option Class redefined as a phantom ATO model so that it can be referenced in M1 through M1,000.

The following graphic shows the BOM Option Class with the large number of the same Options in the previous figure now changed into an ATO Model. The 1,000 explicit Models each contain a reference to the ATO Model.

Another Possible Abstraction of Related Products

the picture is described in the document text

Changing BOM Option Classes into BOM Models has the following consequences within Oracle Configurator:

Note: If you have redesigned BOM Option Classes as phantom ATO Models, you cannot specify a value greater than 1 to the Instances Maximum.

Non-Imported Model References

Referencing is a technique used to optimize development and maintenance of a configuration model in which the same submodel appears multiple times in the structure. Replacing each explicit occurrence of the submodel with References to a separate Model that represents the submodel can also improve runtime performance. Additionally, it is a good idea to place a Component with repetitive structure within a non-imported Model and then create References to that Model. See the Oracle Configurator Developer User’s Guide for information about using Model referencing in configuration models.

Downstream Consequences in Other Oracle Applications

A BOM submodel behaves like a BOM Option Class in most of the Oracle Applications if you leave the Supply Type of the BOM submodel set to phantom on its parent BOM Model.

In Flow Manufacturing, some conveniences in defining BOM Option Classes are not available when defining BOM Models. For example, you cannot create a common routing for all BOM Models as you can for all BOM Option Classes under a parent BOM Model.

Related Best Practices and Relevant Case Studies

Referencing is used when creating abstractions. See Explicit Model Structure Versus Abstractions.

See Many Large BOM Models.

Optional and Multiple Instantiation

Optional instantiation is an implementation approach used to optimize performance of a configuration model by creating a component instance only if and when it is needed. This prevents Oracle Configurator from loading model elements at initialization that may not be selected or needed in the configuration session.

Multiple instantiation is an implementation approach used to optimize usability by allowing end users to create and individually configure multiple occurrences of a Model or Component at runtime, as needed. For more information about multiple instantiation, see the Oracle Configurator Developer User’s Guide.

Optional Instantiation of BOM Option Classes

It is good modeling practice to convert a large hierarchy of BOM Option Classes to a hierarchy of optionally instantiable BOM Models. For guidance in converting BOM Option Classes into BOM Models, see Referencing BOM Option Classes. The selective instantiation improves runtime memory usage and reduces caching of redundant data. For example, if M1 through M1,000 in Explicit Model Structure contained more structure, as shown in Explicit Nested Hierarchy, the resulting large number of Model elements that need to be loaded and instantiated could affect performance and usability adversely.

The following graphic shows an ATO Model containing a BOM Option Class with several child BOM Option Classes, each with unique Options.

Explicit Nested Hierarchy

the picture is described in the document text

Rather than load all the explicit, nested BOM Option Classes of Explicit Nested Hierarchy, define them once as BOM Models and include them by reference in M1 through M1,000, as shown in Referenced Nested Hierarchy. Be aware of the consequences of changing BOM Option Classes into BOM Models, as described in Referencing BOM Option Classes.

The graphic Referenced Nested Hierarchy shows the ATO Model from the previous figure now with references to a submodel containing references to child Models that in the previous figure were the nested BOM Option Classes.

Referenced Nested Hierarchy

the picture is described in the document text

To save additional memory and improve runtime performance, make the References in Referenced Nested Hierarchy optionally instantiable.

Not loading instances at start up and instead implementing optional instantiation can result in significant performance improvement. However, requiring end users to instantiate many components interactively one at a time may affect usability. Instead, implement guided buying or selling to find out how many instances the end user needs and implement a Configurator Extension that instantiates that number of components all at the same time.

With optional instantiation, as with multiple instantiation, instances cannot be created using rules. Either the minimum is set, the end user clicks an Add button, or a Configurator Extension adds instances based on inputs. Using optional instantiation in a generated UI of the BOM structure results in Add buttons that end users must understand how to use to complete a configuration. If your end users are not product experts, consider using guided buying or selling questions. See Guided Buying or Selling for details.

Setting Node Values After Adding Instances

Design your UI flow and Configurator Extension so that instances are added when there are as few settings as possible. Adding an instance causes all previous requests to be retracted, after which the requests are added and reasserted. This occurs with each component addition. It is good modeling practice to delay setting the states or values of nodes until after all instances are added either at startup (with a Configurator Extension bound to the postConfigNew event) or early in the end-user flow of a configuration session. See also The postConfigNew Configurator Extension.

Adding an instance is particularly expensive when there are default values set by configuration rules. Retracting default assertions is time-consuming and iterative. See Defaults Rules Versus Alternatives to Default Selections for details. The initial values set in Configurator Developer for Boolean Features should also be regarded as default values.

Downstream Consequences in Other Oracle Applications

See Downstream Consequences in Other Oracle Applications for the effects on Oracle Applications of changing a BOM Option Class into a BOM Model.

Multiple instantiation of submodels is only available if the parent ATO BOM Model’s Supply Type is set to non-phantom. This means that each configured instance of the Model receives its own configuration Item number, bill of material, and routing, and is built or bought individually.

Large Numbers of Instances

If your Model has large numbers of instances, check for similarity among instances. If many sibling components are nearly identical, meaning they only differ in the value of their attributes and are not distinguished by connectivity, consider representing the entire set of instances as a single instance. You can store the set of attribute values offline or in a custom table.

Related Best Practices and Relevant Case Studies

See Explicit Model Structure Versus References.

See Large Option Features and Option Classes.

See Many Large BOM Models.

Guided Buying or Selling

Guided buying or selling questions are intended to guide end users to specific selections and valid configurations.

The size or complexity of your Model may cause usability or performance problems at runtime. Large models, even if not complex, may require large amounts of memory to load, or require end users to make many selections or page through many options. Complex models, even if not large, may require long end-user think time and complicated navigation. Under these circumstances, you can simplify or streamline the end-user’s experience by defining guided buying or selling structure.

Guided buying or selling questions gather user inputs to accomplish any of the following scenarios:

You implement these behaviors by adding rules that tie the end-user inputs to the selection or exclusion of options.

Generating a default UI for a large imported BOM may result in an unreasonably large and poorly performing runtime session. You can use guided buying or selling UI structure to control which elements of the imported BOM you want exposed and visible in the UI. This requires defining rules that associate the guided buying or selling UI structure to the BOM Model items and disabling the UI visibility attribute of the BOM nodes before generating the UI.

Manufacturing vs. Sales View of a Model

In many cases, the Sales and the Manufacturing organizations of a company have very different views of the product definition. This can driven by several factors, including:

For companies that were previously using two separate configuration solutions for their Sales and Manufacturing operations, the result may be two separate configuration models and the need to "translate" Sales configurations into Manufacturing configurations when an order is sent to production.

With Oracle Configurator, the same configuration model is shared by the entire Enterprise, and requirements from the different divisions that are involved in the configuration process need to be considered throughout the configuration model design phase.

As a Configurator model designer, you may want to use your current Manufacturing structure as the basis for your configuration model, and create additional structure to satisfy Sales requirements, adding configuration rules to map the Sales options to Manufacturing rules. This approach can lead to performance issues as it increases the size of the model and the number of rules. Instead, the recommended approach is to review and modify (if necessary) your Manufacturing structure to accommodate Sales requirements, thereby optimizing your configuration model's performance and usability. For example, you can expose Manufacturing options to end users by giving the related item a user-friendly description and then displaying the description (rather than the item name) in the Configurator User Interface.

In most cases, using the current Manufacturing structure is not recommended. Be sure to evaluate whether functionality in Oracle Configure to Order (CTO) or other applications will permit changes to the model design that benefits deployment and minimizes the amount of future maintenance.

Shallow Versus Nested or Deep Hierarchy

The depth of Model structure is determined by the levels of hierarchy contained under the root node. Shallow structure is acceptable when not displaying BOM nodes in the UI. A shallow structure generally decreases the size of the configuration model and potentially eases downstream processing.

Deeply nested structure takes advantage of the performance gains made when using optional instantiation to load only those parts of the Model structure that are needed. Nesting items into deeper structure can also ease Model maintenance. However, deep nesting may distribute end-user selections across UI pages in a manner that requires end users to flip back and forth as they check previous selections. When this is the case, guided buying or selling questions can significantly ease navigation flow. See Guided Buying or Selling for additional information about guided buying or selling.

Related Best Practices

See Explicit Model Structure Versus References for descriptions of nested structure. Nested or deep hierarchy affects performance when used with optional instantiation. See Optional and Multiple Instantiation.

Relevant Case Studies

See Many Large BOM Models and Many BOM Items.

Items Versus Alternatives to Items

Items either need to appear on the order line, or they need to represent characteristics that are needed as input somewhere in the process. Some item information is only needed as a temporary value during configuration.

You should define Inventory Items only for elements of your structure that need to be ordered or routed downstream from Oracle Configurator. For example, elements of Model structure that must appear on an order line and are picked or assembled for shipping need to be Inventory Items.

Alternatives to Inventory Items are Option Features or configuration attributes. For upstream item information that is needed in Configurator computations or for downstream processing such as calculations or passing along information about an item, you should define an alternative to Items.

For example, if you have raw materials that are ordered by lengths, do not create an item for each length. Instead, define a single item for each raw material with an attribute: Length. Then capture the needed length from the end user by a numeric input or from a List of Options, and associate that input with the attribute.

For another example of changing explicit items into Features, compare Explicit Model Structure with Abstraction of Related Products.

For more information about configuration attributes, see Oracle Configurator Methodologies.

Values Needed For Configuration Only

If the value is not needed in any way downstream but only for completing the configuration, use non-BOM Features and Options. These values cannot participate in downstream calculations.

For information about leveraging the power of Properties, see Oracle Configurator Developer User’s Guide.

Values Needed Downstream

If the value is needed downstream, such as in Fulfillment or Billing Integration, and represents a Configurator computation or inputs from the end user, you can define configuration attributes to pass along those inputs. For performance reasons, it is optimal to define as few attributes as possible. Omit Feature and attribute definitions from your Model structure whose values can be referenced from other Model structure or computed in custom code downstream from other attributes. If a value cannot be referenced or computed using custom code, minimize the set of attributes and Features you define in the Model structure. If an attribute is shared among multiple components, use inheritance to share the Feature in which the attribute is defined.

See Oracle Configurator Methodologies for details about implementing configuration attributes. Note that configuration attributes are not accessible to downstream applications without customization.

For example, consider a Container Model that defines a configurable Public Switched Telephone network (PSTN). The top-level Model contains two Components: Primary Line (1/1) and Child Line (29/29). Each Component contains Items (such as Application Date and Billing Date) that have been modeled as attributes of Features and are required for downstream processing. All the Features are hidden in the runtime UI. A Configurator Extension rule gets the required attribute values from custom code outside Configurator and copies the values for the model and its submodels. The duplication of data across many models and the process of copying the values causes poor performance when the configuration is saved, restored, or during batch validation.

For details about using the type of attributes referred to in this example, refer to the method for using configuration attributes with Install Base that is described in the Oracle Telecommunications Service Ordering Process Guide.

The graphic Model Design with Minimal Set of Features, shows a better Model design that moves all the duplicated common attribute Features to the top-level Container model.

Model Design with Minimal Set of Features

the picture is described in the document text

The design includes attribute Features for unique attributes at the individual Model level. A Configurator Extension copies the value from the custom application to the top-level Features. Attribute Mode set to ALL propagates the value from the top-level Model to all the submodels.

Related Best Practices and Relevant Case Studies

See Many BOM Items.

Large Option Features and Option Classes

If your Model contains large BOM Option Classes or Option Features, evaluate the following best practices for possible use in your project:

If your design cannot eliminate the need for configuring BOM Option Classes with large numbers (for example, hundreds) of Items, be aware that the Generic Configurator UI does not perform faster than a generated Configurator UI. With the generated Configurator UI you can use multiple screens to display BOM Option Classes with large numbers of Items. If you are using guided buying or selling questions, hide all the Items and have the guided selling questions drive the selections. See Guided Buying or Selling for more information.

Grouped Versus Ungrouped Items

In cases where there are many options to choose from, the end user’s experience and Oracle Configurator performance can be improved by grouping items into BOM Option Classes. Typically, you can improve usability and performance by combining grouping with the use of optional instantiation. This requires changing BOM Option Classes into BOM Models. See Optional Instantiation of BOM Option Classes for details.

For example, a manufacturer of upholstered furniture lets customers select fabrics from a huge inventory, including solids, stripes, floral prints, and geometric patterns. Rather than have end users flip through screen after screen of swatches in no particular order, the configuration experience can be organized by types of fabrics, and only the group that is selected needs to be loaded into memory. End users select one from a subset of fabrics, thereby reducing the number of displayed options. The inventory that does not need to be displayed to the end user is not instantiated.

Grouping items can also ease Model maintenance.

Maximum Selections on Large Option Classes or Features

Defining a Maximum Selections on a large BOM Option Class or Option Feature can adversely affect performance. If an Option Feature contains an Option that participates in a rule, propagation of that rule triggers a count of the current number of selected Options. If the maximum number of Options specified by the value of Maximum Selections is reached, this rule propagates Logic False to all unselected Options. If the number of Options is large, propagating Logic False or retracting and reasserting the logic state on all the Options can cause slow performance.

The best way to improve performance is to restructure the Model or BOM Model to contain Option Features or BOM Option Classes with fewer Options or Items.

If your business requirements demand many options and a maximum number that can be selected, and you need the remaining options to be Logic False after the maximum is reached, then you must set the Maximum Selections and incur the performance cost.

However, since the runtime display icons for both Logic False (from maximum reached) and Unknown states indicate that an Option is available for selection, your logic requirements may permit you to set the Maximum Selections to no value and define the number of allowable selections by using a rule that counts the selected Options. For example, if you want only three Options to be selected from a Feature, impose that maximum by defining a Total, a Numeric Rule, and a Logic Rule with CDL or as a Statement Rule as shown in Maximum Selections Imposed by a Rule.

Maximum Selections Imposed by a Rule

One Feature, F1, contains five Options, and a second Feature, AlwaysTrue, contains one Option, as shown in the following design:

the picture is described in the document text

The rules:

Total T1 tracks the number of options selected.
Numeric Rule: EachOf (Options of F1) Contributes 1 to T1
Statement Rule expressing a Logic Rule with the following expression for
Operand 2: AlwaysTrue Requires Total < 4

At runtime, when the end user selects O1, O2, and O3, the number of selections is less than 4. When the end user selects O4, the Logic Rule displays a violation message. The violation message can be customized to explain that the maximum number of allowable selections has been exceeded.

If your business requirements demand many options and a maximum number that can be selected, and it does not matter to your implementation whether Options are Unknown or Logic False, then having them be Unknown is better. The Oracle Configurator engine does not push the Unknown state to other options that are connected through rules, except if NotTrue is used. Design your configuration model so that valid configurations are allowed even when numerous Options are Unknown. That way the CIO and the Oracle Configurator engine process fewer changes on each end-user action. For example, use the suggested rule for counting selected options to minimize the propagated Logic False states, instead of the regular Maximum Selections.

Alternatives to Option Features With Many Options

When an Option from a large Option Feature participates in a rule, the propagation of that rule triggers an evaluation of all that Feature’s other Options. (This does not apply to BOM Option Classes and BOM Standard Items.) However, if no Options participate in rules or the Option Feature is not constrained by a maximum number of Options that can be selected, redesign the Options as Boolean Features. Create a Component containing the Boolean Features or design all selectable Options as BOM structure.

Redesigning Unconstrained Options as Boolean Features

A Feature called Finish contains four independent furniture finishing Options, Polish, Stain, Varnish, and Paint, as shown in the following design:

the picture is described in the document text

Since end users can select any Option independent of the other Option selections, it is better to define a Component containing a Boolean Feature for each Option.

Relevant Case Studies

See Many BOM Items.

Defaults Rules Versus Alternatives to Default Selections

Defaults Logic Rules reduce the number of required end-user selections by providing the following:

Some implementations of Defaults relation can cause performance problems at runtime, especially when propagation of the defaulted items affects many other items. This is because the Oracle Configurator engine retracts default values before applying or reapplying user requests or adding or deleting components.

Evaluating the Need for Default Selections

When designing a configuration model, add Defaults Logic Rules at the end of the design process and weigh the performance cost of adding them against the perceived benefit to the end user.

The following considerations can help you determine the usefulness of setting initial values:

Activating Defaults on End User Request

If you intend to apply default values to complete the configuration session rather than set selections during the configuration session, design the Defaults Logic Rules so they are not processed at runtime until the end user requests them. For example, create a Boolean Feature at the root of the Model for this purpose. This Boolean Feature could be called ApplyDefaults.

  1. Create a Statement Rule with Operand 1 of the Defaults relation defining a condition.

  2. In every Defaults relation, replace

    X Defaults Y

    where X is the condition, and Y is the result, with

    AllTrue (X, ApplyDefaults) Defaults Y

    Note that it is enough to define this rule as AllTrue (Apply Defaults) if X is always true.

  3. Write a Configurator Extension bound to the preConfigSave event that sets the ApplyDefaults Boolean Feature to True. This causes applicable Defaults to be applied so their consequences appear in the output.

  4. Write a Configurator Extension bound to the postConfigRestore event that unsets ApplyDefaults. This allows the configuration session to proceed in the absence of defaults. Since this Configurator Extension could cause unnecessary work during batch validation, consider using Step 5.

  5. Optionally, make the ApplyDefaults Boolean Feature visible in the User Interface so the end user can turn it on and see the consequences of the Defaults. Since this is expensive in terms of performance, the end user might elect to use it sparingly.

If you do not make the ApplyDefaults Boolean Feature visible, line items and prices may appear in the order that the end user was not aware of during the configuration session.

Boolean Features With Initial Values

Boolean Features with an initial value (True or False) cause slow performance because they behave like Defaults Logic Rules. Leaving the initial value Unknown improves performance.

The postConfigNew Configurator Extension

A Configurator Extension bound to the postConfigNew event simulates the behavior of setting initial default values, but avoids the cost of repeatedly retracting and reapplying default values after the end user makes selections involving Defaults relation participants. However, there are consequences to using the Configurator Extension that you should consider. Defaults Rule Behavior at Runtime and Configurator Extension That Simulates Defaults Rule show the differences in behavior during the runtime selection process between Defaults relations and Configurator Extensions that simulate Defaults relations.

Defaults Rule Behavior at Runtime

Two Features contain different Options, as shown in the following design: Feature F1 contains Options A, B, and C. Feature F2 contains Options D, E, and F.

the picture is described in the document text

The rules:

F1 has a Maximum Selections set to 1
F1 Defaults A
E Requires B

At startup, A is selected. When the end user selects E, Option B is selected and A is deselected. No contradiction occurs in this example.

Configurator Extension That Simulates Defaults Rule

Using the same two Features shown in Defaults Rule Behavior at Runtime, define the following rules:

Configurator Extension selects A
E Requires B

When the configuration session begins, Option A is selected. The end user selects Option E. Oracle Configurator displays a contradiction message asking whether the end user wants to override the contradiction and select Option B. This is because settings made by the Configurator Extension have the status of an end-user request.

Implies Relation Instead of Defaults Relation

In some rare cases, an Implies relation can be used instead of a Defaults relation if your end users do not need the flexibility to change the default value.

Implies Rule Provides Behavior of an Unoverridable Defaults Rule

Two Features contain different Options, as shown in the following design: Feature F1 contains Options 1, 2, and 3. Feature F2 contains Options 4, 5, and 6.

the picture is described in the document text

The rules:

Option 1 Defaults Option 4
or
Option 1 Implies Option 4

At runtime, both rules cause Option 4 to become selected when the end user selects Option 1. The Defaults relation gives end users the flexibility to override the default value and select Option 5 or Option 6 when Option 1 is selected. If you your end users do not need that flexibility, use the Implies relation and only Option 4 can be selected when Option 1 is selected.

Default Rule Idiosyncrasies

When designing Defaults rules, avoid overlapping rules as this can cause unexpected behavior at runtime. Rules overlap when they both contain the same node (or nodes) as participants.

For example, in Model A, Features Y and Z are siblings (that is, they appear at the same level in the Model structure). You define the following rules:

All True (A, B) Defaults Y
All True (A, B, C) Defaults Z 

When A, B and C are all true at runtime, neither Y nor Z will be selected by default consistently. In other words, sometimes Y will be selected by default and sometimes Z will be selected by default. To avoid this kind of unintended behavior, be very explicit when defining Defaults rules.

To implement the rules in this example properly, define the first rule as follows:

All True (A, B, Not (C)) Defaults Y

Repetitive Rule Patterns and Redundancy

Repetitive patterns or redundancy means that several rules include the same subexpressions or have the same result. This could cause performance issues.

Repetitive Patterns and Common Subexpressions

The Oracle Configurator engine separately evaluates and propagates each instance of the subexpressions of every rule, even if there are commonly used patterns of operators and operands in those subexpressions. Consequently, a large number of rules with common subexpressions impairs performance by triggering redundant calculations of the subexpressions. (A subexpression provides a calculation result that is subsequently used as a term in a parent expression.)

Subexpressions are defined within a pair of parentheses, and every pair of parentheses is treated as a subexpression using the conventional order of operations.

Rules With Common Subexpressions shows two rules containing a common calculation contributing to a Resource.

Rules With Common Subexpressions

[(A + B) * C] contributes to R1

[(A + B) * C] + D contributes to R2

Create an intermediate node (I1) to contain the value of the commonly used subexpression and create an intermediate rule that contains the subexpression [(A + B) * C] and the intermediate node:

[(A + B) * C] contributes to I1

The original rules can then be rewritten by replacing the common subexpression with the new node that expresses the intermediate rule.

I1 contributes to R1

I1 + D contributes to R2

Although this technique creates an additional rule (the definition of the common subexpression), the effect of replacing repeating patterns in rules with nodes that represent those patterns is that Oracle Configurator only computes the subexpression once, thereby reducing the calculation required for each rule containing the common subexpression.

Note: When you use the technique of replacing common subexpressions with intermediate nodes, you must customize the violation message of the intermediate rule to explain the contradiction in terms of the rules that contain the intermediate rule. In other words, the default violation message for I1 in Rules With Common Subexpressions, which is displayed to the end user when Oracle Configurator encounters a problem with R1 or R2, describes a contradiction in I1 unless you customize the message to explain the error in terms of R1 and R2.

Redundancy

Redundancy occurs when you unintentionally create multiple rules that perform the same function in a configuration model. Executing redundant rules at runtime is inefficient and contributes to poor performance. Redundant rules are most often Logic Rules, and when they are of this type they are more difficult to detect when unit testing.

Redundant Rules: Simple Example shows two redundant rules.

Redundant Rules: Simple Example

Note, however, that the following rules are not redundant (since the Implies relation is not bidirectional):

The following example shows two more rules that perform the same purpose.

Redundant Subexpression

In Redundant Subexpression, Rule 2 overlaps Rule 1 because it contains the same options (A, B, X, and Y) and performs the same purpose as Rule 1 (they both ensure that options X and Y are selected when A and B are selected).

It is also important to understand what kinds of runtime behavior Oracle Confgurator inherently provides to be sure that you do not create rules that accomplish the same tasks. For example, Rules that Perform Unnecessary Actions shows a rule that performs an action that Oracle Configurator does implicitly.

Rules that Perform Unnecessary Actions

Model A contains Feature X, and Feature X has three Options: A, B, and C. Model A also has the following rule:

AnyTrue('Option A', 'Option B', 'Option C') Implies AnyTrue('Option Feature X')

When an end user selects any of a Feature X's Options, Oracle Configurator automatically selects Feature X. It is therefore not necessary to define a rule that does the same thing.

Circular Propagation

Circular rules may involve both Logic and Numeric Rules. In some cases this may result in Oracle Configurator not being able to settle on a final result. Circular Rules (Logic and Numeric) shows four rules that are circular.

Circular Rules (Logic and Numeric)

A Contributes A.count() to B

B Contributes B.count() to C

C Requires D

D Contributes D.count() to A

Examine all possible actions or inputs and their results to show where the propagation path does not settle on a result but cycles through the rule again and again. In Circular Rules (Logic and Numeric), the following sequence of events occur when you set A to 3:

Set A =3
B is set to 3, and true
C is set to 3, and true
D is set to 1, and true
A is set to 4, and true
B is set to 4, and true
C is set to 4, and true

The circularity stops at this point, because D is already set to 1, and true.

Circular Numeric Rules may cause numeric cycles, as shown in Numeric Cycles.

Numeric Cycles

A Contributes A.count() to B

B Contributes B.count() to C

C Contributes C.count() to A

In Numeric Cycles, the following sequence of events occur when you set A to 3:

Set A =3
B is set to 3, and True
C is set to 3, and True
A is set to 6, and True
B is set to 6, and True
C is set to 6, and True
A is set to 9, and True

Examining all possible actions or inputs and their results suggests that these rules would continue to propagate without end. However, Oracle Configurator catches the error in Numeric Cycles as a runtime numeric cycle failure.

The circular rules may not be obvious. Imported BOM Models automatically enforce Bill of Material quantity cascade, which can be thought of as Numeric Rules. Attempting to contribute the quantity of a Standard Item to it's parent Option Class or any other ancestor node in the model hierarchy will result in a circular rule.

Optimize the configuration problem to avoid creating rules that create cycles.

One way to debug redundancy and cycles is to turn rules on or off by explicitly disabling them at the rule or Folder level. For a review of logic states and other information related to rules, see the Oracle Configurator Developer User’s Guide. See the Oracle Configurator Performance Guide for a discussion about the effect of the quantity and complexity of rules on runtime performance.

Number and Complexity of Rules

Complex or large numbers of rules within a configuration model could cause slow performance. Whenever possible, use effectivity dates or Usages to turn off rules that are not necessary in certain contexts of the calling application. That lets the Oracle Configurator engine ignore those rules and propagate among the enabled rules more efficiently. When debugging configuration models, disable rules explicitly at the rule or rule folder level to let the Oracle Configurator engine ignore them. For information on Property-based Compatibility rules, see Minimizing the Size and Complexity of Property-based Compatibility Rules.

Large numbers of rules with commonly used subexpressions also cause slow performance. When the Oracle Configurator engine propagates such rules, even if there are commonly used patterns of operators and operands, the engine needs to evaluate and propagate each instance of the common subexpression separately.

Consider Rules With Common Subexpressions showing two rules with a common calculation contributing to a Resource.

Rules With Common Subexpressions

[(A + B) * C] contributes to R1

[(A + B) * C] + D contributes to R2

Create an intermediate node (I1) for the commonly used subexpression and create an intermediate rule that contains the subexpression [(A+B)*C] and the intermediate node.

[(A+B*C] contributes to I1

The original rules can then be rewritten by replacing the common subexpression with the new node that expresses the intermediary rule.

I1 contributes to R1

I1+D contributes to R2

Although this technique creates an additional rule, the net effect of replacing repeating patterns in rules with nodes that represent those patterns is that the Oracle Configurator only computes the subexpression once, thereby reducing the amount of calculation required for each rule that contains the common subexpression.

Warning: When you use the technique of replacing common subexpressions with intermediate nodes, you must customize the violation message of the intermediary rule to explain the contradiction in terms of the rules that contain the intermediary rule. In other words, the default violation message for I1 in Rules With Common Subexpressions, which is displayed to the end user when Oracle Configurator encounters a problem with R1 or R2, describes a contradiction in I1 unless you customize the message to explain the error in terms of R1 and R2.

NotTrue Logical Function Imposes Order and Causes Locking

The logical function NotTrue is used in CDL and Statement Rules.

Order Dependency Caused By NotTrue

Using NotTrue in a Statement Rule can impose an order for rule propagation that makes the configuration model harder to design and use. Rule order diminishes the flexibility with which end users make selections. For example, if the intention is to have one Option, Y, not be selected until another Option, X, is selected, then using NotTrue achieves this result, but alternative rule definitions have a similar effect without causing order dependency.

If the rule is NotTrue(X) Excludes Y, the following occurs at runtime:

  1. Initially, X is unknown and Y is not available for selection (false).

  2. When X is selected (true), Y becomes unknown, or available for selection. If Y is selected, X remains true.

  3. If X is deselected (false), Y becomes false.

If you want Y to be unavailable for selection until X is selected, you need to use NotTrue(X) and incur the cost of imposed order in the rule propagation. If you only need to make sure that Y is never selected when X is not selected, you can express this with less restrictive alternative rules

For example, Not(X) Excludes Y preserves the original intent of ensuring that Y cannot be true without X being true, but X can be true without Y being true. If the rule is Not(X) Excludes Y, the following occurs at runtime:

  1. Initially, X is unknown and Y is unknown, or available for selection.

  2. When X is selected (true), Y remains unknown. If Y is selected (true), X becomes selected (true).

  3. If X is deselected (false), Y becomes deselected (false).

Both these rules use a double negative (which may be difficult to understand) and a subexpression (which compromises efficiency).

An optimal alternative rule is Y Implies X, which imposes no order and avoids the double negative and subexpression of the previous alternative. If the rule is Y Implies X, the following occurs at runtime:

  1. Initially both X and Y are unknown and available for selection.

  2. When Y is selected (true), X becomes selected (true).

  3. If X is deselected (false), Y becomes deselected (false).

Although this rule preserves the original intent of ensuring that Y cannot be in a sales order without X, it does not allow X to be in the sales order without Y.

Note that in release 11.5.10 and later, a simpler and more efficient approach is to define a display condition to prevent Y from appearing in the UI until X is selected. Display conditions are explained in the Oracle Configurator Developer User's Guide.

Locked States Caused By NotTrue

Using NotTrue can result in a locked state for the initial values of some items. In the following example, Model X contains the following structure:

Option Feature A, containing some Options

Option Feature B, containing some Options

Your project requires that Feature B should be false and not displayed to the end user until an Option in Feature A is selected.

When an Option in Feature A is selected, Feature B should be true and displayed to the end user. End users must select an Option from Feature B to satisfy the configuration.

The following rules fulfill these requirements:

Rule 1: NotTrue(A) Excludes B
Rule 2: A Implies B

Initially, as a consequence of Rule 1, A is unknown and B is false. As a consequence of Rule 2, A is made false when B is false. Rule 1 and Rule 2 together result in both A and B being false, which is a locked state. Changing the state of either A or B results in a contradiction.

To accomplish the intent of Rule 1 without locking, create a display condition in Oracle Configurator Developer that hides Feature B until an Option in Feature A is selected.

Locking also results from embedding a NotTrue expression within a series of rules involving the same operands. Consider the following rule:

NotTrue(A) Implies B

If A is an Option of a Feature whose other Options participate in other rules that side effect A and B (such as through a maximum number of selections setting), then A being NotTrue locks the series of rules from completing. To avoid this locking, do not use the participants of a NotTrue expression in any other rules.

For more information about logic states, display conditions, and other information related to rules, see the Oracle Configurator Developer User’s Guide.

Compatibility Rules

When you want to express compatibility, use Compatibility Rules instead of Logic Rules. The Oracle Configurator engine performs calculations over a large number of Options faster with Compatibility Rules than with any other rule type.

However, consider the following when designing compatibilities or incompatibilities among items in your Model:

These guidelines are explained in the following sections.

Expressing Compatibility Using Properties

Explicit Compatibility Rules defined with a large number of participants are difficult to maintain and can cause performance problems at runtime. It may be better to express the compatibility among options by using a Property-based Compatibility Rule.

For example, power supply voltage for a personal computer is determined by the voltage used in the country where the computer will be used. The United States is compatible with a 110 volt power supply, while France and India are compatible with a 220 volt power supply. You can create a Property-based Compatibility Rule to enforce this relationship at runtime.

The Model for this example includes a Feature named "Country" and a BOM Option Class named "Power Supply Type." Preliminary steps in creating this rule are to define a Property named "Voltage Needed" for the Feature and to define a Property named "Voltage Supplied" for the BOM Option Class.

The table below lists the Options of the Feature called “Country,” as well as each Option's Property and Property Values.

Option Name Property Value
USA Voltage Value 110
France Voltage Value 220
India Voltage Value 220

The following table lists the options within the Power Supply Type BOM Option Class, as well as each option's Property and Property Value.

Option Name Property Value
110V Voltage Value 110
220V Voltage Value 220

The final step is to create the following Property-based Compatibility Rule that links the Country Feature selected at runtime to the Power Supply Type BOM Option Class voltage specified for the computer:

Operand 1:

Operator:

Operand 2:

At runtime, when the end user makes a selection for the Country (Feature), the value for the Voltage Value Property is determined. The Property-based Compatibility Rule matches the value of the BOM Option Class Voltage Value to the value of the Feature Property Voltage Value.

In this example, a Property-based Compatibility Rule design performs better than an Explicit Compatibility Rule defining particular power supply types and the voltages or countries with which they are incompatible. Maintenance is also streamlined. For example, when you add a new country, you add only the Voltage Value Property rather than modifying the rule to add the new compatibility. Or if a country changed its line voltage, the change could be reflected in your Model by changing the value of the Voltage Value Property.

If you needed to express compatibility between country and currency, the problem would be more complex and the maintenance advantages of the Property-based Compatibility solution even greater.

Minimizing Participants in a Compatibility

To express compatibility among Options by using Compatibility Rules, it is better to design several Compatibility Rules with fewer participants than to define one Compatibility Rule with many participants.

Using the Excludes Relation to Express Incompatibilities

If your Compatibility Rule defines a larger number of compatibilities than incompatibilities, consider defining the incompatibilities by using Excludes relations. For example, a Compatibility table contains compatibility between six Features, each with two Options. This is shown in Compatibility Table.

The following table lists the compatibilities among the two Options (A and B) and six Features. A1 and A2 are compatible with B1 and B2. A3 is compatible with B1 only.

Compatibility Table
A B
A1 B1
A1 B2
A2 B1
A2 B2
A3 B1

In this Compatibility table, the only incompatibility exists between Options A3 and B2. In this case, it would be better to express the incompatibility between A3 and B2 in an Excludes relation.

Minimizing the Size and Complexity of Property-based Compatibility Rules

Property-based relationships between large BOM Option Classes can be implemented more efficiently by introducing Property Features that correspond directly to Properties, with options corresponding to the Property values. Relationships between Property values are then expressed on these smaller Features instead of directly on the Option Classes. Property-based Compatibility Rules are then used to relate the Option Classes and the Property Features. This can result in improved runtime performance and shorter times to generate logic and load a configuration model. Property Features may also provide a shortcut to a needs-based Configurator User Interface.

One of the best ways to make a configuration model simple to define and easy to maintain is to base as many of the rules as possible on Property relationships and avoid the explicit use of options unless absolutely necessary. A possible solution is the use of the Constraint Definition Language's (CDL) 'FOR ALL' expression with Property-based WHERE clauses.

However, there is a negative aspect to this approach. The statement of a Property-based Compatibility or the CDL's FOR ALL...WHERE rule can be deceptively simple. If the Features or Option Classes used in the rule have a large number of options, the rule can expand into large and complex logic within the Configurator Engine. This large and complex logic can result in time-consuming generation of logic in Configurator Developer and poor runtime performance. The best way to avoid this situation is to keep in mind the number of explicit relationships implied by the Property-based expression and take steps to minimize it.

Large Number of Options

A model has two Option Classes, A and B. Each Option Class has a large number of options, for example 1000. The options of A have a Property X, the options of B have a Property Y, and an option of A is compatible with an option of B when A.X = B.Y. This relationship can be expressed as a Property-based Compatibility Rule.

Now suppose that X and Y each have 20 distinct values, more or less evenly distributed, so on average each option of A is compatible with 50 options of B. Expressing the relationship as an Explicit Compatibility Rule between A and B would result in each option of A appearing in 50 rows of the table, and the table would contain 50,000 rows (1000 x 50). This illustrates the complexity of the rule as compiled by logic generation. Because this is a very large rule, compiling the logic takes a long time and runtime performance is adversely affected.

The logic of this relationship can be simplified by creating "Property Features." A Property Feature should have Options that correspond to each possible value of the Property, and these Options should each contain the Property in question. Typically, a Property Feature represents a Property of the items of a specific Option Class. It is also possible for a single Property Feature to correspond to multiple Option Classes whose options come from the same catalog. A Property Feature is related to its corresponding Option Class via a Property-based Compatibility Rule, with a condition 'PropertyFeature.Property = OptionClass.Property'.

Property Features can be created easily using a Populator.

  1. Manually create a Feature.

  2. Define a Populator on the Feature: Select Property Values as the Source and Options as the Destination. Select the Item Type of the Items in the corresponding Option Class and a Property of the selected Item Type. The Populator will automatically attach the specified Property to the Options it creates.

After creating the Populator, create the Property-based Compatibility Rule that links the Property Feature to its corresponding Option Class.

Whenever new options are added to the Option Class in Oracle Inventory (possibly including new values for Properties), Property Features can be brought up to date by rerunning the Populator(s).

How do Property Features Simplify Property-based Relationships between Large Option Classes?

Any direct property-based relationship between Option Classes is equivalent to a Property-based Compatibility Rule between Property Features, together with the structural Property-based Compatibilities. The complexity of a structural Property-based Compatibility Rule is equivalent to that of an Explicit Compatibility Rule with only as many rows as the Option Class has options. Since the Property Features have a small number of options, a property-based relationship between them will generally correspond to a fairly small number of compatibility table rows or explicit relationships. The total complexity of such a set of indirect relationships is usually less than the complexity of the original direct relationship.

In the Large Number of Options example, Property Features FeatureX and FeatureY are created. Populators create 20 Options each in FeatureX and FeatureY, which correspond to the 20 different values of the Properties. Each Option bears the corresponding Property and value. The structural Property-based Compatibility would specify 'FeatureX.X = A.X' and 'FeatureY.Y = B.Y'. The property-based relationship requiring X and Y to be equal would specify 'FeatureX.X = FeatureY.Y'. The net effect of these three relationships is equivalent to the original relationship 'A.X = B.Y'. But now, instead of 50,000 equivalent explicit compatibility rows, there are only 2020 (1000 + 1000 + 20).

One other possible benefit of Property Features is that Property values often characterize the form, fit, and function of the Items in an Option Class, and may be closely related to the end user's reasons for preferring one Item over another. In an ideal case, the Properties (or a subset of them) directly represent the user's needs. By presenting Property Features in the runtime UI, it may be possible to implement a needs-based Configurator that requires little or no ongoing maintenance aside from defining Items and BOM Models in Oracle Inventory.

Comparison Rules

Depending on your requirements, it is generally good modeling practice to avoid rules that raise contradictions. Instead, define rules that cause only validation failures or warnings and therefore allow end users to proceed.

When defining Comparison rules, avoid involving the initial value of a Total in the comparison. The initial value can cause locking when retracted during a numeric cycle.

The examples in this section show best practices for building rules that avoid contradictions and problems caused by intermediate values (also known as locking). However, it is important to remember that subsequent changes to any nodes that participate in the rule may alter a rule's behavior at runtime.

Comparison Rules That Raise Warnings

When defining Comparison Rules, construct your rules so they lead to a resource violation rather than a contradiction. Rules that raise contradictions are much less flexible because they require one or more previous selections to be deselected before the end user can continue. A resource violation, however, only displays a warning indicating that a specific value has been exceeded, does not deselect any options, and allows the end user to acknowledge the warning and proceed with the configuration.

For an example, see Avoiding Unexpected Contradictions from Intermediate Values.

Using Intermediate Values Effectively With Comparison Rules

Comparison Rules that raise contradictions can also lead to problems caused by an intermediate value. Oracle Configurator triggers each rule in a configuration model sequentially (that is, one after another), rather than propagating all rules simultaneously. As a result, a rule may be violated when it reaches a specific value, even if you defined another rule to prevent the violation from occurring in the first place. However, since the intermediate value is reached before the other rule propagates, a violation occurs. (See Unexpected Contradictions from Intermediate Values). See also Connectors with Connection Rules for additional reasons to avoid rule order.

Problems with intermediate values can also occur when:

Unexpected Contradictions from Intermediate Values

Model A contains the following:

The rules:

Logic: Boolean Feature X Requires AllOf (OptionsOf (Option Feature F2))
Numeric: EachOf (OptionsOf (Option Feature F2)) Contributes to Numeric Feature Z
Comparison: Numeric Feature Z equal to 1 Excludes Option Feature F1

At runtime, the end user selects Boolean Feature X, making the state of X true. This makes F2 true. Propagation of Option2 makes the value of Numeric Feature Z equal 1. The Comparison Rule causes the propagation of Z=1 to try to push the value of Option Feature F1 false. Even though the current value of Numeric Feature Z is an intermediate value, and the propagation of Option2 will result in a value of Z=2, a contradiction occurs. To avoid the contradiction, consume from a Resource to keep Z=1 when Option2 is true.

Avoiding Unexpected Contradictions from Intermediate Values

This example shows how to avoid contradictions raised by Comparison Rules because of intermediate values.

In addition to the nodes described in the previous example, above, Model A also contains the following:

To avoid a contradiction from an intermediate value, define the following rules (note that you define these instead of the rules shown in Unexpected Contradictions from Immediate Values, not in addition to those rules):

Logic: Boolean Feature X Requires AllOf (OptionsOf (Option Feature F2))
Numeric: EachOf (OptionsOf (Option Feature F2)) Contributes to Numeric Feature Z
Comparison: Numeric Feature Z equalto 1 Implies Temp
Numeric: Temp Consumes from Res

At runtime, the end user selects Boolean Feature X, making the state of X true. This makes F2 true. Propagation of Option2 makes the value of Numeric Feature Z equal 1. The Comparison Rule causes the propagation of Z=1 to push Boolean Feature Temp true. Temp consumes 1 from Resource Res. Since Oracle Configurator checks validation failures at the end of propagation, Option3 can become true without any validation failures.

Connectors with Connection Rules

Connection rules that involve Connector nodes in the Model structure operate only when component instances are connected at runtime, and only among the connected instances. The logic generated by connection rules is not initially loaded with the configuration model at runtime. Connection rules are loaded and executed only when the Connectors in the parent instance have been assigned to corresponding instances of the target Models.

When an end user makes a connection, the following happens:

  1. All the end-user inputs are retracted.

  2. The connection is made.

  3. Connection rules are loaded and executed.

  4. All the end-user inputs are applied again.

This process leads to changes in values and logic that conflict with the configuration as it was before the connection was made. The sequence in which the rules are loaded and the end-user inputs are reapplied could cause unexpected behavior due to invalid intermediate values. Such situations could cause fatal errors and prevent the end user from proceeding with the configuration.

To avoid inconsistency or errors, ensure that all component instantiations and connections can be performed independent of end-user inputs. Additionally, as with all configuration rules, write rules that are order independent.

Consider the two models in Model with a Connector. The Rack Model contains a Total, a Boolean Feature that is Always True, and an Options Feature named Rack Type with Option A and B. The Rack Type Options Feature has a Property named Width. The Server Model contains a Connector to the Rack Model and a Boolean Feature that is Always True.

Model with a Connector

the picture is described in the document text

The following sections use these Models to demonstrate:

Connection Rules That Depend on End-User Input

The rules in the Rack Model are as follows:

Rule 1: Total < 0 Excludes Always True
Rule 2: Each Of (Options Of(Rack Type)) * Property.Weight Contributes To Total
CDL Rule 1: CONSTRAIN (Total < 0) EXCLUDES "Always True"
CDL Rule 2: CONTRIBUTE (EachOf (OptionsOf(Rack Type)) * Property.Weight) TO Total

The intent of the CONSTRAIN rule ensures that the value of Total never drops below 0 (zero).

The rule in the Server Model is the Connection rule:

Rule 3: Always True * Constant(Value) Consumes From Total
CDL Rule 3: CONTRIBUTE ((Always True * Constant(Value))* -1) TO Total

At runtime, the end user selects a Rack Type. Oracle Configurator executes Rule 2, contributing the selected Rack Type’s Property Weight to Total. The end user then connects to the Rack Model in the Server Model. Oracle Configurator retracts the selected Rack Type, which resets Total to 0. Oracle Configurator loads the connection rule, Rule 3, and consumes Value from Total (0), causing Rule 1 to be invalid. This results in a non-overridable contradiction and the connection fails.

Order Independent Connection Rules

You can avoid the dependence on end-user input described in Connection Rules That Depend on End-User Input by creating a rule rather than an end-user input that makes the contribution. Rewrite Rule 2 in the above case as:

Rule 1: Total < 0 Excludes Always True
Rule 2: Always True * Constant(Value) Contributes To Total
CDL Rule 1: CONSTRAIN (Total < 0) EXCLUDES "Always True"
CDL Rule 2: CONTRIBUTE "Always True" * Constant(Value) TO Total

When Oracle Configurator starts up, a configuration is created. The end user connects the Server Model to a Rack Model. Oracle Configurator retracts all end-user inputs, but does not retract the Value of Total because it has been set by a rule, not an end-user input. Then Oracle Configurator loads the connection rule, Rule 3, and consumes from Total without a contradiction occurring.

Rule 3: Always True * Constant(Value) Consumes From Total
CDL Rule 3: CONTRIBUTE (("Always True" * Constant(Value))* -1) TO Total

This solution avoids order dependence but may still encounter intermittent failures when a configuration is restored. See Restoring Configurations With Connections for details.

Restoring Configurations With Connections

Restoring a configuration created using the rules described in Order Independent Connection Rules intermittently results in failures. When Oracle Configurator restores a configuration, the Oracle Configurator engine activates all the rules and the order of assertions is no longer guaranteed. In some cases, Rule 1 and Rule 3 might be executed before Rule 2, resulting in a fatal error.

You can avoid the fatal error either by populating a Total with an initial value, or using a Resource instead of a Total. Over-consuming a resource does not result in a fatal validation failure, which allows the end user to proceed with the configuration session.

Rule 1: Resource < 0 Excludes Always True
Rule 2: Always True * Constant(Value) Contributes To Resource
Rule 3: Always True * Constant(Value) Consumes From Resource
CDL Rule 1: CONSTRAIN (Total < 0) EXCLUDES "Always True"
CDL Rule 2: CONTRIBUTE "Always True" * Constant(Value) TO Total
CDL Rule 3: CONTRIBUTE (("Always True" * Constant(Value))* -1) TO Resource

When Oracle Configurator starts up, a configuration is created. The end user connects the Server Model to a Rack Model. Oracle Configurator retracts all end-user inputs, but does not retract the Value of Resource because it has been set by a rule, not an end-user input. Then Oracle Configurator loads the connection rule, Rule 3, and consumes from Resource without a contradiction occurring. The connection is made. Now, when the end user restores this configuration, only a validation failure would occur if Rule 1 and Rule 3 were executed before Rule 2. The validation failure would not prevent the configuration from being restored.

Optimizing User Interface Performance

The following design considerations can help you improve performance of a runtime User Interface:

For details about creating a User Interface, see the Oracle Configurator Developer User’s Guide.

Display Conditions

Using display conditions to hide items is generally more expensive than allowing all options to be displayed. However, the overall effect on performance is minimal when only a small number of items on a page have display conditions. For best performance, avoid placing many items with display conditions on the same page.

Graphics

The number and size of GIFs in a page does not increase the time needed to render the screen on the server. However, reducing the number of controls and GIFs on the page may improve the performance of rendering the browser page on the client machine.

Number and Type of Pages and Controls

The number of Oracle Configurator pages and the number of UI controls on each page influences runtime performance. Increasing the number of controls increases the time needed to render a page. This is due to browser resource limitations, not an inherent limitation in Oracle Configurator. For DHTML UIs, Oracle recommends a maximum of 8 to 10 UI controls and 5 graphics per page. The performance of an HTML UI is not adversely affected by pages containing a large number of UI controls.

The type of controls on a page does not influence server performance. For example, Drop-down Lists and Selection Lists take the same amount of time to render. However, In a DHTML UI, Dropdown Lists may render faster than Selection Lists, and the time it takes to render a Selection List is dependent on how many Options are displayed in the list.

Configuration Summary User Interface Template

By default, the predefined UI Master Templates use the Summary with Status Region Content Template to display all orderable items in the Configuration Summary page at runtime. The default template displays the Summary Table fully expanded, which can negatively affect performance in a large configuration.

To improve performance of the Configuration Summary page:

  1. Create a custom configuration summary UI Content Template. (Refer to the predefined template to see which UI elements are required and understand the structure.)

    When creating the Summary Table UI element, deselect Expand All Levels on Entry.

  2. Create a custom UI Master Template.

  3. In the Utility Templates section of your UI Master Template, select your custom configuration summary template for the Configuration Summary/Preview setting.

  4. Use your custom UI Master Template to generate the UI.

Custom User Interface

A Custom User Interface is created outside of Oracle Configurator Developer. It is usually coded as a set of Java Server Pages that display model content via the Configuration Interface Object (CIO). You create a custom UI by writing custom code that allows your configuration model to interface with the Configuration Interface Object (CIO).

Because it interacts with the CIO, it is important to optimize the CIO calls for best performance. For more information, see Configurator Extension Design.

Large Amounts of End-User Data Collected Using Configurator Extensions

In rare cases, you may have unconstrained end-user data, meaning it is not constrained by or does not participate in rules. Collecting large amounts of that kind of data from end users, especially if it is repetitive, can degrade the usability of the Oracle Configurator UI. If you can identify data that could be collected outside the main interactive configuration session, especially if it lends itself to being collected in a tabular or spreadsheet form and is not orderable or constrained by rules, consider the following implementations:

Configurator Extension Design

The design of Configurator Extensions and how they interact with the configuration model as well as other software may affect performance. This section presents the following topics:

Configurator Extensions must use the Configuration Interface Object (CIO) to interact with the configuration model. See the Oracle Configurator Extensions and Interface Object Developer’s Guide for additional information about the CIO and Configurator Extensions.

Avoiding Unnecessary Interactions

Design Configurator Extension to avoid any unnecessary interactions, such as recursively processing unselected Model subtrees or creating large numbers of Configurator Extension instances by associating Configurator Extension instantiation component instances that occur in large numbers.

Accessing Runtime Nodes

Components and Requests

Programmatic changes to the configuration model are dependent on the sequence of events. For example, to instantiate some Components and programmatically set some Features in each Component, you could use either of these approaches:

The second approach is faster, because the creation of each Component requires the retraction of all previous inputs (all user selections and all default selections). In the second approach, you can assert inputs and defaults only once, between when you add all the Components and when you set all the Features in all the added Components. The expensive events that you are avoiding in this second approach are the retractions and reassertions of inputs and defaults, which are processed every time that a Component is added.

If you are modifying the structure of a Model, you can improve performance by using the technique described in Optimization of Configurator Extensions that Change Model Structure.

Adding and Deleting Instantiable Components

Adding or deleting an instance of a ComponentSet can be very expensive in terms of performance. For example:

To avoid these performance problems, follow these guidelines for adding instances of a ComponentSet:

Impact of Making Connections Among Components

Connectivity among components can add further complexity to the suggested sequence described in Detailed Sequence. The best approach depends on understanding the number of connections you plan to make, and how many you expect to fail. Completing a connection involves the creation and loading of all rules that are enforced as a result of the connection. That means all current requests have to be retracted and reapplied after the net is added.

The optimum point at which to make the connection is between the retraction of all requests and adding or reusing component instances.

If you do not expect the end user requests or the new values to make a difference on whether connection is allowed, then you need to add or reuse component instances, or reassert applicable requests before the connection.

The number of connections may cause you to adjust your thinking, due to the impact of retracting inputs.

You may also want to consider using the method ConfigTransaction.allowOnlyStructuralChanges (). For details, see Optimization of Configurator Extensions that Change Model Structure.

Optimization of Configurator Extensions that Change Model Structure

Use the following general strategy to optimize performance of a Configurator Extension that changes model structure:

  1. Store all needed values.

  2. Begin a transaction and call ConfigTransaction.allowOnlyStructuralChanges().

  3. Make changes to model structure. Model structure changes are defined as:

    • Adding or deleting instantiable components

    • Connecting or disconnecting component instances

  4. Delete extra component instances.

  5. Commit or roll back the transaction.

  6. Set values on components.

The structural change transaction enables you to mark a transaction as being only for modifying the product structure. When you use the method ConfigTransaction.allowOnlyStructuralChanges(), Oracle Configurator automatically retracts the inputs and stores them until you close the transaction. If the end user changes any inputs, Configurator displays an exception.

The principle behind this strategy is that making structural changes in a block, inside a transaction that suspends the usual retraction and reassertion of requests, optimizes the event sequence. Detailed Sequence explains these events in more detail.

Detailed Sequence

Based on the preceding guidelines, optimize the performance of a Configurator Extension that changes model structure by designing it according to the following sequence:

  1. Store all needed values and logic states in temporary variables.

    These are the values that are needed for later calculations and which would be lost by retracting requests.

  2. Begin a transaction. Use Configuration.beginConfigTransaction().

  3. Call ConfigTransaction.allowOnlyStructuralChanges().

    This method puts the configuration into a state in which the only changes allowed are those that modify the structure of the Model. Model structure changes are defined as:

    • Adding or deleting instantiable components

    • Connecting or disconnecting component instances

    You cannot make any requests (changes to values or logic states in the configuration) while in the structural-changes-only state. If you make a request, a non-overridable logical exception is thrown.

    The allowOnlyStructuralChanges() method retracts all user and non-overridable requests. The requests are stored until your transaction is committed or rolled back. If a contradiction occurs during the retraction, then the retraction is aborted, and the transaction loses its structural-changes-only state.

    Any nested transactions that you create inherit the structural-changes-only state of the parent transaction.

    Caution: Do not call any methods that get values or logic states in the configuration while it is in the structural-changes-only state. Because the allowOnlyStructuralChanges() method previously retracted all requests, any values or states in the configuration returned by a query will be incorrect.

  4. Add or reuse component instances, as suggested in Adding and Deleting Instantiable Components. To add a component instance, use ComponentSet.add().

  5. If you know that you have extra component instances, you may be able to delete them, as suggested in Adding and Deleting Instantiable Components. To delete a component instance, use ComponentSet.delete().

  6. Commit or roll back the transaction. Use Configuration.commitConfigTransaction() or Configuration.rollbackConfigTransaction().

    When you commit or roll back the transaction, the CIO removes the configuration from the structural-changes-only state, and reasserts all the previously retracted user and non-overridable requests. If a contradiction occurs during the reassertions, then a LogicalOverridableException is thrown. You can override the exception and examine the failed requests. See the Oracle Configurator Extensions and Interface Object Developer’s Guide for details on exceptions and failed requests.

  7. Set values on Component instances or their children. Use setState(), setCount(), setValue(), and so on.

Comparison of Coding Approaches

Consider an example of creating instances of a certain number of instantiable Components, and setting the values of Features in each one. Setting Components and Feature Values One at a Time (Slower) creates a Component, then sets its Features before creating the next Component. Setting All Components and Then All Feature Values (Faster) creates all the Components, then sets all of their Features.

Setting Components and Feature Values One at a Time (Slower)

// Block for 1st component
Add Component1 to ComponentSet
Set Feature1 in Component1
Set Feature2 in Component1
// Block for 2nd component
Add Component2 to ComponentSet
Set Feature3 in Component2
...

Setting All Components and Then All Feature Values (Faster)

// Block for all structure changes
Begin strucure-only transaction
Add Component1 to ComponentSet
Add Component2 to ComponentSet
Commit strucure-only transaction
// Block for all assertions
Set Feature1 in Component1
Set Feature2 in Component1
Set Feature3 in Component2
...

Setting Components and Feature Values One at a Time (Slower) is subject to the negative performance effects identified in Optional and Multiple Instantiation. Setting All Components and Then All Feature Values (Faster) results in significantly faster runtime performance.

The reason why Setting Components and Feature Values One at a Time (Slower) is slower is shown by comparing Detailed Slower Approach with Detailed Faster Approach. The operations that have to be performed by the CIO when adding ComponentSet instances are highlighted in boldface. repeats all of the operations for each addition of an instance, so that each addition takes longer than the preceding one, and the total processing time is proportional to the number of instances to be added. If there are many instances to be added, the impact is great. Detailed Faster Approach performs the operations once, greatly lessening the effect of adding many instances.

Detailed Slower Approach

...
Set Feature1 in Component1
Set Feature3 in Component2
// Block for 1st component
Retract requests // (2 requests)
Add Component1 to ComponentSet
Reassert requests // (2 requests)
Set Feature1 in Component1
Set Feature2 in Component1
...
// Block for 2nd component
Retract requests // (2 existing + 2 new = 4 requests)
Add Component2 to ComponentSet
Reassert requests // (4 requests)
Set Feature3 in Component2
...

For n components added, this approach results in n retractions and reassertions, each of which is an expensive operation. Note also that the queue of requests grows over time, further increasing the expense of retraction and reassertion.

Contrast this with the result for Detailed Faster Approach.

Detailed Faster Approach

...
Set Feature1 in Component1
Set Feature3 in Component2
Set Feature1 in Component1Set Feature2 in Component1
Begin strucure-only transaction // retracts all existing requests (4 requests)
Add Component1 to ComponentSet
Add Component2 to ComponentSet
Commit strucure-only transaction // reasserts all existing requests (4 requests)
...
Set Feature3 in Component2
...

For n components added, this approach results in only 1 retraction and reassertion. Contrast this with the result for Detailed Slower Approach. You could further improve performance by performing structural changes before making requests, thus reducing the size of the queue of requests.

Code Example

Consider the simple runtime Model structure shown in Model Structure for Adding Components. At runtime, this Model contains a ComponentSet object and several BooleanFeature objects.

The following graphic shows a simple Model, consisting of a ComponentSet object named Comp1, which contains three BooleanFeature objects called BoolFeat1, BoolFeat2, and BoolFeat3.

Model Structure for Adding Components

the picture is described in the document text

Assume that you have written a Configurator Extension bound to the onCommand event that sets the state of the Boolean Features as illustrated in Setting Features (Slower Code).

Setting Features (Slower Code)

...for(int i=0; i<100; i++) {
    comp = Comp1.add();
 ((BooleanFeature)comp.getChildByName("BoolFeat1")).setState(IState.TRUE);
    ((BooleanFeature)comp.getChildByName("BoolFeat2")).setState(IState.FALSE);
    ((BooleanFeature)comp.getChildByName("BoolFeat3")).setState(IState.TRUE);
}
...

You can significantly improve the performance of this operation by modifying the code as shown in Setting Features (Faster Code). The differences are highlighted in boldface.

Setting Features (Faster Code)

...
ConfigTransaction tr = config.beginConfigTransaction(); 
ConfigTransaction.allowOnlyStructuralChanges();
for(int i=0; i<100; i++){
    comp[i] = Comp1.add(); 
}
config.commitConfigTransaction(tr);
for(int i=0; i<100; i++){
    ((BooleanFeature)comp[i].getChildByName("BoolFeat1")).setState(IState.TRUE);
    ((BooleanFeature)comp[i].getChildByName("BoolFeat2")).setState(IState.FALSE);
    ((BooleanFeature)comp[i].getChildByName("BoolFeat3")).setState(IState.TRUE);
}
...

Setting Features (Faster Code) improves performance by adding all the ComponentSet instances, then setting all the BooleanFeature values. This follows the principles identified in Optional and Multiple Instantiation, and the example shown in Setting All Components and Then All Feature Values (Faster) under Comparison of Coding Approaches.

Optimization of Validation Configurator Extensions

In general, Oracle Configurator applies validation tests and defaults more often than would be expected. The onConfigValidate event is called whenever the end user selects an option or enters an input in the runtime Oracle Configurator. In a Configurator Extension bound to this event, defaults should be used as judiciously as possible, as described in Defaults Rules Versus Alternatives to Default Selections. Validation tests must also be minimal. You should arrange the code so that onConfigValidate is only called when necessary, and the condition test is quick.

The examples Minimizing Validation Tests on a Configuration Model and Causing More Validation Tests on a Configuration Model show two ways of applying a validation test. Minimizing Validation Tests on a Configuration Model performs better because it performs the task of setting up the validation (by finding the node in each call) in a method bound to the postCXInit event, which occurs once, and then performs the validation test only after all other calls are completed.

The example Causing More Validation Tests on a Configuration Model sets up the validation as part of the validation test, so the setup is performed every time the onConfigValidate event occurs.

If you are using Oracle Configurator release 11.5.9 or earlier, use onConfigValidate. If you are using release 11.5.10 or later - and only the end user can modify the Feature - then use the postValueChange event instead. This event has a more limited scope and is much more efficient than onConfigValidate. Refer to the Oracle Configurator Extensions and Interface Object Developer's Guidefor more information.

Minimizing Validation Tests on a Configuration Model

OptionFeature f = null;
doPostCXInit() {     // bind to postCXInit event
      f = (OptionFeature) root.getChildByName("feature_name");
   }
doOnConfigValidate () { // bind to onConfigValidate event
  if (f.isTrue()) {
  }
}

Causing More Validation Tests on a Configuration Model

doPostCXInit() {     // bind to postCXInit event
   // empty
   }
doOnConfigValidate () { // bind to onConfigValidate event
  OptionFeature f = (OptionFeature) root.getChildByName("feature_name");
  if (f.isTrue()) {
  }
}