Publishing Service APIs with MuleSoft

Publishing Service APIs with MuleSoft

1580 517 Will

It’s now imperative for organisations to seize the opportunities of participating in the API economy as the success stories of tech giants like Google, Amazon and Facebook highlight the importance of public APIs to drive their business. At the very least, strategies to open up APIs internally will break down information silos and unlock data. However, by making APIs become publicly readily available, companies can externalise innovation and turn every third-party developer into a product augmenter. 

The evolution of cloud and IoT only increases the value of APIs as every customer touch point will find itself interacting with APIs and elasticity supporting the scaling of those cloud applications. MuleSoft provides an all-in-one platform to handle the entire life-cycle of APIs, from design to maintenance. MuleSoft’s Anypoint Studio allow us to build APIs simply via a graphical interface and one-click access to an extensive library of pre-built connectors and templates. 

TM Forum is a global industry association providing best-practice guidelines and industry research to its enterprise members, of which the majority operate in the telecommunications sector, however also extend to digital service providers and software suppliers. One of TM Forum’s featured programs is its Open API initiative, contributing a suite of over 50 REST APIs that provide a standardised structure for CSPs to manage services and integration between internal systems as well as externally to partners and customers. 

In this guide, we will be looking at using TM Forum’s Open API standard for Activation and Configuration, forming the framework of service creation, specifically an NSX® Edge Services Gateway. For more information on VMware NSX® for vSphere® and the SDDC architecture, click here.

Prerequisites
  • A machine running Windows, OSx or Linux
  • Installed version of Postman. A REST client, Postman will act as the role of the API consumer.
  • A VMware vSphere® environment including required credentials for the NSX® Manager. The NSX® Manager requires port 443/TCP for REST API requests.
Installing and Configuring Java

If you’re up and away with Java 8 skip this step, otherwise here are some basic steps to installing and configuring Java in Windows.

Click here and download the appropriate Java SE 8 for your operating system. 

You will need to edit the path in your system variables to accommodate Java.

  1. Go to Control Panel
  2. Click Advanced System Settings
  3. Click Environment Variables
  4. In the section System Variables, find the PATH environment variable and click Edit.
  5. In the Edit System Variable window; specify the value of the Java PATH (where the JDK sotware is located, for example, C:\Program Files\Java\jdk.1.8.0_201)
Installing Anypoint Studio

Anypoint Studio can be downloaded from https://www.mulesoft.com/lp/dl/studio on a 30-day free trial. 

Note: Following installation of Anypoint Studio 7.x, I noticed there was an issue when importing the RAML specification that goes on to auto-create a Mule flow (detailed in Step 4 below). I have submitted a bug report with MuelSoft Support, however for the time being I will be using an older version of Anypoint Studio (6.5) for this demonstration. 

The Anypoint Studio application appears when the unzip operation completes.  It may be even that you have set your path but Anypoint Studio will still prompt you to install the JDK (shown below).

If this is the case, you can directly point AS to Java for updating AnypointStudio.ini file, located in the same directory as the application. You do this by adding a “-vm” tag and including the path as per your system.

An example is shown below:

Converting TM Forum Swagger 2.0 to RAML

A caveat of working with the TM Forum specification is that RESTful API Modelling Language (RAML) is not supported. As MuleSoft works with RAML or OAS when it comes to API design, we need to convert the TMF640 standard from Swagger 2.0 to RAML.

You can find the Swagger 2.0 source code on TM Forum’s Github repo here.

In terms of converting methods, there are two online converters we could opt to use:

  1. APIMATIC’s online conversion tool (https://www.apimatic.io/transformer) – however you must signup with a valid email to use this 
  2. MuleSoft’s own OAS RAML Converter (https://mulesoft.github.io/oas-raml-converter/)
Create a Project and Import the RAML Specification

We will want to create a new project and import the RAML specification we have just converted. 

  • Go to File > New > Mule Project to create a project, and set the field values in the project wizard:
    1. Enter a Project Name
    2. Under APIkit Settings, select the path of your RAML file
    3. Click Finish

The APIkit provided by Anypoint Studio allows us to create Mule flows from RAML definitions. This should be apparent when Anypoint Studio loads the definition file, you will notice that a message flow has been produced reflective of the methods and resources depicted in the imported schema.  

Anypoint Studio offers a multitude of pre-built connectors that allow connection to almost any endpoint, including those with widely-used third party apps such as Salesforce and SAP. For the purpose of this demonstration, our focus will be limited to HTTP Connectors. The HTTP Connector has a Listener operation that receives requests over HTTP or HTTPS protocol. Receiving a request, and other incidents, initiates a Mule event. This may be one of the first things you will notice when the message flow that has been created. It is best to think of the HTTP Listener as the functionality provider; we will be exposing an API that a consumer (in our case, Postman) will call. However, our message flow just provides a front-end, we are not calling any services and therefore we have to introduce the concept of an HTTP Requester that will facilitate the outbound request to vSphere® to create our NSX® Edge Gateway. In essence, we are both an API provider and client here. A request will be received in the form of a consumer posting data in way of our TM Forum schema (in JSON format), triggering a Mule flow to translate the incoming data in a format that the outbound request to our external HTTPS URL requires. 

Under the General tab of the HTTP Listener, we will define the host and port where the server will be set up, as well as the protocol to use: HTTP for plain connections or HTTPS for TLS connections. We will implement the former. 

Obtaining and translating the NSX® API XML

The NSX® REST API library is defined by a collection of XML documents. The elements defined in these schemas, along with their attributes and composition rules, represent the data structures of NSX® objects. The target of our requests will be the URL of the NSX® Manager communicating over port 443/TCP. 

Using the latest version (at date of publishing) of the NSX® API Guide here, from page 256 we can find instructions on how to deploy an Edge Services Gateway (ESG). Stored in Open Virtual Machine (OFV) format, once requested the API copies the NSX® Edge OVF from the Edge Manager to the specified datastore and deploys an NSX® Edge on the given datacentre.

If we consider the all of the configurable parameters to deploy the virtual appliance, we can make use of the XML request body detailed on page 257 of the above guide. 

However, for this demonstration, we’re only interested in deploying an appliance of minimal/baseline configuration. Therefore, we can trim down the request body to the following as input for our straightforward deployment. 

<edge>
  <name>NSX-Edge-45</name>
  <datacenterMoid>datacenter-1</datacenterMoid>
  <type>gatewayServices</type>
  <appliances>
    <applianceSize>compact</applianceSize>
    <appliance>
      <resourcePoolId>domain-1</resourcePoolId>
      <datastoreId>datastore-1</datastoreId>
    </appliance>
  </appliances>
  <vnics>
    <vnic>
      <index>0</index>
      <portgroupId>dvportgroup-10</portgroupId>
      <addressGroups>
        <addressGroup>
          <primaryAddress>10.10.10.100</primaryAddress>
          <subnetMask>255.255.255.0</subnetMask>
        </addressGroup>
      </addressGroups>
      <isConnected>true</isConnected>
      <macAddress>
        <edgeVmHaIndex>0</edgeVmHaIndex>
      </macAddress>
    </vnic>
  </vnics>
  <cliSettings>
    <userName>admin</userName>
    <password>password</password>
    <remoteAccess>false</remoteAccess>
  </cliSettings>
</edge>
Adding a Reference Flow to trigger the NSX® API

As aforementioned, we will be calling an external NSX® API targeted at a designated NSX® Manager that will pass the data captured by the HTTP Listener, as defined by our TM Forum RAML schema. Therefore, we must identify which combination of method and resource is mot suitable for our use case. Scrolling through, it makes most sense to invoke the Service POST block as our request REST API and therefore we will embed a Flow Reference here. For the moment, we simply need to capture a display name, of which we will reference in the request flow we will create. 

Creating a Request Flow for NSX® API

Now that we have created a “fork” in our flow, the listening request is able to be relayed to a secondary flow that will comprise the external request to the NSX® Manager in order to create the ESG.

  1. From the Mule Palette tab on the right-hand side, search for the Transform Message element
  2. Drag and drop the element onto the Message Flow graphical view
  3. This will automatically create a parent flow too, of which we will have to name, matching that of the Flow Reference we created in the previous step 
Transforming Input Data

The Transform Message component carries out transformations over the input data it receives. This element makes use of DataWeave, MuleSoft’s expression language for accessing and transforming data. We have the choice of either using the UI to build transformations implicitly via drag and drop or explicitly writing it out in DataWeave language. 

  1. Click the Transform Message element
  2. You will notice that our Input Payload is defined as per the TM Forum RAML specification, however we need to define our Output metadata to be mapped. Click Define metadata.
  3. Select Add
  4. Enter a new Type id and select Create type
  5. Change Type to Xml
  6. Change definition from Schema to Example
  7. Browse for the NSX® ESG POST XML document
  8. Click Select

Once the metadata has been auto-populated, we will map the relevant data fields. It is really your prerogative, deciding which fields from the TM Forum specification align most appropriately with the external API. We have designated the serviceCharacteristic subset as appropriate fields for mapping. For the sake of simplicity, of the condensed NSX® request body (including all required fields), we will only map three fields for the consumer (Postman) to populate – the other required fields we will hard-code. This is somewhat reflective of an actual service provisioning request in that you may opt to restrict the selection of some fields on the customer’s behalf. 

The final DataWeave output will look like the following:

%dw 1.0
%output application/xml
---
{
  "edge": {
    "datacenterMoid": "datacenter-1",
    "name": payload.serviceCharacteristic[2].value,
    "type": "gatewayServices",
    "appliances": {
      "applianceSize": payload.serviceCharacteristic[0].value,
      "appliance": {
        "resourcePoolId": "domain-1",
        "datastoreId": "datastore-1"
      }
    },
    "vnics": {
      "vnic": {
        "index": "0",
        "portgroupId": "dvportgroup-10",
        "addressGroups": {
          "addressGroup": {
            "primaryAddress": payload.serviceCharacteristic[1].value,
            "subnetMask": "255.255.255.0"
          }
        },
        "macAddress": { "edgeVmHaIndex": "0" },
        "isConnected": "true"
      }
    },
    "cliSettings": {
      "userName": "admin",
      "password": "password",
      "remoteAccess": "false"
    }
  }
}
Configuring the HTTP Requester

The HTTP Requester will facilitate the external call to the NSX® Manager. This will accept a POST method in our instance, sending the message payload defined in the previous step as the body of our request. The required minimum setting for the request operation is a host URI, which can include a path. However, we will be adding a few additional configurations such as authentication, headers, TLS/SSL and timeout limits.  

  1. Adjoin a HTTP Connector as the subsequent step in the Mule flow

2. On the General tab of the HTTP Connector, update the Display Name as appropriate
3. Update the Method to POST and the URI path (the extension of the base path). NOte: We will set the base path to ‘/api’ in the next steps, however the full path could easily be set here too. 
4. Add the two headers Content-Type and Authorization in the Parameters section. Authorization requires Base64 encoding.

5. Select the Edit icon of the Connector Configuration field
6. Update the URL Configuration parameters (Protocol and Port must be set to HTTPS and 443, respectively) and increase the Idle and Response Timeout values to 120000

7.  Next we will be disabling any TLS Validations. You may have more stringent requirements in your environment. 

8. Using Basic Authentication, enter the login credentials of the NSX Manager

9. For good measure, we will include a Logger in our Mule flow (set at the default log level of INFO). This will aid in any troubleshooting by signalling any error messaging or status notifications. 
10. Additionally, we will add a Set Payload transformer in order to return the JSON response payload. 

Running the Mule project and executing the POST API call via Postman

We can run the project by right-clicking anywhere in the Message Flow area. As the project is compiling, the Console tab will show the Mule Runtime logs. Wait until the console shows the application has completed deployment.

Now we’re ready to call our API via Postman. You’ll notice below that in our JSON Request body, we’ve included a few additional fields to ‘pad it out’, but effectively we are only concerned with the values and arrangement of those in the serviceCharacteristic list (as they are the ones being mapped). Recall that we referenced the index of our values during the DataWeave transformation, so it’s important that we organise our list items accordingly. Enter the URL we set in our HTTP Listener configuration and hit Send!

You can see below that our call returned a 201 response, denoting our service has been provisioned.

When we log in our vSphere® environment, we notice that sure enough, an NSX® Edge VM has been spun up. For some reason however, the NSX® API appends a ‘0’ to the virtual device’s name. I have tried searching for the root cause however to no avail, so if someone is in the know, let us know in the comments below!

Conclusion

And there we have it, we’ve successfully created an end-to-end API that makes use of a best practice industry standard set by TM Forum that transposes to an external API call to VMware’s NSX®. 

Obviously, this is a very simple configuration we have implemented in MuleSoft. Improvements in the way of error handling would certainly need to be put in place in a production environment as error codes form the first and most important step towards not only notifying the user of a failure, but jump-starting the error resolution process.