Skip to main content

skip to main content

developerWorks  >  Autonomic computing  >

Create a simple resource model for processing Common Base Events from a file

developerWorks
Document options

Document options requiring JavaScript are not displayed

Sample code


Rate this page

Help us improve this content


Level: Introductory

Neeraj Joshi (jneeraj@us.ibm.com), Staff software engineer, IBM
Balan Subramanian (bsubram@us.ibm.com), Staff software engineer, IBM
Brad Topol (btopol@us.ibm.com), Senior software engineer, IBM

15 Jun 2004

This article describes how to create a simple resource model for processing Common Base Events that are stored in a file. First, it describes how to build a new resource model management project that can read Common Base Events. It then shows how to modify the decision tree script associated with this resource model to add trace statements to validate that the Common Base Events are being passed to the resource model. Finally, it demonstrates how to export the resource model as an AME package and how to deploy and test this package on AME using a simple logfile containing Common Base Events.

Introduction

In this article, you'll go through the steps for using the IBM Autonomic Computing Toolkit's Resource Model Builder to create a simple resource model for the Autonomic Management Engine (AME). The resource model is capable of processing Common Base Events stored in a file. You'll modify the decision tree script associated with this resource model to add trace statements to validate that the Common Base Events are being passed to the resource model. Finally, you'll learn how to export the resource model as an AME package and how to deploy and test this package on AME using a simple logfile containing Common Base Events.



Back to top


Prerequisites

This article assumes you have installed the Autonomic Management Engine (AME) and the Resource Model Builder from the Autonomic Computing Toolkit (see Resources). It also assumes that you installed the Problem Determination scenario. Because all you need from the scenario is the zip file CanonicalSituationMonitor.zip, use the do not check prerequisites option when you install the scenario. Information on how to download these components can be found in Resources.

The resource model described in this article requires a text file from which the resource model reads in Common Base Events. We have provided this type of sample text file for you to use. Unzip this file as CBEout.log and place this file as c:\CBEout.log for the example described in this article to work properly.



Back to top


Creating a new resource model management project

The first step in creating a resource model is to start the Resource Model Builder. It can typically be started by selecting Start > Programs > IBM WebSphere Studio> Resource Model. Figure 1 illustrates what the Resource Model Builder containing no existing no projects looks like once it has been started.


Figure 1. Empty resource model builder
Empty resource model builder

After the resource model builder has been started, you need to create a new resource model project. To do this, select File > New > Project. Here, you are presented with a new project selection panel as shown in Figure 2. From this panel, select Tivoli Management Project and click Next.


Figure 2. Creating a new Tivoli Management Project project
Creating a new Tivoli Management Project project

Now, you are presented the Project Name box as shown in Figure 3. Enter CBE_RM in the Project name field and click Next.


Figure 3. Adding the project name
Adding the project name

After the project name is entered, you are shown a panel that let you select the Basic Resource Model Wizard, as shown in Figure 4. Click Basic Resource Model Wizard.


Figure 4. Select the Basic Resource Model Wizard
Select the Basic Resource Model Wizard

Once this wizard is initiated, you are asked to select a platform and scripting language. As shown in Figure 5, select w32-ix86 because you are building a resource model for use on a Windows® platform. Then select JavaScript as the scripting language and click Next.


Figure 5. Select the platform and scripting language
Select the platform and scripting language

The resource model we are creating relies on a Common Information Model (CIM) class as its mechanism for pulling in Common Base Events from a file. To add this to the resource model, we need to use the CIM/WMI data source wizard to incorporate the needed CIM class into the resource model. As shown in Figure 6, select CIM/WMI Datasource on the Datasource selection page.


Figure 6. Select the CIM/WMI data source wizard
Select the CIM/WMI data source wizard

As shown in Figure 7, the CIM/WMI data source wizard let us look through the CIM repository on the local machine for our CIM class. Because the CIM class might not have been compiled or stored in the repository, we will compile the Managed Object Format (MOF) file that contains our CIM class and then store the CIM class into the repository. To begin these steps, we need to select Mof Compiler shown in Figure 7. At this point, we are shown the panel presented in Figure 8, which provides us with an opportunity to compile a MOF file. Click Go to continue with this operation.


Figure 7. Invoking the Mof Compiler
Invoking the Mof Compiler

Figure 8. Selecting a MOF compiler operation
Selecting a MOF compiler operation

We now need to find the MOF file that contains the CIM class we will be using for our resource model. The file we need, CanonicalSituationMonitor.mof, can be found in the CanonicalSituationMonitor.zip file discussed in Prerequisites. First expand this zip file, then unzip __win32-ix86__CanonicalSituationMonitor.zip to find the CanonicalSituationMonitor.mof file. Place this file somewhere where you can browse for it. With this file now available, you can specify it as the file you need in the browse field of the panel shown in Figure 9. Also note that on this MOF selection panel, you must change the namespace field to root/default. After you have specified these two values, click Next.


Figure 9. Select the MOF file and namespace
Select the MOF file and namespace

Figure 10 shows the next panel displayed. This panel lets you change the CIM class update options. For this panel, go ahead and use the defaults and click Finish.


Figure 10. Specify update options
Specify update options

With the update options specified, you can now view the results of compiling the CIM class contained in the CanonicalSituationMonitor.mof file. The compiler output field on the panel should state that the MOF file has been successfully parsed and stored in the repository as shown in Figure 11.


Figure 11. Viewing the MOF compiler output
Viewing the MOF compiler output

With the compiled CIM class now stored in the CIM repository, you can connect to the repository and extract a copy of this CIM class for use in the resource model. Do this by changing the namespace field in the panel shown in Figure 12 to root\default. Then click Connect, which is shown on the panel as a lightning bolt.


Figure 12. Connecting to the CIM repository
Connecting to the CIM repository

After you have connected to the repository, you should now see that a CommonSituationsEvent CIM class is available for you to select. As shown in Figure 13, select this class and click Next.


Figure 13. Selecting the CIM class from the CIM repository
Selecting the CIM class from the CIM repository

After selecting this CIM class, you need to select the properties of the class that you are interested in using inside of the resource model. Two default properties, FileName and Offset, should already be selected and listed as selected properties as shown in Figure 14. The other property you need is the situation property. The situation property contains a single Common Base Event when this value is passed into the resource model. To select this property, highlight the situation property and click the right arrow button to move it to the selected properties list. The selected properties list should now look the list shown in Figure 15.


Figure 14. Select properties
Select properties

Figure 15. Completion of selected properties
Completion of selected properties

The next panel, shown in Figure 16, allows you to set some advanced filtering conditions for the Common Base Event data you are sending to the resource model. You do not need this feature, so click Next.


Figure 16. Set filtering conditions
Set filtering conditions

The next panel, shown in Figure 17, lets you specify some event triggers if you want to send events (for example, to a component like the Tivoli® Event Console) based upon the particular Common Base Events passed to the resource model. You do not need this feature, so click Next.


Figure 17. Specification of event triggers
Specification of event triggers

The panel in Figure 18 lets you choose properties you want to log. You do not need to log any properties, so click Finish.


Figure 18. Select properties to log
Select properties to log

At this point, you have specified all the characteristics associated with the CIM class. You can now add the CIM class to the resource model by clicking Finish on the panel shown in Figure 19.


Figure 19. Add class to the resource model
Add class to the resource model

With the CIM class added to the project, you now need to give the resource model a more meaningful internal name. As shown in Figure 20, set the internal name to CBERM_CommonSituationsEvent and click Next.


Figure 20. Setting the model internal name
Setting the model internal name

Now, it's time to set the cycle time for the resource model. The cycle time refers to the time interval that the resource model waits before deciding to read for monitoring input. The smaller the cycle time, the more quickly the resource model will receive monitored input. The trade off with this is that the smaller the cycle time, the greater the amount of CPU resources that the resource modeling engine uses. For our example, go ahead and set the cycle time to 20 seconds, as shown in Figure 21.


Figure 21. Setting the cycle time
Setting the cycle time

Now, select a folder name for the resource model project. As shown in Figure 22, select the CBE_RM folder and click Finish.


Figure 22. Select the project folder
Select the project folder

You have now finished all the steps required by the basic resource model wizard. As shown in Figure 23, click Finish.


Figure 23. Project creation wizard completion
Project creation wizard completion

You now have a basic resource model project from which you can work. Your resource model builder should look like the snapshot in Figure 24. In the next section, we begin to add some necessary customizations to this resource model project.


Figure 24. Created CBE_RM resource model project
Created CBE_RM  resource model project

Adding parameters to the resource model

The CIM class we use in this resource model (located in the CanonicalSituationMonitor.mof file) contains parameters to allow it to easily change the name of the file from where it should read Common Base Events. You need to add a parameter to the resource model that maps to the parameter in the CIM class and sets the file name that you want it to read from. To add this parameter to the resource model, click on on the plus sign next to CBE_RM and the plus sign next to CBERM_CommonSituationsEvent.jrm to expand the project. Then click on Parameters to show the Parameters page as illustrated in Figure 25.


Figure 25. Viewing the parameters editor
Viewing the parameters editor

Now, click on the parameters icon in the resource model to add the parmLogName parameter needed by the CIM class. Click on Add Parameter shown in Figure 26. When you update the internal name of the parameter, you might be asked if you want to update the references to parmLogName. Click Yes.


Figure 26. Adding a new parameter
Adding a new parameter

After clicking Add Parameter, fill in the internal name field with the value parmLogName. Next, fill in the Descriptive name field and the Description fields as shown in Figure 26. Then click Add and an Add New Parameter Value dialog box opens. Fill in the value of the path to the file that contains the Common Base Events, which in this example is c:\CBEout.log (make sure that this is the name and location of the file containing your Common Base Events for everything to work properly). Click on the floppy disk icon to save your changes to the resource model.

Adding dependences to the resource model

The resource model has several file and library dependences that must be included for it to function properly. Click on the Dependencies folder to open the dependencies editor. Then, click on the w32-ix86 subfolder and Add, as shown in Figure 27.


Figure 27. Viewing the dependencies editor
Viewing the dependencies editor

You then need to browse for the files listed below. They can be found in the CanonicalSituationMonitor.zip file. First, expand this zip file, then unzip __win32-ix86__CanonicalSituationMonitor.zip to find the following required files:

  • gnuregexp1.1.1.jar
  • itmcs_loggingtools.jar
  • itmcs_util.jar
  • jlog2_pdxml.jar
  • log.jar
  • wmftools.jar
  • itmcsLog.properties
  • CanonicalSituationMonitor.mof

Check w32-ix86 as the supported platform as shown in Figure 28 and click OK for each dependency.


Figure 28. Adding a dependency
Adding a dependency

When you have finished adding all the dependences, save your changes to the resource model. The Dependency Editor should then look similar to Figure 29.


Figure 29. Completed list of added dependences
Completed list of added dependences

Decision tree script enhancements

The decision tree script portion of a resource model is the component where the resource model hands off to you the Common Base Events it receives, and you are allowed to write a JavaScript module to manipulate the Common Base Events. It is at this point where you can then perform some analysis on the Common Base Events and take any needed autonomic actions.

To keep the resource model in this example simple, we are only going to print out the Common Base Events we receive to a trace file. In a subsequent article we will show how, from this JavaScript module, we can pass the Common Base Events to a Java module for advanced analysis and processing.

We will now continue by adding some functionality to the decision tree script of the resource model. The initial decision tree script provided to us when we created the resource model project is a piece of JavaScript code. Click on the source folder to open the decision tree script source editor as shown in Figure 30.


Figure 30. Decision tree script source editor
Decision tree script source editor

The first enhancement you are going to make to the decision tree script is to print a trace file of the Common Base Event the resource model is handing off to you to ensure that the resource model engine is functioning properly. You will perform this enhancement by scrolling down in the source window to the VisitTree function (the VisitTree function is the one used to hand the CommonBaseEvents off to you for processing). Underneath the following line of code:

Svc.SetMapStrElement(hPropTable, "situation", curCommonSituationsEventsituation);

add the lines shown in Listing 1.


Listing 1. Trace statements to add to the VistTree function
Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "*** Printing out received CommonBaseEvent ***");
Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "===> CBE = " + curCommonSituationsEventsituation);

Listing 2 shows how complete VisitTree function should look, and Figure 31 shows what the enhancements look like when viewed in the resource model builder.


Listing 2. VistTree function with new trace statements added
// VisitTree contains the monitoring algorithm
// It is called cyclically after a cycle time has elapsed
// Implement the monitoring code here
function VisitTree(Svc)
{	
   //vars for data source: CommonSituationsEvent
   var curCommonSituationsEventOffset;
   var curCommonSituationsEventFileName;
   var curCommonSituationsEventsituation;
   var hPropTable;
   var numOfInstances;
   var idx;
   var ParamCount;
   var ParamIdx;
   var Different;
   hPropTable = Svc.CreateMap();
   //triggering logic for data source: CommonSituationsEvent
   numOfInstances = Svc.GetNumOfInst("CommonSituationsEvent");
   for(idx = 0; idx < numOfInstances; idx++){
      Svc.RemoveMapAll(hPropTable);
      //Handle numeric properties
      curCommonSituationsEventOffset = Svc.GetNumProperty("CommonSituationsEvent", 
      idx, "Offset");		      
      Svc.SetMapNumElement(hPropTable, "Offset", curCommonSituationsEventOffset);
      //Handle string properties
      curCommonSituationsEventFileName = Svc.GetStrProperty("CommonSituationsEvent", 
      idx, "FileName");		            
      Svc.SetMapStrElement(hPropTable, "FileName", curCommonSituationsEventFileName);
      curCommonSituationsEventsituation = Svc.GetStrProperty("CommonSituationsEvent", 
      idx, "situation");		      
      Svc.SetMapStrElement(hPropTable, "situation", curCommonSituationsEventsituation);
      Svc.Trace(TRACE_FINEST, TRACE_SOURCE + 
      "*** Printing out received CommonBaseEvent ***");
      Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "===> CBE = " + 
      curCommonSituationsEventsituation);
   }
   Svc.DestroyMap(hPropTable);
   return (0);
}	  


Figure 31. Source view of adding extra trace to the VisitTree function
Source view of adding extra trace to the VisitTree function

Adding the parameter association to the decision tree script

Earlier in this article, we used the Parameters Editor to define for the resource model a parmLogName parameter that identifies the file that contains the Common Base Events we want to pass into the resource model. In addition to defining this parameter, we must also bind it to our CIM class using a provided function called AssociateParameterToClass. Only after this association has been performed will the CIM class be cognizant of the actual name and path of the file it is expected to monitor. Perform this enhancement by scrolling down in the source window to the Init function and underneath the following code:

Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "Init entered");

add the lines shown in Listing 3.


Listing 3. Parameter association code to add to Init function
   Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "Init Associate parmLogName to CSF");
   Svc.AssociateParameterToClass("parmLogName", "CommonSituationsEvent");

The reason for adding this code to the Init function is that this function executes when the resource model is initialized and, therefore, this is the appropriate spot to inform the CIM class of the file name parameter it requires. Listing 4 shows what the complete Init function should now look like, and Figure 32 shows what the enhancements look like when viewed in the resource model builder.


Listing 4. Init function with parameter association added
// Init is called by the DM For Windows Analyzer after that
// the resource model default settings have been overridden
// It is called only once, when the resource model is started.
// You can write additional initializing code in this function if required
// to use the thresholds and parameters values
function Init(Svc)
{
   Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "Init entered");
   Svc.Trace(TRACE_FINEST, TRACE_SOURCE + "Init Associate parmLogName to CSF");
   Svc.AssociateParameterToClass("parmLogName", "CommonSituationsEvent");
   return (0);
}    


Figure 32. Source view of adding parameter association to the VisitTree function
Source view of adding parameter association to the VisitTree function


Back to top


Deploying and testing the resource model on AME

The resource model is now complete. You can now export it as a package that will execute on the Autonomic Management Engine (AME). Make sure the decision tree script window is in focus. Then, click ITM. From the pull-down menu, select generate package, and click AME (zip).( If this option is grayed out, that means that you did not click in the decision tree script window and put it in focus.) Make sure you save the exported package as CBERM_CommonSituationsEvent.zip. It is not important what directory you save it to, just remember where you put it so you can find when it is time to deploy. Figure 33 illustrates exporting the resource model package.


Figure 33. Exporting the resource model package
Exporting the resource model package

Starting AME

With the package created and exported, you can attempt to deploy and test it on AME. Open a command prompt and navigate to the directory where you installed AME. Next, navigate to the sara subdirectory. From there, run the sara.bat command from the command prompt to start the resource model engine:

C:\AME\sara>sara.bat

The command returns with a ready prompt such as the following:

ready:

At the ready prompt, type the startrme command to start the AME engine. Use the reset option if you want to clear out any previously installed resource models. Here is an example:

ready: startrme -reset
ready: RME started.

At this point the AME engine is started.

Installing the CBERM_CommonSituationsEvent resource model

Next, you need to install the resource model. The instrmtype command is used to install a resource model, and it takes the path to the zip file representing the resource model as a parameter. To install the CBERM_CommonSituationsEvent resource model, use a command such as:

ready: instrmtype C:\developerWorks\autonomic\autonomic1\CBERM_CommonSituationsEvent.zip
ready: Resource Model Type ' CBERM_CommonSituationsEvent ' installed.

Creating an instance of the CBERM_CommonSituationsEvent resource model

With the resource model installed, you now must create an instance of it. Use the mkrminstance command to create an instance of a resource model. To make an instance of the CBERM_CommonSituationsEvent resource model enter the following commands:

ready: mkrminstance CBERM1 CBERM_CommonSituationsEvent
ready: Resource Model Instance 'CBERM1' created.

Starting an instance of the CBERM_CommonSituationsEvent resource model

With the resource model instance created, all that is left to do is to start the instance. Use the startrminstance command to start an instance of a resource model. To start an instance of the CBERM_CommonSituationsEvent resource model, type:

ready: startrminstance CBERM1
ready: Resource Model Instance 'CBERM1' started.

Stopping the resource model engine

Let the resource model run for approximately 30 seconds to pick up the log records from the CBEOut.log file. You can stop the resource model by executing the quit command similar to:

ready: quit
ready: bye

A snapshot of the execution of all of the above commands is provided in Figure 34.


Figure 34. Command prompt output from running RME
Command prompt output from running RME


Back to top


Checking your results

You can now open the AME log file to see if trace statements you added to the resource model verify that the Common Base Events were read from the file and sent to the resource model. From the sara subdirectory, change directories to the logs subdirectory. Inside of this directory you should see a trace.log file. If you open up this trace file, you should see trace statements similar to those in Listing 5. An easy way to search for the trace statements you added is to search for ===>.


Listing 5. Resource model trace output
2004-05-20 23:32:10.608-05:00 com.ibm.amw.rme.impl.analyzer.RMServiceImpl DECSCRIPT
     stingerbt5 IP RM TRACE: *** Printing out received CommonBaseEvent ***

2004-05-20 23:32:10.608-05:00 com.ibm.amw.rme.impl.analyzer.RMServiceImpl DECSCRIPT 
     stingerbt5 IP RM TRACE: ===> CBE = <CommonBaseEvent 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.ibm.com/AC/commonbaseevent1_0_1" 
creationTime="2004-02-16T20:22:50" extensionName="CommonBaseEvent" 
globalInstanceId="N082DE9000E711D88000B36AA6C6A928"
localInstanceId="9.42.117.481076981029625-523299866" 
msg="PMGR0000E: Call stack:" severity="50" 
version="1.0.1"><contextDataElements name="myContext" 
type="String"><contextValue>contextValue</contextValue>
</contextDataElements><sourceComponentId 
componentType="AppServer" application="ApplicationServer" 
component="WebSphere" componentIdType="ProductName" 
executionEnvironment="acdevx1\acdevx1\server1" 
location="9.42.117.48" locationType="IPV4" processId="1312" 
subComponent="com.ibm.ws.ejbpersistence.dataaccess.DataAccessRequestImpl"
threadId="9cadfb6"/><msgDataElement 
msgLocale="en-US"><msgId>PMGR0000E</msgId>
<msgIdType>IBM4.4.1
</msgIdType></msgDataElement>
<situation categoryName="ConnectSituation"><situationType 
reasoningScope="EXTERNAL" situationDisposition="CLOSED" 
successDisposition="UNSUCCESSFUL" 
xsi:type="ConnectSituation"/></situation>
</CommonBaseEvent>

2004-05-20 23:32:10.618-05:00 com.ibm.amw.rme.impl.analyzer.RMServiceImpl 
DECSCRIPT      
stingerbt5 IP RM TRACE: *** Printing out received CommonBaseEvent ***

2004-05-20 23:32:10.618-05:00 com.ibm.amw.rme.impl.analyzer.RMServiceImpl 
DECSCRIPT      
stingerbt5 IP RM TRACE: ===> CBE = <CommonBaseEvent 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.ibm.com/AC/commonbaseevent1_0_1" 
creationTime="2004-02-16T21:30:50" extensionName="CommonBaseEvent" 
globalInstanceId="N082DE9000E711D88000B36AA6C6A929"
localInstanceId="9.42.117.481076981029625-523299867" 
msg="PMGR0000E: Call stack:" severity="50" 
version="1.0.1"><contextDataElements name="myContext" 
type="String"><contextValue>contextValue</contextValue></contextDataElements>
<sourceComponentId 
componentType="AppServer" application="ApplicationServer" 
component="WebSphere" componentIdType="ProductName" 
executionEnvironment="acdevx1\acdevx1\server1"
location="9.42.117.48" 
locationType="IPV4" processId="1312" 
subComponent="com.ibm.ws.ejbpersistence.dataaccess.DataAccessRequestImpl"
threadId="9cadfb6"/><msgDataElement
msgLocale="en-US"><msgId>PMGR0000E</msgId><msgIdType>IBM4.4.1
</msgIdType></msgDataElement>
<situation categoryName="ConnectSituation">
<situationType reasoningScope="EXTERNAL" situationDisposition="CLOSED" 
successDisposition="UNSUCCESSFUL" xsi:type="ConnectSituation"/></situation>
</CommonBaseEvent>



Back to top


Hints and Tips

When AME reads from a log file, a properties file called LOGFILENAME.properties is created in the location returned by the JAVA get Temp directory API. Usually it would be in the C:\Documents and Settings\USERNAME\Local Settings\Temp\logfiles directory. You must delete this file if you want AME to start re-reading from the beginning of the log file.



Back to top


Summary

In this article, we described how to use the Autonomic Computing Toolkit's Resource Model Builder to create a simple resource model for processing Common Base Events stored in a file. We leveraged the CanonicalSiutationsEvent CIM class that comes with the with the Problem Determination scenario from the Autonomic Computing Toolkit to create a resource model that can read Common Base Events from a file. We then showed how to modify the decision tree script associated with this resource model to add trace statements to validate that Common Base Events are being passed to the resource model. Finally, we demonstrated how to export the resource model as an AME package and how to deploy and test this package on AME using a simple logfile containing Common Base Events. In a future article, we will show how to modify the decision tree script to enable you to pass the Common Base Events to to a Java module for advanced analysis and processing.




Back to top


Download

NameSizeDownload method
ac-mohawk1source.zipHTTP
Information about download methods


Resources



About the authors

Neeraj Joshi works as a staff software engineer in the Autonomic Computing Division of IBM. He has a master's degree in computer science from North Carolina State University. He can be reached at jneeraj@us.ibm.com.


Author photo

Balan Subramanian enjoys working as a Staff Software Engineer in the Autonomic Computing group at IBM in Research Triangle Park, North Carolina, focusing on data collection, problem determination, and provisioning. His other interests include Web services, grid services, and pervasive computing. A Sun Certified Java Programmer, Balan received his master's degree in computer science from George Mason University in 2000 with a thesis on Web services performance. He was also a core developer on the IBM Generic Log Adapter for Autonomic Computing and as a development co-op on the AUIML toolkit. He has previously worked at IBM India. He can reached at bsubram@us.ibm.com.


Brad Topol is a senior software engineer for IBM in Research Triangle Park, North Carolina, in the WebSphere Platform System House Advanced Technology group. He received a Ph.D. in computer science from the Georgia Institute of Technology in 1998. Currently, he is actively involved in advanced technology projects in the areas of Autonomic Computing, Web services, and Aspect-Oriented Programming. He can be reached at btopol@us.ibm.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top