4 Adding a Gesture

You can add your own gestures and operations to OIG Configuration Utility. The utility includes GesturesSPI, which is a Service Provider Interface that you can use to implement new gestures. To do so, create your own gesture by extending the AbstractGesture class. Each gesture can define one or more operations. Add support for operations by extending AbstractGestureOperation for each operation. You can use MBeans operations to make changes to WebLogic Server. After your code is complete, copy your gesture class to the lib/ directory, add the gesture to the gesturesConfig section of oig-utility-config.json and set its isEnabled value to true. Provided the gesture is valid, when you launch the utility, your gesture appears in the "Configured Gestures" section of the utility help.

Extending AbstractGesture

To create a gesture, you must extend the AbstractGesture class, implementing abstract methods to add gesture-specific information. The TuningGesture.java source code provides an example of how to extend AbstractGesture to implement a gesture. The following sections provide some additional details on creating a gesture class.

Overriding Gesture Methods

You must override the following methods in your gesture class for your gesture to be usable in OIG Configuration Utility:

Method Description Sample Return Value
public String getDescription() Returns a string that contains a description for the gesture. Tune different components.
public List<GestureOperation> getOperations() Returns a list of operations supported by this gesture. Operations are created by extending the AbstractGestureOperation class.  
public String getShortName() Returns the short name of the gesture. tune

The utility automatically generates help for enabled gestures by using the values returned by these methods. You can enable gestures in oig-utility-config.json.

Extending AbstractGestureOperation

To create an operation, you must extend the AbstractGestureOperation class, implementing abstract methods to provide operation-specific information. For example, the tune gesture provides a "tune DB" operation, which is implemented by TuneDBOperation.java. The code for the operations that come with OIG Configuration Utility demonstrate how to extend AbstractGestureOperation to implement an operation. Each gesture can define one or more operations. The following sections offer additional information about implementing operations to work in the OIG Configuration Utility framework:

Overriding GestureOperation Methods

You must override the following methods in your gesture operation class for your gesture to be usable in OIG Configuration Utility:
Method Description Sample Return Value
public int execute() This method defines the execution logic of the operation. The framework calls this method when it receives a request to execute this operation.  
public GestureOperationReport generateReport() Generates a report for the attributes affected by this operation.  
public String getDescription() This method returns a description of the operation. Tune Database Operation
public String getLongCliFlag() This method returns the long CLI flag that can be used to execute this operation. -database
public String getShortCliFlag() This method returns the short CLI flag that can be used to execute this operation. -d
public Class getOperationAttributeClass() This method returns the attributes class used by this operation to define attributes. DBTuneAttributes.class
public List<Option> getOptions() This method returns a list of supported options that can be specified on the command line for this operation.  
public List<RequiredParam> getRequiredParams() This method returns the list of parameters that are require to execute this operation. They can be defined in inputs.properties or provided via the CLI.  
public List<String> getWarnings() This method returns a list of warnings that you want to display in an HTML report and in the logs. These are generic warnings, such as any manual steps required after operation execution.  
public void validate() This method contains any validation that you want to perform for your gesture operation.  

Implementing Attributes

For each operation, you must create a class that implements the com.oracle.oig.gesture.spi.Attributes marker interface. This interface is defined in Attributes.java as part of the GesturesSPI framework. Each class that implements Attributes contains the attributes that the operation modifies.

An example implementation of Attributes is DBTuneAttributes.java, which models all the attributes used by the database tuning operation. The framework uses your implementation to create objects to use when executing the operation associated with that set of attributes.

Update oig-utility-config.json

After creating an attributes model for an operation, you must update oig-utility-config.json by adding a section with your operation’s attributes and their values. For example, the attributes for the DB Tuning operation, which correspond to the DBTuneAttributes.java implementation of the Attributes marker interface, are included in oig-utility-config.json as follows:

                "Tune Database Operation":
                {
                  "com.oracle.oig.attributes.DBTuneAttributes":
                  {
                    "queries":
                    [
                      "java.util.ArrayList",
                      [
                        {
                          "com.oracle.oig.attributes.QueryAttributes":
                          {
                            "parameter": "DB_KEEP_CACHE_SIZE=200M"
                          }
                        },

                        ...

                        {
                          "com.oracle.oig.attributes.StoredProcedures": 
                          {
                            "parameter": "OPEN_CURSORS=600"
                          }
                        }
                      ]
                    ]
                  }
                },

Users of the OIG Configuration Utility can modify the values of the attributes of the structure that you add for your operation to set new values in the configuration.

Defining Options

An operation has a set of associated options, each of which is defined by an Option object.

Each operation defines an array to hold its options. TuneDBOperation defines its array as follows:
private static final List<Option> options = new ArrayList<Option>();
An Option consists of six values:
  • description - a description of the operation, used in the utility help.

  • hasValue - a flag that indicates whether the option has an associated value. If set to true, the framework expects a value for this option, and validates whether a value was provided when the operation is executed.

  • isOptional - a flag that indicates whether the option is optional. Set to true if optional; false, if the option is required.

  • longCliFlag - the option's CLI long flag.

  • shortCliFlag - the option's CLI short flag.

  • validValues - the set of valid values for this option.

The Class Variables demonstrates how to define the longCliFlag and shortCliFlag members of an Option. The values for hasValue and isOptional are defined when the Option is created.

Adding Options to an Operation

You add options to an operation by implementing the getOptions() method. In it, you create the options for the operation, and add them to the options list.

When creating an Option, there are two available constructors—one where the option defaults to being optional (no value is passed for isOptional), and a second where you must specify whether the option is optional. For example, TuneDBOperation uses the first method, as demonstrated in the following:
  @Override
  public List<Option> getOptions() throws OIGException {
    if (options == null || options.isEmpty()) {
      final Option dbOption = new Option(LONG_CLI_FLAG, SHORT_CLI_FLAG, "Tune DB params", false);
      options.add(dbOption);
    }
    return options;
  }
The getOptions() method is also where you specify the valid values for an option. For example, the following getOptions() method adds the option to enable some function "XYZ":
  @Override
  public List<Option> getOptions() throws OIGException {
    if (options == null || options.isEmpty()) {
      final Option enableOption =
          new Option(LONG_CLI_FLAG, SHORT_CLI_FLAG, "Enable XYZ for OIM servers", false);

      for (final PostInstallConstants.SupportedComponents s : PostInstallConstants.SupportedComponents
          .values()) {

        enableOption.addValidValue(s.getSupportedComponent());
      }

      options.add(enableOption);
    }
    return options;
  }

The above example demonstrates adding the valid values to an Option (here, enableOption), before adding the Option to the operation’s options list. The framework checks input against these values, and returns an error if an invalid value is provided.

Defining Required Parameters

Your operation may require certain inputs. For example, an operation might require a WebLogic Server username and password. These types of inputs are referred to as required parameters.

Each operation defines a class variable to store its required parameters as follows:
private static final List<RequiredParam> requiredParams = new LinkedList<RequiredParam>();

You define a required input by creating a RequiredParam object. Each RequiredParam has five attributes: the name of the parameter, the text to display when prompting a user to enter a value for the parameter in interactive mode, a description of the parameter, whether the input is secure and needs to be masked in interactive mode, and whether the parameter is optional. If the parameter is secure (set to true), then input entered for that value is masked on the command line. Creating a RequiredParam without specifying whether it's optional, results in it being required.

You set the required parameters for an operation by overriding AbstractGestureOperation’s getRequiredParams() method. The following is the implementation from TuneDBOperation.java:

@Override
public List<RequiredParam> getRequiredParams() throws OIGException {
  if (requiredParams.isEmpty()) {

    final RequiredParam dbSysUrl = new RequiredParam(DBParams.DB_SYS_URL.paramName,
      "Enter Database JDBC URL for sys dba: Ex:jdbc:oracle:thin:@dbhostname:5521(:orclsid or /serviceName)",
      "Jdbc url is used to connect to the db ", false);

    final RequiredParam dbSysDbaUser = new RequiredParam(DBParams.DB_SYS_DBA_USER.getParamName(),
      "Enter Database Sys User", "Database Sys User", false);

    final RequiredParam dbSysDbaPassword =
      new RequiredParam(DBParams.DB_SYS_DBA_PASSWORD.getParamName(),
      "Enter Database Sys Password", "Database Sys Password", true);

    final RequiredParam dbOimUrl = new RequiredParam(DBParams.DB_OIM_URL.paramName,
      "Enter Database JDBC URL for oim user: Ex:jdbc:oracle:thin:@dbhostname:5521(:orclsid or /serviceName)",
      "Jdbc url is used to connect to the oim user. (Example: jdbc:oracle:thin:@dbhostname:5521(:orclsid or /serviceName)) ",
      false);

    final RequiredParam dbOimUser = new RequiredParam(DBParams.DB_OIM_USER.getParamName(),
      "Enter Database Oim User", "Database Oim User", false);

    final RequiredParam dbOimUserPassword =
      new RequiredParam(DBParams.DB_OIM_USER_PASSWORD.getParamName(),
      "Enter Database Oim Password", "Database Oim Password", true);

    requiredParams.add(dbSysUrl);
    requiredParams.add(dbSysDbaUser);
    requiredParams.add(dbSysDbaPassword);
    requiredParams.add(dbOimUrl);
    requiredParams.add(dbOimUser);
    requiredParams.add(dbOimUserPassword);
  }
  return requiredParams;

}

When an operation is executed, the framework checks the inputs provided to the operation, and returns an error if any of the required parameters were not provided.

Deploying a Gesture

After you created a gesture by writing an AbstractGesture class and AbstractGestureOperation classes for each operation that the gesture supports, you need to perform a few steps to add the gesture to the utility.

After your code is complete, create a JAR for your gesture, copy the JAR to the lib/ directory, add the gesture to the gesturesConfig section of oig-utility-config.json, and set its isEnabled value to true.

Build and Copy a JAR

To prepare your gesture for the utility, build your Java code, generate a JAR for your gesture, copy the JAR to the utility’s lib/ directory, and set the JAR class path environment variable, if not already set. You can set the class path in oig-config-utility.sh by appending the path to the line that begins with "CLASSPATH=".

Add and Enable the Gesture

The framework can access all of the gesture code that exists in the lib/ directory. However, for OIG Configuration Utility to offer a gesture to its users, the gesture must be added to the utility configuration.

To add a gesture to the utility configuration, edit oig-utility-config.json and add an entry for your gesture to the gesturesConfig array. For example, the entry for our sample MyGestureOperation gesture would be as follows:

    {
      "name": "My Gesture",
      "gestureClass": "com.yourcompany.oig.gestures.MyGesture",
      "isEnabled": "true"
    }

To enable your gesture, set the value of isEnabled to true in its gesturesConfig entry. To disable a gesture, set its isEnabled value to false.