Meeting Server API
via Provisioning Portal API

As with CUPI, in flaskr/cms/v1/cms.py we have provided a CMS class that extends the REST class, this time with a base_url of /api/v1 and a header as:

A dictionary of error codes is also built, which is pulled from the CMS documentation to provide some more useful error information instead of just a code.

In this CMS class, we also have two methods which provide the same features as the CUPI class, but must process things slightly differently because of the XML return data:

  • _cms_request() - sends the request using the REST _send_request(), checks for basic errors and then returns the parsed response from _cms_parse_response(). The _cupi_request() method takes the following variables, exactly as with the CUPI class:
    • api_method: The API method, such as "coSpaces" that will be used with the existing base_url to form a complete url, such as "/api/v1/coSpaces"
    • parameters: A dictionary of URL parameters to be sent, such as {'offset': 10}
    • payload: The payload to be sent, used with a POST or PUT
    • http_method: The request verb. CUPI only supports 'GET', 'PUT', 'POST', and 'DELETE'
  • _cms_parse_response() - this function parses the response and then performs the following tasks:
    1. Return the response data, converted from XML, in a predictable format
    2. For a POST request, return the result in the location header
    3. Return information about error conditions, which are XML return codes for which there is more information that can be provided.

Once the CMS class is built, you can initialize the class globally, as before. CMS actually does not implement any sessions that could be over-utilized. In this case, the Session will still work as before; it simply will never get a JSESSIONID to use as part of the request header. With the class initialized, you can add functions that send requests similar to what you did with Postman, however, you can fine-tune this data to return exactly what you want. For example, the Get Version function will query the /system/status endpoint in CMS as before, but we will only return the version, since that is all that was asked for.

In this lab, we have assumed that if users are assigned personal CMS Spaces, then they will be created with the user ID as the uri, the telephone number as a secondaryURI, and the name of the Space built from the user's display name. These properties could be retrieved from an LDAP directory, but for this lab we chose to implement a UDS-based query using the exact same REST class you already built. It is already initialized as myCUCMuds and only has one callable function, get_user(userid), that returns a response dictionary with a userName, phoneNumber, and displayName that we can use.

This will allow you to build a POST to create a Space using the information from the data in UDS of the CUCM--and return an error, if that user does not exist in the CUCM.

Just as with CUPI, user modifications/deletions will require you to look up users by user ID. In this lab's case, that means trying to mach a user ID to a URI, a field which you will have populated with the user ID when the Space was created. The challenge is that CMS does not allow you to do a direct lookup. It only allows you to add a filter= parameter, which is always a wildcard filter. In other words, to search for a specific user, you must first search with a filter, then for the results returned, you need to look through each of them to see if the user id you are searching for matches the URI field.

To complicate things further, CMS can throttle responses, limiting the number of objects returned to 10 (per documentation). To retrieve more results than that, you have to implement paging; that is to say repeating the same query, each time adjusting the offset in order to get the next "page."

In this section, you will implement and verify the following Cisco Meeting Server API tasks:

  1. Retrieve the Version
  2. Retrieve a CMS Space by User Id
  3. Create a CMS Space by User Id
  4. Modify a CMS Space by User Id
  5. Delete the Space by User Id
  6. Verification

Step 1 - Retrieve the Version

When working with Postman, you retrieved the system status from CMS, which included the version. In this case, you can first write a function to return the CMS version directly, using the information from the system status query.

  1. In your VS Code tab, open up flaskr/api/v1/cms.py
  2. As you did previously with CUPI, the first step is to instantiate the CMS object near the top of the file. Add the following lines:

  3. In the cms_version_api() class, under the get() function, replace the pass line with the following highlighted text:

  4. Save this file.

Step 2 - Retrieve a CMS Space by User Id

Using Postman, you were able to retrieve a list of Spaces and an individual Space using the Space ID. But in your web portal, you will want to retrieve, create, update, and delete a CMS space using only a user id, where the user ID is mapped to a URI associated with the Space.

Since all of these tasks require retrieving a list of Spaces and then searching through them to see if the user ID matches a Space URI, you should put that capability in its own function.

  1. In your VS Code tab, open up flaskr/api/v1/cms.py
  2. The main function to retrieve the ID of the coSpace using the user ID is get_coSpace_id(). Logically, it needs to:
    1. Query the coSpaces using the user ID as the filter (in order to reduce the number of coSpaces returned in the reponse)
    2. Check if all coSpaces were returned in the response, or if it is a partial list, since CMS will limit the number of items returned, but at the same time will indicate how many matches there are.
    3. For the coSpaces returned, check if the URI/secondaryURI of these coSpaces matches the user id you are searching for exactly.
    4. If the original response did not include all coSpaces that matched the filter, then you need to repeat your query one or more times, each time repeating checks on the response and using the offset capability to retrieve the "next" set of matches.
    Add the following lines:

  3. The get_coSpace_id() function also utilizes another function, called match_space_uri(), that searches a provided list of Spaces and if one of those Space's URI/Secondary URI matches the user ID you are searching for, then return the ID of that Space.

    Replace the pass line with the following highlighted text in the match_space_uri() function:

Step 3 - Retrieve a CMS Space by User Id

Now that you have the ability to look up a Space by the user ID, you just need to add the code to call that function.

  1. In your VS Code tab, open up flaskr/api/v1/cms.py
  2. In the get() function of the cms_spaces_api() class, replace the pass line with the following highlighted return line:

  3. Save this file.
  4. Since you don't have a user created at this time, you can verify this code later, after the ability to add and modify users is added.

Step 4 - Create a CMS Space by User ID

Creating a CMS Space was not very difficult in Postman. You simply need to send a POST request to /coSpaces. Even without any other parameters, a Space is created. But for this portal you would like to specify a user ID when creating the Space. With the user ID, you should be able to look up properties about the user. The source of this information might be Active Directory, but here we will use the CUCM's User Data Server (UDS).

THe UDS class we have created for you is another very simple REST service, which can send user searches for user IDs in the CUCM. For this, we have built a get_user() function which takes a user string. Utilizing the same REST class, it returns the same response dictionary containing the following keys:

  • success (boolean) - whether or not the request succeeded
  • message (string) - Detailed message about the message sent/received
  • response (string) - the user, if found
  • num_found (integer) - number of users found (should be 0 or 1 for us)
You can use this to populate the CMS Space URI with the user ID, the secondaryURI with the telephone Number, and generate a name based on the user's display name property. Obviously you could use any other fields available to use via UDS.

  1. In your VS Code tab, open up flaskr/api/v1/cms.py
  2. In the cms_spaces_api() class, under the post() function, add the following highlighted lines:

  3. Save this file.

Step 5 - Modify a CMS Space by User Id

Modifying a CMS object is much simpler. You use get_coSpace_id(). If the response is successful, then you can send the PUT request to CMS with the retrieved Space ID. Otherwise you can respond an errored user lookup (which could have failed because the user was not found or because there was some error communicating with CMS).

  1. In your VS Code tab, open up flaskr/api/v1/cms.py
  2. Under the put() function of the cms_spaces_api() class, insert the following highlighted lines:

  3. Save this file.

Step 6 - Delete the Space by User Id

Similar to Space modification, a CMS Space Delete uses get_coSpace_id() to look up the Space's ID which is used to generate a DELETE request to CMS.

  1. In your VS Code tab, open up flaskr/api/v1/cms.py
  2. In the cms_spaces_api() class, under the delete() function, replace the pass line with the following highlighted lines:

  3. Save this file.

Step 7 - Verification

You have added a lot of code so far, now it is time to make sure it works as expected.

  1. In VS Code, make sure flaskr/api/v1/cms.py 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 Swagger UI page at http://dev1.pod6.col.lab:5000/api/v1/
  5. Expand the cms section.
  6. Perform the individual checks:
    1. Retrieve the Version
      1. Click the GET /cms/version method.
      2. At right, click Try it out.
      3. Click Execute.
      4. Examine the response populated below. You should note a Server response code of 200 and a response body with the version.
    2. Create a CMS Space by User Id
      1. Click the POST /cms/spaces/{userid} operation.
      2. At right, click Try it out.
      3. Enter the user ID: pod6user1
      4. Click Execute.
      5. Examine the response. You should note a Server response code of 200 and the results should show a message with the new object's ID. For example:

        The "message" contains the object ID of the new Space.
    3. Modify a CMS Space by User Id
      1. Click the PUT /cms/spaces/{userid} operation.
      2. At right, click Try it out.
      3. Change the name to New Pod6 User1 Space
      4. Change the defaultLayout to allEqual
      5. Enter the user ID: pod6user1
      6. Click Execute.
      7. Examine the response. You should note a Server response code of 200 and the results should success as true.
    4. Retrieve a CMS Space by User Id
      1. Now look up that Space by ID. Within the Swagger UI, click the GET /cms/spaces/{userid} operation.
      2. At right, click Try it out.
      3. Enter the user ID: pod6user1
      4. Click Execute.
      5. Examine the response. Make sure the name has been changed to New Pod 6 User1 Space and the defaultLayout is set to allEqual.
    5. Delete the Space by User Id
      1. Click the DELETE /cms/spaces/{userid} operation.
      2. At right, click Try it out.
      3. Enter the user ID: pod6user1
      4. Click Execute.
      5. Examine the response. You should note a Server response code of 200.
      6. To check some of the error handling, simply repeat this same DELETE /cms/spaces/{userid} operation by clicking Execute. Since the object was deleted, the ID you specify now is invalid, and you should get a fairly readable message in the return.

Cisco Meeting Server capabilities could be easily expanded. But now you are ready to take a look at Cisco Webex and notifications.