9.5 SCM and Scripting

The Service Configuration Manager (SCM) imports data from external sources and generates new element hierarchies in the Operations Center console. A large part of the import preparation involves mapping imported data. This section assumes familiarity with SCM functionality. Read Using the Service Configuration Managerin the Operations Center 5.6 Service Modeling Guide for more information.

When using SCM, most sites perform these two actions:

  • First Stage: Relate services to applications.

  • Second Stage: Relate applications to hosts.

When beginning to relate applications to hosts, the following mapping usually occurs:

Host A Host A (OV) Host A (Patrol) Host A (Remedy)

However, this format is not optimal for most users. They want to see the children of Host A (OV), Host A (Patrol), Host A (Remedy). Use dynamic matching to do this:

[^\x2F]*=${name}.*

Join rules can be written using regular expression and Apache Velocity.

When trying to join things with spaces, use this main concept:

$class=$name

Use the form:

${formula.util.encodeURL($class)}=${formula.util.encodeURL($name)}

Main packages for BCSM are in com.mosol.Formula.ViewBuilder Also see com.mosol.Formula.commands.ViewBuilder.java.

Some scripting applications involving SCM include scheduling SCM jobs, building core views and generating elements.

9.5.1 Scheduling a SCM Job by Using a Script

The following script example shows running a SCM job.

NOTE:Do not run SCM jobs in parallel unless you know for certain that the SCM jobs do not affect the same elements. To be safe, use a script that runs the SCM jobs in a specific sequence, as shown in Section 9.5.2, Scheduling Multiple SCM Jobs by Using a Script.

var logger = Packages.org.apache.log4j.Logger.getLogger("BSCM_copy_script");

function buildbscm(viewDName)
   {
     var viewElement = null;
     try {
        viewElement = formula.Root.findElement( viewDName );
     } catch( Exception ) {
     formula.log.error( "ERROR - caught exception while finding view " +
     viewDName + ": " + Exception );
     return false;
     }
     if( viewElement == null ) {
       formula.log.error("ERROR - view " + viewDName + " not found" );
       return false;
     }
     try {
       var ret = viewElement.perform( session, "ViewBuilder|Run", [], [] );
     } catch( Exception ) {
     return false;
     }
   }    

logger.info('Build bscm: start ----------------------');
buildbscm('org=elements_bscm/root=Organizations');
logger.info('Build bscm: end ----------------------');

9.5.2 Scheduling Multiple SCM Jobs by Using a Script

The following script example shows the kicking off of SCM jobs in a specific sequence in order to remove the risk of them conflicting with each other. This is important unless you know for certain that the SCM definitions do not affect any of the same elements or hierarchies.

// This script uses a "dnames" array to define the elements containing
// the SCM job definitions. Instead of using the schedule in the SCM job, 
// it uses the "Administration > Jobs" Time Management to run the SCM jobs
// in the order you specify.

// Edit the dnames variables to specify the specific dnames in the order you        // require them to be built.

// For more advanced functionality (ie; requires more scripting), you can turn on
// adapters just before a job runs, interrogate the adapter to see if it is done
// "starting". Once it is done, you can kick off the SCM job and when complete,     // you can stop the adapter.    


formula.log.info( "Starting build of SCM jobs..." );

var dnames = new Array()

dnames[0] = "Application=Application+A+thru+C/layout_organic=my+Applications/root=Generational+Models/root=Services"
dnames[1] = "SCM job name using DName"

// Add dname instances above as necessary.

/* no changes required below here */
/* function to kick of SCM jobs based on the dnames above */

function buildView( viewDName )
{
    var viewElement = null;

// find the element based on the dname

    try {
        viewElement = formula.Root.findElement( viewDName );
    } catch( Exception ) {

        formula.log.error( "ERROR - caught exception while finding view " +
viewDname + ": " + Exception );

        return false;
    }

// if element can't be found, issue an error to log file

    if( viewElement == null ) {

        formula.log.error("ERROR - view " + viewDName + " not found" );
        return false;
    }


//if the element is found, kick of SCM job via the perform() method.

    try {

        var ret = viewElement.perform( session, "ViewBuilder|Run", [], [] );

    } catch( Exception ) {

        return false;
    }
}

/* for loop to run through each dname and kick off SCM job */

for( var i=0; i<dnames.length; i++ )

{
    formula.log.info( "Starting SCM job for:  " + dnames[i] );
    buildView( dnames[i] );
}

formula.log.info( "Finished running all SCM jobs" );

9.5.3 Generating Elements by Using a Script

The scripts used to generate elements vary, but it is important to add the following line to the end of the script, or else all elements generated by the script are removed at the end of the SCM job.

bscm.addGeneratedElement( postScriptGeneratedElement )

For example:

// Example 'Post Element Generation Script' to build element trees under generated elements that look like:
//    gen_container=Versions/router=NetRouter+One/gen_container=Installed+Routers/[generated element]

// Create an element tree.
var isSourceChild = true; // Make children contribute condition.
var routerName = 'NetRouter One'; // Will need to URL encode this for spaces or other special characters.
var child1 = createChildElement( element /* the generated element */, 'gen_container=Installed+Routers', isSourceChild );
var child2 = createChildElement( child1, 'router=' + formula.util.encodeURL( routerName ), isSourceChild );
var child3 = createChildElement( child2, 'gen_container=Versions', isSourceChild );

// Function to create and return a child on a parent.
function createChildElement( parentElement, childKey , isSourceChild ) {
   // Get the child (or create it if it does not exist).
   var child = server.getElement( childKey + '/' + parentElement.dname );
   if ( isSourceChild ) {
      // This child should contribute condition to the parent.
      bscm.addStaticMatches( parentElement, [ child ], false /* displaySourceElementsAsChildren */ );
   }
   // Prevent SCM from removing the element.
   bscm.addGeneratedElement( child );
   // Return the element.
   return child;
}

9.5.4 Building Core Views

//
// This script initiates the build of core views in the following order:
// Production Views --> _Common Views --> GRNs
// Production Views --> _Common Views --> Sybase Hosts
// Production Views --> _Common Views --> Consolidated Host List
//

load("custom/msAdapterUtils.fs");

var errHdr = "MONITOR_FAILED_TO_BUILD_VIEW: ";
    
function buildCoreViews()
{
    var adapterList = new Array();
    var runtimeAlarmDName;
    var viewDName;
    var viewObject;
    var status;

    formula.log.info("\n\n***************** Building Production Views --> _Common Views --> GRNs: STARTED");
    runtimeAlarmDName = "EBI-Element=Adapter+Runtime+Information/DEF_ESP_APPS2=AD_ESP_APPS2/root=Elements";
    adapterList[0] = new MSAdapterObject("AD_ESP_APPS2", runtimeAlarmDName, RUN_COMPLETED, ADAPTER_STARTED, false);
    adapterList[1] = new MSAdapterObject(NETCOOL_ADAPTER_NAME, "", "", NETCOOL_ADAPTER_STARTED, false);
    
    viewDName = "org=GRNs/org=_Common+Views/org=Production+Views/root=Organizations";
    viewObject = new MSViewObject(viewDName, adapterList);
    
    status = viewObject.buildView();
    if( status == false )
    {
        formula.log.error( errHdr + "core view " + viewDName + " build failed, aborting the entire view build process")
        return false;
    }
    formula.log.info("\n***************** Building Production Views --> _Common Views --> GRNs: COMPLETED\n");
    formula.log.info("Sleeping for 10 seconds before starting next view build...");
    java.lang.Thread.sleep( 10000 ); 
    
    
    formula.log.info("\n\n***************** Building Production Views --> _Common Views --> Sybase Hosts: STARTED");
    
    runtimeAlarmDName = "EBI-Element=Adapter+Runtime+Information/DEF_ESP_SYBASE_INFRA=AD_ESP_SYBASE_INFRA/root=Elements";
    
    adapterList.length=0;
    adapterList[0] = new MSAdapterObject("AD_ESP_SYBASE_INFRA", runtimeAlarmDName, RUN_COMPLETED, ADAPTER_STARTED, true);
    adapterList[1] = new MSAdapterObject(NETCOOL_ADAPTER_NAME, "", "", NETCOOL_ADAPTER_STARTED, false);
    
    viewDName = "org=Sybase+Hosts/org=_Common+Views/org=Production+Views/root=Organizations";
    viewObject = new MSViewObject(viewDName, adapterList);
    
    status = viewObject.buildView();
    if( status == false )
    {
        formula.log.error( errHdr + "core view " + viewDName + " build failed, aborting the entire view build process")
        return false;
    }
    formula.log.info("\n***************** Building Production Views --> _Common Views --> Sybase Hosts: COMPLETED\n");
    formula.log.info("Sleeping for 10 seconds before starting next view build...");
    java.lang.Thread.sleep( 10000 );
    
    
    formula.log.info("\n\n***************** Building Production Views --> _Common Views --> Consolidated Host List: STARTED");
    
    runtimeAlarmDName = "EBI-Element=Adapter+Runtime+Information/DEF_ESP_CHL3=AD_ESP_CHL3/root=Elements";
    adapterList.length=0;
    adapterList[0] = new MSAdapterObject("AD_ESP_CHL3", runtimeAlarmDName, RUN_COMPLETED, ADAPTER_STARTED, true);
    adapterList[1] = new MSAdapterObject(NETCOOL_ADAPTER_NAME, "", "", NETCOOL_ADAPTER_STARTED, false);
    
    viewDName = "org=Consolidated+Host+List/org=_Common+Views/org=Production+Views/root=Organizations";
    viewObject = new MSViewObject(viewDName, adapterList);
    
    status = viewObject.buildView();
    if( status == false )
    {
        formula.log.error( errHdr + "core view " + viewDName + " build failed, aborting the entire view build process")
        return false;
    }
    formula.log.info("\n***************** Building Production Views --> _Common Views --> Consolidated Host List: COMPLETED\n");
    formula.log.info("Sleeping for 10 seconds before starting next view build...");
    java.lang.Thread.sleep( 10000 );
    
    return true;
}
    

var server = formula.Administration.findElement('formulaServer=Server' );
// pause updates to Elements.ini
server.perform( session, 'Element|PausePersistence', [],[true] );

var result = buildCoreViews();

formula.log.info("Triggering a FULL GC if possible...");
java.lang.System.gc();
    
// resume updates to Elements.ini
server.perform( session, 'Element|PausePersistence', [],[false] );

if( result )
{
    formula.log.info( "Core view builds are done, wait for 3 minutes before starting state view builds." );
    java.lang.Thread.sleep( 180000 );
    var stateViewDName = "Job=Build+State+Views/jobs=Jobs/timeManagement=Time+Management/root=Administration";
    var jobElement = formula.Root.findElement( stateViewDName );
    if( jobElement.isJobRunning() )
    {
        formula.log.info( "State View refresh job is already running.")
    }
    else
    {
        try {
            formula.log.info( "Enabling job..." );
            jobElement.perform( session, 'Enable', [], [] );
        } catch( exception ) {
            formula.log.info("Caught exception when enabling job: " + exception);
        }

        try {
            formula.log.info( "Starting job..." );
            jobElement.perform( session, 'Run', [], [] );
        } catch( exception ) {
            formula.log.error( errHdr + "Caught exception when starting job: " + exception );
        }
    }
}