CUCM Monitoring (SXML)
via Provisioning Portal API

In this section, you will implement the following CUCM Serviceability XML API tasks utilizing the global classes in the Portal:

  1. Search for devices in the Real-Time Information Database
  2. Get CUCM services status information
  3. Get operformance monitoring counters from CUCM
  4. Verification

Step 1 - Device Search

Earlier you used Python to retrieve information from the Serviceability XML API. You will now incorporate similar functionality into the portal to retrieve the phone device registration details from your CUCM Real-Time Information Database. You will achieve this by leveraging the global CUCM SOAP API Python class mySXMLRisPort70Service that you instantiated earlier.

With the help of your CUCM SOAP API Python class mySXMLRisPort70Service you will send a selectCMDevice RisPort70 API request and relay the response if successful.

All of the changes again will be implemented in flaskr/api/v1/cucm.py
  1. In your VS Code tab, using the Explorer function, open up flaskr/api/v1/cucm.py
  2. In the cucm_device_search_api() class, def get(self): method, locate the existing line raise Exception('Not implemented yet!!') remove it and replace it with the following highlighted lines.

  3. Save this file by going to Application Menu → File → Save or by simply Pressing Ctrl+S

Step 2 - CUCM Services Status

Next let's work on the code to get CUCM Services Status using the Portal API. You will achieve this by leveraging the global CUCM SOAP API Python class mySXMLControlCenterServicesService that you instantiated earlier.

With the help of your CUCM SOAP API Python class mySXMLControlCenterServicesService you will send a soapGetServiceStatus Control Center Services API request and relay the response if successful.

All of the changes again will be implemented in flaskr/api/v1/cucm.py
  1. In your VS Code tab, using the Explorer function, open up flaskr/api/v1/cucm.py
  2. In the cucm_service_api() class, def get(self): method, locate the existing line raise Exception('Not implemented yet!!') remove it and replace it with the following highlighted lines.

  3. Save this file by going to Application Menu → File → Save or by simply Pressing Ctrl+S

Step 3 - CUCM Performance Monitoring Counters

Next let's work on retrieving CUCM performance monitoring counters using the Portal API. You will achieve this by leveraging the global CUCM SOAP API Python class mySXMLControlCenterServicesService that you instantiated earlier.

This Portal API will execute the following logic:

  1. If the perfmon_counters parameter is supplied, then do the following:
    1. Open a performance monitoring session
    2. Add the PerfMon counters that you would like to poll to the monitoring session
    3. Collect PerfMon session data to retrieve the counter values
    4. If any of the PerfMon counter names include a "%" or "Percentage", pause for 5 seconds and collect PerfMon session data again in order to get accurate sampling.
    5. Close the Performance Monitoring Session
  2. If perfmon_class parameter is supplied, collect the entire class of counters via the perfmonCollectCounterData API method

With the help of the CUCM SOAP API Python class mySXMLPerfMonService and the input parameters supplied you will execute the following CUCM PerfMon API methods in order to efficiently retrieve the performance monitoring counters' values.

and relay a final response if all PerfMon API requests are successful.

All of the changes again will be implemented in flaskr/api/v1/cucm.py
  1. In your VS Code tab, using the Explorer function, open up flaskr/api/v1/cucm.py
  2. In the cucm_perfmon_api() class, def post(self): method, locate the existing line raise Exception('Not implemented yet!!') remove it and replace it with the following highlighted lines.

  3. Save this file by going to Application Menu → File → Save or by simply Pressing Ctrl+S

Step 4 - Verification

You have added even more capabilities to your Provisioning Portal's APIs, now it is time to make sure it all works as expected, again utilizing your Portal's RESTPlus/Swagger UI page.

  1. In VS Code, make sure flaskr/api/v1/cucm.py file is saved
  2. Restart your Flask app by clicking the green restart button from the controller: which you should always see along the top of the window, when Flask is running.
    Or, if Flask is not started at all, click the Debug button on the left side followed by the green start/play button next to Start LTRCOL-2574 Portal
  3. If the Terminal window at bottom right shows: * Running on http://10.0.106.40.40:5000/ (Press CTRL+C to quit), then your Flask app is running.
  4. Access the RESTPlus/Swagger UI page at http://dev1.pod6.col.lab:5000/api/v1/
  5. Expand the cucm section.
  6. Perform the following individual checks:
    1. Search for Devices in the Real-Time Information Database
      1. Click the GET /cucm/device_search operation.
      2. At right, click Try it out.
      3. For the SearchItems Parameter, enter CSFPOD6UCMUSER
      4. In the expanded section, click Execute.
      5. Scroll down and examine the server response. You should note a server response code of 200 and a response body with the details of the Phone Device Configuration. Here is a sample response body:
            {
                "TotalDevicesFound": 1,
                "message": "Device Search Results Retrieved Successfully",
                "ris_search_result": {
                    "SelectCmDeviceResult": {
                    "CmNodes": {
                        "item": [
                        {
                            "CmDevices": {
                            "item": [
                                {
                                "ActiveLoadID": "Webex_for_Windows-44.5.0.29672",
                                ...
                                "Description": "Cisco Live LTRCOL-2574 - pod6ucmuser",
                                "DeviceClass": "Phone",
                                "DirNumber": "\+19197060001-UnRegistered",
                                "DownloadFailureReason": null,
                                "DownloadServer": null,
                                "DownloadStatus": "Unknown",
                                ...
                                "Httpd": "No",
                                "IPAddress": {
                                    "item": [
                                    {
                                        "Attribute": "Unknown",
                                        "IP": "10.0.106.45",
                                        "IPAddrType": "ipv4"
                                    }
                                    ]
                                },
                                "InactiveLoadID": "Webex_for_Windows-44.5.0.29672",
                                "IsCtiControllable": true,
                                "LinesStatus": {
                                    "item": [
                                    {
                                        "DirectoryNumber": "\+19197060001",
                                        "Status": "UnRegistered"
                                    }
                                    ]
                                },
                                "LoginUserId": "pod6ucmuser",
                                "Model": 503,
                                "Name": "CSFPOD6UCMUSER",
                                "NumOfLines": 1,
                                "PerfMonObject": 2,
                                "Product": 390,
                                "Protocol": "SIP",
                                "RegistrationAttempts": 0,
                                "Status": "UnRegistered",
                                "StatusReason": 0,
                                "TimeStamp": 1654799252
                                }
                            ]
                            },
                            "Name": "cucm1a.pod6.col.lab",
                            "NoChange": false,
                            "ReturnCode": "Ok"
                        }
                        ]
                    },
                    "TotalDevicesFound": 1
                    },
                    "StateInfo": ""
                },
                "success": true
            }

        If you recall, you deleted this CSF device in the last section, so you might be wondering why you are still getting a result back from this API call. The Real-time Information System (RIS) database is an in-memory store and does not pay attention to what is in the CUCM database. RIS will maintain information about unregistered devices for a period of time, even if the device has been deleted from the database. The in-memory store cleanup is controlled via CUCM RIS Data Collector Service Parameter named RIS Unused Cisco CallManager Device Store Period which defaults to 3 days and could be as high as 30 days.

    2. Get CUCM Services Status Information
      1. Click the GET /cucm/service operation.
      2. At right, click Try it out.
      3. For the Services Parameter, enter Cisco CallManager, Cisco Tftp
      4. In the expanded section, click Execute.
      5. Scroll down and examine the server response. You should note a server response code of 200 and a response body with the uuids of the newly added phone and the associated user you just updated. Here is a sample response body:
            {
                "message": "Service(s) Status Info Retrieved Successfully",
                "service_info": {
                    "ReasonCode": -1,
                    "ReasonString": null,
                    "ReturnCode": {
                    "_value_1": "0"
                    },
                    "ServiceInfoList": {
                    "item": [
                        {
                        "ReasonCode": -1,
                        "ReasonCodeString": " ",
                        "ServiceName": "Cisco CallManager",
                        "ServiceStatus": "Started",
                        "StartTime": "Mon May  2 21:09:13 2024",
                        "UpTime": 1108052
                        },
                        {
                        "ReasonCode": -1,
                        "ReasonCodeString": " ",
                        "ServiceName": "Cisco Tftp",
                        "ServiceStatus": "Started",
                        "StartTime": "Mon May  2 21:09:21 2024",
                        "UpTime": 1108044
                        }
                    ]
                    }
                },
                "success": true
            }
                                
    3. Get Performance Monitoring Counters from CUCM
      1. Click the POST /cucm/perfmon operation.
      2. At right, click Try it out.
      3. For the payload Parameter, enter the following payload.
      4. In the expanded section, click Execute.
      5. Scroll down and examine the server response. You should note a server response code of 200 and a response body with the uuid phone device you just updated Here is a sample response body:
            {
                "message": "PerfMon Data Retrieved Successfully",
                "perfmon_class_result": [
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Allocated FDs"
                    },
                    "Value": 7712
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Being Used FDs"
                    },
                    "Value": 7712
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Freed FDs"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOAwait"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOCpuUtil"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOKBytesReadPerSecond"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOKBytesWrittenPerSecond"
                    },
                    "Value": 229
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOPerSecond"
                    },
                    "Value": 24
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOReadReqMergedPerSecond"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOReadReqPerSecond"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOReqQueueSizeAvg"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOSectorsReadPerSecond"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOSectorsReqSizeAvg"
                    },
                    "Value": 18
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOSectorsWrittenPerSecond"
                    },
                    "Value": 458
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOServiceTime"
                    },
                    "Value": 0
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOWriteReqMergedPerSecond"
                    },
                    "Value": 8
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\IOWriteReqPerSecond"
                    },
                    "Value": 24
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Max FDs"
                    },
                    "Value": 582286
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Total CPU Time"
                    },
                    "Value": 109266374
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Total Processes"
                    },
                    "Value": 207
                    },
                    {
                    "CStatus": 1,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\System\\Total Threads"
                    },
                    "Value": 1138
                    }
                ],
                "perfmon_counters_result": [
                    {
                    "CStatus": 0,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\Cisco CallManager\\RegisteredOtherStationDevices"
                    },
                    "Value": 2
                    },
                    {
                    "CStatus": 0,
                    "Name": {
                        "_value_1": "\\\\cucm1a.pod6.col.lab\\Cisco Tomcat Connector(http-bio-8443)\\ThreadsBusy"
                    },
                    "Value": 1
                    }
                ],
                "success": true
            }

Congratulations! You have added some core CUCM monitoring capabilities to your Portal APIs that allows you to keep an eye on the health and operational state of your CUCM servers. Let's add some core REST API capabilities to your Portal which will help you with other UC Applications (Webex, CUC, and CMS)