Requirements
 
Prerequisite knowledge
Basic knowledge of SOAP web services and WSDL documents.
 
User level
All
 
 
Required products
Adobe ColdFusion Enterprise Edition (2016 release) (Download trial)

Introduction
 
ColdFusion 2016 comes with a component called API Manager that lets you expose existing web services for controlled use. The SOAP protocol defines how web services are architected and designed.
 
This article provides an insight into how SOAP web services are imported and exposed from the ColdFusion API Manager.
 
If you are looking for an article on SOAP to REST translation, you can find it here. The SOAP to REST translation helps you to expose an existing SOAP service as a REST endpoint. SOAP Proxy,  on the other hand, exposes SOAP services, as-is, to your customers.
 
The article is divided into three sections:
1. The first section explains how a SOAP web service is channeled through the API Manager.
2. The second section is a tutorial.
3. The third section goes explains various security mechanisms that protect your SOAP APIs.
 
Deciphering SOAP services

 

Before we focus on how SOAP services are used in API Manager, let’s see what a SOAP web service comprises of. In this section, you will also see how the API Manager creates a publicly exposed proxy of your service.
 
WSDL Components
                      
Let’s look at some of the components you find in a WSDL. For example, we’ll use a publicly accessible WSDL, http://wsf.cdyne.com/WeatherWS/Weather.asmx?wsdl.
Types
A container for abstract type definitions defined using XML Schema.
 
Messages
A definition of an abstract message that may consist of multiple parts, with each part being of a different type. You will see more on this later.
 
Port Types
An abstract set of operations supported by one or more endpoints (commonly known as an interface); operations are defined by an exchange of messages. In the WSDL specified above, we have three port types - WeatherHTTPGet, WeatherHTTPPost,and WeatherSoap, ach with three operations - GetCityForecastByZIP, GetCityWeatherByZIP, and GetWeatherInformation.
 
● Binding
The WSDL binding element describes details of using a particular portType with a given protocol. The binding element contains several extensibility elements as well as a WSDL operation element for each operation in the portType. In the WSDL specified above, if you consider the Port Type, WeatherSoap, the soap:binding element indicates that this is a SOAP 1.1 binding. It also indicates the default style of service, document in this case, along with the required transport protocol, HTTP. The soap:operation element defines the SOAPAction HTTP header value for each operation. And the soap:body element defines how the message parts appear inside of the SOAP Body element, Literal, in this case.
 
● Service
The WSDL service element defines a collection of ports, or endpoints, that expose a particular binding. For instance, right at the bottom of the WSDL, if you look at the service definition for Port Type: WeatherSOAP, the endpoint is listed as http://wsf.cdyne.com/WeatherWS/Weather.asmx
 
The API Manager does not alter the structure of the above mentioned components, but identifies and rewrites external references in all these components. This is explained in the next section.
 
Understanding WSDL modifications
The API Manager needs to make certain changes to your WSDL document to ensure API invocations are not redirected to actual points. To do this, all external references in the WSDL – endpoints and XSD references are rewritten to point to API Manager servers.
 
In the SOAP web service we have considered, all references to cdyne.com endpoints have been replaced with references to the API Manager server. Here are the two WSDLs:
 
Actual WSDL:
<wsdl:service name="Weather"> <wsdl:port name="WeatherSoap" binding="tns:WeatherSoap"> <soap:address location="http://wsf.cdyne.com/WeatherWS/Weather.asmx"/> </wsdl:port> <wsdl:port name="WeatherSoap12" binding="tns:WeatherSoap12"> <soap12:address location="http://wsf.cdyne.com/WeatherWS/Weather.asmx"/> </wsdl:port> <wsdl:port name="WeatherHttpGet" binding="tns:WeatherHttpGet"> <http:address location="http://wsf.cdyne.com/WeatherWS/Weather.asmx"/> </wsdl:port> <wsdl:port name="WeatherHttpPost" binding="tns:WeatherHttpPost"> <http:address location="http://wsf.cdyne.com/WeatherWS/Weather.asmx"/> </wsdl:port> </wsdl:service>
 
API Manager exposed, Proxy WSDL:
 
<wsdl:service name="Weather"> <wsdl:port name="WeatherSoap" binding="tns:WeatherSoap"> <soap:address location="http://localhost:9100/WeatherWSDL/v1.0/SOAP11"/> </wsdl:port> <wsdl:port name="WeatherSoap12" binding="tns:WeatherSoap12"> <soap12:address location="http://localhost:9100/WeatherWSDL/v1.0/SOAP12"/> </wsdl:port> <wsdl:port name="WeatherHttpGet" binding="tns:WeatherHttpGet"> <http:address location="http://localhost:9100/WeatherWSDL/v1.0/HTTP"/> </wsdl:port> <wsdl:port name="WeatherHttpPost" binding="tns:WeatherHttpPost"> <http:address location="http://localhost:9100/WeatherWSDL/v1.0/HTTP"/> </wsdl:port> </wsdl:service>
 
These changes ensure that all requests to the API are channeled through API Manager. API Manager then authenticates users based on the credentials passed, provides access based on the SLA plans chosen, while also logging metrics for your SOAP services. 
 
Workflow Walkthrough
 
The sections below walk you through importing an existing SOAP service into the API Manager.
 
Setting up the environment
Install the API Manager along with ColdFusion (2016 release), and ensure that services are running. For example, let’s consider that the API Manger portal is running on http://localhost:9000/portal and the runtime (proxy) is running on http://localhost:9100/.
 
Importing the web service
Let’s use the publicly accessible SOAP web service already mentioned - http://wsf.cdyne.com/WeatherWS/Weather.asmx?wsdl - for trying out the workflow. Once the web service is verified to be accessible, you can login into API Manager at http://localhost:9000/portal. If no users are created as yet, you should be able to login with the default credentials, admin/admin. 
 
file
The Create API page displays.  We shall explore the option Import SOAP API’  for the rest of this section. When you choose this option, you see the Basic Settings page. On this page, you can see the following:
 
  • API Name – A name with which you can identity your API
  • Context – Denotes the URL context. The SOAP WSDL exposed by API Manager has this as an identifier in the URL.
  • WSDL URL – Location of your already existing web service. In our case, it is http://wsf.cdyne.com/WeatherWS/Weather.asmx?wsdl.  
 
After populating the fields, the page looks as follows:
 
file
 
When you click Fetch, the API Manager parses the WSDL to identify SOAP endpoints, port types, operations, and so on, and also rewrites all endpoints and XSD document references to point to API Manager runtime gateway.  You can see the screen once the WSDL is successfully interpreted.
 
file
 
The page lists all available Port Types, possible Message Envelopes, and Endpoints. For example, the screenshot above is limited to the Port Type, WeatherSOAP. The WSDL in reality exposes port types for HTTP GET and HTTP POST as well. It is important to ensure all these are in compliance with the web service originally provided.
 
Message envelopes are also generated automatically. Clicking on any of the buttons alongside the Envelope label, displays a dialogue showing the SOAP Action, Body Type and a sample Message. The API Manager generates the sample, and the sample needs to be validated for documentation of the original API.
 
Your subscribers can view this information. The information also serves as documentation for accessing the API Manager proxy endpoint.
The example below is a SOAP 1.2 message envelope for Port Type: WeatherSoap and Operation: GetCityWeatherByZIP. 
 
file

 

After you close the dialog box, you can make changes to other sections such as Authentication or SLA plans before clicking on Save.
 
What you will then see is a summary of the proxy SOAP service just created. The ‘Test this API’  section will provide options to try out the newly created SOAP proxy from within the API Manager. We will explore this in the next section.
 
Try Out in API Manager
The Test this API’ section is similar to the summary page shown while creating the API. On this page, you can see the two WSDL URLs., The first URL is the original WSDL URL and the second URL is the proxy URL generated by the API Manager. If the two WSDLs are compared, you can see that the actual endpoints (http://wsf.cdyne.com/WeatherWS/Weather.asmx) are replaced with the API Manager generated proxies (http://localhost:9100/WeatherWSDL/v1.0/{Binding}). This is also true for externally referenced XSD documents. Before publishing the API, you need to ensure all endpoints / XSD references start with the URL, http://localhost:9100/WeatherWSDL/v1.0/.
 
The message envelope sent to the proxy is forwarded as-is to the original service after verifying its authenticity, authorizations, etc.   
 
We will test the service, PortType: WeatherSoap and Operation: GetCityWeatherByZIP. Since the sample message generated has an invalid ZIP, the message is updated as shown below,
 
<s12:Envelope xmlns:s12='http://www.w3.org/2003/05/soap-envelope'> <s12:Body> <ns1:GetCityWeatherByZIP xmlns:ns1='http://ws.cdyne.com/WeatherWS/'> <ns1:ZIP>94133</ns1:ZIP> </ns1:GetCityWeatherByZIP> </s12:Body> </s12:Envelope>
 
Click Run API Call, and see the results as shown below! 
 
file
 
Publish the API after testing each operation.
 
Security Mechanisms
 
This section explains how your web services can be secured from API Manager, and what your customers can do to access these services.
 
In the previous section, we did not choose any authentication method. However, in your business environment, you would want to secure your web services as much as possible.
 
A client can access your web service from a server or from a mobile app. Both work well with different authentication schemes. 
 
Choose an authentication type from Security > Authentication. Ensure you click Apply to all Resources after you choose a method.
 
For Authentication Types other than 'None’, subscribe to the API before invoking. This is required because the credentials used to access the API are from an Application the API is tied to. To subscribe to an API, switch to a subscriber mode by choosing the option on the dropdown at the top-left corner.  Navigate to API Catalog, click the API you just created, and subscribe by selecting an Application and an SLA plan.
 
To learn how various authentication schemes work, and to understand how subscriptions via applications work, please read the articles on API Manager Security.
 
No Authentication
If Authentication Type is set to 'None’, invoking the API Manager-exposed proxy is similar to invoking any other SOAP web service. The sample ColdFusion client code is shown below:
 
<cfscript> wsobj=createObject("webservice","http://localhost:9000/amp/soapproxy/WeatherWSDL/v2.0?wsdl", {refreshwsdl=true,wsversion="2"}); result = wsobj.GetCityWeatherByZIP("94133"); writeOutput("It's " & result.getTemperature() & "F at " &result.getCity() & ", " & result.getState()); </cfscript>
 
Authentication via API Key
If the Authentication Type is set to 'API Key’, include an API Manager-generated API Key every request to an endpoint. Two API keys are provided, Production and Sandbox, and you can obtain them from the My Applications page in the subscriber view.
 
The API Key can be passed as a query parameter in the endpoint URL, or included in the headers. Here’s the sample code for the former. We create a new EndpointReference object with the API Key included.
  
<cfscript> wsobj = createObject("webservice", "http://localhost:9000/amp/soapproxy/WeatherWSDL/v1.0?wsdl", {refreshwsdl=true,wsversion="2"}); ep = createobject("java","org.apache.axis2.addressing.EndpointReference"); ep.init("http://localhost:9100/WeatherWSDL/v1.0/SOAP12?api_key=<INSERT API KEY>"); wsobj._getServiceClient().getOptions().setTo(ep); result = wsobj.GetCityWeatherByZIP(javaCast("String", "94133")); writeOutput("It's " & result.getTemperature() & "F at " &result.getCity() & ", " & result.getState()); </cfscript>
 
Basic Authentication
Basic authentication validates and authorizes a user based on a username, password, and ClientID that are sent alongwith the request. The API Manager validates the user-name / password combinations in User Store, and generates a Client ID. The Client ID is a system-generated key that you can get from the My Applications page in the subscriber view. 
 
The credentials – user name, password - are concatenated, base64-encoded, and passed in the Authorization HTTP header. The Client ID can be sent as a header / query / POST parameter.
The HTTP request headers that need to be passed for authentication are below,

Authorization: Basic Base64(username:password)
 
clientid: <Enter Client ID of the application used for subscribing>
 
Authentication via OAuth
OAuth is probably the most complex of the four authentication modes. In a typical OAuth request, you are redirected to a second portal (OAuth Server, for example, Okta) for authentication. On successful validation, the API Manager identifies if a user is already authenticated based on an Access Token. Access Tokens have an expiry, and are issued by the OAuth Server. API Manager also has an OAuth Server built into it.
 
In addition to the access token, the API Manager also passed a client ID to identify the application consuming this service.
 
The HTTP request headers that need to be passed for authentication are below:

Authorization: Bearer <OAuth2 Access Token>
 
clientid: <Enter Client ID of the application used for subscribing>
 
Where to go from here
 
We have looked at importing an existing SOAP web service, and exposing a proxy through API manager. We have also looked at how clients access these web services when protected with security mechanisms.  
 
For further reading, if you are looking for deeper understanding on API Manager Security, see here.
 
To explore how an existing SOAP web services can be exposed as a REST web service, see here.