The WSO2 API gateway is a proxy between consumer applications and backend APIs. The WSO2 API gateway also secures, protects, and manages APIs by intercepting API requests and applying policies such as throttling and security. You can implement a custom handler to change the API flow by meeting specific requirements and use cases.
When integrated with the Cequence Unified API Protection (UAP) platform, the WSO2 gateway uses a custom mediator in APIM to send all request and response data to Cequence API Edge server.
The custom mediator extends the AbstractHandler class and is triggered asynchronously to processes the request and response data. The custom mediator reformats the data into the JSON format that the Cequence UAP platform uses. The Cequence common library batches the JSON-formatted transactions and sends the batches to the Cequence API Edge server.
The Cequence Edge server then processes the transactions and provides insights into the API traffic.
High-level architecture
- Client sends a request to the WSO2 API manager.
- The Cequence plugin collects metadata for the API request.
- WSO2 sends the request to upstream applications.
- The upstream applications give a response to WSO2.
- The Cequence plugin collects metadata for the API response.
- WSO2 sends the response to the client.
- The Cequence plugin processes the API request, the response payload, and the metadata for both the request and the response. The Cequence plugin then reformats the data to the JSON format the Cequence UAP platform uses and sends the formatted JSON transaction to the Common Library. The Common Library batches the transactions and sends them to the Cequence UAP platform (API Edge server).
Prerequisites
Before you begin, confirm that your environment meets the following requirements.
- A working install of WSO2 APIM version 2.6.0.
- Java Version - 1.8 (java-8-openjdk-amd64).
- Cequence UAP platform release 6.14.13 or later.
- Access to a client ID and client secret generated from the Cequence UAP platform web UI.
- Token Authentication and API Edge endpoints as provided to you by a Cequence team member.
Enabling access to the WSO2 API Publisher and API Store
In a cloud environment, you must update the server URLs to use public IPv4 addresses. This involves editing the api-manager.xml and carbon.xml files. These files are located in the ${WSO2_APIM_HOME}/repository/conf directory.
In carbon.xml, remove the comment markers (<!-- and -->) and add a public IPv4 address.
<!--HostName>www.wso2.org</HostName-->
<HostName>54.252.243.53</HostName>
In api-manager.xml, update the APIStore and ServerURL tags, replacing localhost with a public IPv4 address.
<APIStore>
<!--GroupingExtractor>org.wso2.carbon.apimgt.impl.DefaultGroupIDExtractorImpl</GroupingExtractor-->
<!--This property is used to indicate how we do user name comparision for token generation https://wso2.org/jira/browse/APIMANAGER-2225-->
<CompareCaseInsensitively>true</CompareCaseInsensitively>
<DisplayURL>false</DisplayURL>
<URL>https://localhost:${mgt.transport.https.port}/store</URL>
<!-- Server URL of the API Store. -->
<ServerURL>https://localhost:${mgt.transport.https.port}${carbon.context}services/</ServerURL>
After making these changes, WSO2 has access to the API publisher and API store.
Create a sample API and app to test the installation
- Navigate to the WSO2 API Publisher URL, https://domain-name:9443/publisher.
- Log in to the WSO2 Publisher Console and select Create a New API.
The New API creation wizard appears. - In the Context Path field, type /postmanecho/v1.
- Click Next twice.
The wizard advances to the Implement step. - Add the endpoint details for the target or upstream API.
- In Advanced Throttling Policies, select Apply to API.
- Click Save and Publish.
The View in Portal link appears. - Navigate to the store portal.
- Select Add Application.
The Add Application dialog appears. - Navigate to the new API created earlier in this procedure.
- Subscribe to the new API.
- Generate the production keys, API key, secret, and token.
- Run the following command, replacing the placeholder values in italics with the values relevant to your environment.
curl -k --location 'https://IPv4_address:8243/postmanecho/v1/post' \
--header 'Authorization: Bearer token' \
--header 'Content-Type: application/json' \
--header 'Cookie: sails.sid=s%3AiOeSpUD4MKzcfXm4YJykWsabOZ-37Xsb.hYEFm2R0FJHxrh5aZGBrfoq9up%2B7JZMVE3%2FKiYEXFnA' \
--data '{
"a" : "samplebody"
}'
The sample API and app are ready.
Creating a client ID and client secret
Several Cequence components must authenticate to the Cequence UAP platform in order to transmit and receive data. Create authentication credentials in the Cequence UAP platform to enable this authentication.
- Log in to the UAP management portal UI.
The URL for the management portal is typically of the form https://ui.<your-tenant-name>.<domain>. Replace <your-tenant-name> with the name of your Cequence tenant organization. Replace <domain> with your domain name. - Select General Settings > User Management.
The User Management pane appears. - Click the Clients tab.
- Click Add New Client.
The new client dialog box appears. - Type the client name in the Client Name field.
This name is the client ID. Note the client ID for later use. - Enable the Traffic Management toggle.
- (Optional) To change the token lifespan from the default of 1800 seconds, type a whole number of seconds in Token Lifespan.
- Click Save.
A dialog box with the client secret appears. - Click the blue Copy icon to copy the secret to the clipboard, then click Close.
The client is now set up. Note the client name for future use.
The client list appears. - Note the value of the client secret for later use. This value will not be shown again later on the UI for security reasons.
Installing the WSO2 integration
Follow these steps to install the WSO2 integration.
- Download the compressed archive file that contains the integration.
- Extract the compressed archive file to the wso2am-3.1.0 directory.
- In a text editor, open the .env environment file.
- Edit the environment file to match the following template.
# Location of cequence.properties
Replace items in italics with values relevant to your use case. The value of the WSO2_APIM_HOME variable is the parent folder of the installation directory.
CEQ_COMMON_LIB_PROPERTIES_FILE=$WSO2_APIM_HOME/repository/conf/cequence.properties
# The Cequence Edge endpoint
CEQ_EDGE_ENDPOINT=https://edge.subdomain.se-cequence.cloud/api-transactions
# The Cequence Auth endpoint
CEQ_AUTH_ENDPOINT=https://auth.subdomain.se-cequence.cloud/auth/realms/cequence/protocol/openid-connect/token
# The Cequence client ID & secret for OAuth token authentication
CEQ_CLIENT_ID=id
CEQ_CLIENT_SECRET=secret
CEQ_COMMON_LIB_LOG_LEVEL=INFO - From the installation directory, run the following commands.
$ source .env
These commands load the values in the .env file and create a file named according to the value of the CEQ_COMMON_LIB_PROPERTIES_FILE variable. That file contains the endpoint URLs, client ID, client secret, and log level.
$ echo -e "authEndpointUrl=${CEQ_AUTH_ENDPOINT} \
transactionEndpointUrl=${CEQ_EDGE_ENDPOINT} \
clientId=${CEQ_CLIENT_ID} \
clientSecret=${CEQ_CLIENT_SECRET} \
commonLibLogLevel=${CEQ_COMMON_LIB_LOG_LEVEL}" \
>>${CEQ_COMMON_LIB_PROPERTIES_FILE} - From the installation directory, navigate to repository/resources/api_templates and open the velocity_template.xml file in a text editor.
- Add the following line immediately following the <handlers xmlns="http://ws.apache.org/ns/synapse"> line, then save and close the file.
<handler class="com.cequence.logging.LoggingApplication"/>
- Navigate to the repository/conf directory and open the log4j2.properties file in a text editor.
- At the end of the log4j2.properties file, add the following lines.
logger.cequence-log-msg-handler.name=com.cequence.logging.LoggingApplication
logger.cequence-log-msg-handler.level=DEBUG - Edit the loggers line to include cequence-log-msg-handler, then save and close the file.
- Run the following commands.
cp cequence_common_lib-1.2-Java8.jar ${WSO2_APIM_HOME}/repository/components/lib/These commands copy the Java JAR files that comprise the plugin to the correct installation directory.
cp cequence-logging-v2-1.0.0.jar ${WSO2_APIM_HOME}/repository/components/lib/
The WSO2 integration is now installed and ready to start.
Enable the Plugin on all Existing APIs
Run the script enable-cequence-plugin.sh from the scripts folder by setting the values of WSO2_APIM_HOME
ubuntu@ip-10-0-9-207:~/wso2_plugin_download$ ./scripts/enable-cequence-plugin.sh
Enable the Plugin on a Single Existing APIs
Run the script enable-cequence-plugin-per-api.sh from the scripts folder by setting the values of WSO2_APIM_HOME
ubuntu@ip-10-0-9-207:~/wso2_plugin_download$ ./scripts/enable-cequence-plugin-per-api.sh
Disable Plugin on Existing APIs
Run the script disable-cequence-plugin.sh from the scripts folder by setting the values of WSO2_APIM_HOME
ubuntu@ip-10-0-9-207:~/wso2_plugin_download$ ./scripts/disable-cequence-plugin.sh
Disable Plugin on a Single Existing APIs
Run the script disable-cequence-plugin-per-api.sh from the scripts folder by setting the values setting the values of WSO2_APIM_HOME
ubuntu@ip-10-0-9-207:~/wso2_plugin_download$ ./scripts/disable-cequence-plugin-per-api.sh
Testing the Integration
Run the following command to check the WSO2 logs.
tail -f ${WSO2_APIM_HOME}/repository/logs/wso2carbon.log
A functioning installation of WSO2 integrated with the Cequence UAP platform produces output similar to the following sample.
[2024-07-18 23:23:18,578] INFO - CequenceConnector txnSend Stats, avgTxnSize (this batch): 2505
avgTxnSize (so far):2457 Rx:6 Tx:6 [2024-07-18 23:23:18,579] INFO - CequenceConnector
checkRequest: cur-batch-size=2, avg-txn-latency= 0us, avg-batch-processing-latency= 12925us
You can also track transaction flow in the Sitemap Discovery section of the Cequence UAP platform web UI.
Once the transactions are showing up in the Cequence UAP Platform, change the logging level to WARN in the cequence.properties and log4j.properties files to prevent server log bloat.
In cequence.properties, add the following line.
commonLibLogLevel=WARN
In log4j.properties, add the following line.
log4j.logger.com.cequence.logging.LoggingApplication
Restart the WSO2 server.
Troubleshooting
The following actions can sometimes address lack of traffic to the Cequence UAP platform.
Confirm that the Cequence logging JAR file in WSO2 is being picked up properly.
Look for the common library cequence_common_lib-1.1-Java8.jar and cequence-logging-v2-1.0.0.jar in the following directories:
/home/ubuntu/wso2am-3.1.0/repository/components/lib
/home/ubuntu/wso2am-3.1.0/repository/components/dropins
Delete all cequence* JAR files from the /home/ubuntu/wso2am-3.1.0/repository/components/dropins directory and confirm that you have the right cequence* JAR files in the /home/ubuntu/wso2am-3.1.0/repository/components/lib directory, then restart WSO2.
Confirm that the log4j properties file, /home/ubuntu/wso2am-3.1.0/repository/conf/log4j2.properties, contains this line at the end:
log4j.logger.com.cequence.logging.LoggingApplication=INFO
Confirm that the handler file, /home/ubuntu/wso2am-3.1.0/repository/resources/api_templates/velocity_template.xml, contains the following line:
<handler class="com.cequence.logging.LoggingApplication"/>
Check the dropins folder, /home/ubuntu/wso2am-3.1.0/repository/components/dropins, and delete the file cequence_common_lib_1.1_1.0.0.jar if present.
Restart the server, invoke the API, and look for content like the following example in the contents of the wso2carbon.log file.
tail -f repository/logs/wso2carbon.log
[2024-07-09 09:43:38,352] INFO - CequenceConnector connector getInstance: Log levels: current: FINEST effective: FINEST
[2024-07-09 09:43:38,352] WARN - CequenceConnector cannot load properties from: /config.propertiesError: /config.properties (No such file or directory)
[2024-07-09 09:43:38,469] INFO - CequenceConnector applied new config: ConnectorConfig [srcGwName=null, libVersion=1.0, authTokenUrl=https://auth.pratik1.se-cequence.cloud/auth/realms/cequence/protocol/openid-connect/token, transactionEndpointUrl=https://edge.pratik1.se-cequence.cloud/api-transactions, maxMessageSize=10000000, batchSize=100, maxBatches=200, batchInterval=5000, serverCertValidationDisabled=true, transactionEndpointType=uap, authType=oauth2]
[2024-07-09 09:43:38,470] INFO - CequenceConnector Token expired. Initiating token fetch
[2024-07-09 09:43:38,471] INFO - CequenceConnector grant_type=client_credentials&scope=profile&client_secret=s6m9ZdTmdLQiRXgpPnq56NanFK02ZiyQ&client_id=wso2
[2024-07-09 09:43:39,562] INFO - CequenceConnector connector getInstance: Log levels: current: FINEST effective: FINEST
[2024-07-09 09:43:39,565] WARN - CequenceConnector cannot load properties from: /config.propertiesError: /config.properties (No such file or directory)
[2024-07-09 09:43:39,568] INFO - CequenceConnector applied new config: ConnectorConfig [srcGwName=null, libVersion=1.0, authTokenUrl=https://auth.pratik1.se-cequence.cloud/auth/realms/cequence/protocol/openid-connect/token, transactionEndpointUrl=https://edge.pratik1.se-cequence.cloud/api-transactions, maxMessageSize=10000000, batchSize=100, maxBatches=200, batchInterval=5000, serverCertValidationDisabled=true, transactionEndpointType=uap, authType=oauth2]
[2024-07-09 09:43:39,568] INFO - CequenceConnector grant_type=client_credentials&scope=profile&client_secret=s6m9ZdTmdLQiRXgpPnq56NanFK02ZiyQ&client_id=wso2
[2024-07-09 09:43:43,664] INFO - CequenceConnector txnSend Stats, avgTxnSize (this batch): 2574 avgTxnSize (so far):2574 Rx:2 Tx:2
[2024-07-09 09:43:43,666] INFO - CequenceConnector checkRequest: cur-batch-size=2, avg-txn-latency= 0us, avg-batch-processing-latency= 22802us
When the library is not being picked up properly, check the repository/dropins folder, delete all cequence* JAR files, check the lib folder and confirm that two Cequence JAR files are present, then restart WSO2.
To clear the following error, recompile the Cequence logging JAR file with JDK version 1.8 and place the JAR file in the /home/ubuntu/wso2am-3.1.0 directory.
[2024-07-09 11:05:04,901] INFO - DependencyTracker Sequence : _production_key_error_ was added to the Synapse configuration successfully
[2024-07-09 11:05:04,905] INFO - DependencyTracker Proxy service : WorkflowCallbackService was added to the Synapse configuration successfully
[2024-07-09 11:05:04,915] INFO - DependencyTracker API : _WSO2AMTokenAPI_ was added to the Synapse configuration successfully
[2024-07-09 11:05:04,921] FATAL - ServiceBusInitializer Failed to initialize ESB due to a fatal error
java.lang.UnsupportedClassVersionError: com/cequence/logging/LoggingApplication has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClassHoldingLock(ClasspathManager.java:638)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:613)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:574)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:492)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:465)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:395)
at org.eclipse.osgi.internal.loader.SingleSourcePackage.loadClass(SingleSourcePackage.java:35)
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:471)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
Confirm that the Cequence LoggingApplication handler is present in all XML files in the /home/ubuntu/wso2am-3.1.0/repository/deployment/server folder by running the following command.
grep -ir LoggingApplication
Confirm that the string is found in the XML file corresponding to every API.