Custom Policy Creation in Mule 4: Part 1
In this series, I will cover Custom policy creation in Mule 4.
In Part 1, we will create a bare minimum custom policy for Mule 4. The post will help you get used to the creation of custom policy and upload it to Anypoint Exchange. In future posts, I will elaborate mostly on policy implementation logic using some use cases.
Overview
Custom policies are policies that anyone can develop and apply to their APIs, with the intention of extending existing functionality or defining new ones.
The current workflow to get a working policy for Mule 4 that can be applied to the Anypoint Platform consists of:
- Developing the policy
- Packaging the policy
- Uploading the resulting policy assets to Exchange
- Applying the policy to any API through API Manager
From Mule 4, a custom policy is treated as an asset of your Anypoint organization. You can view/download a custom policy as an asset package. Using Maven facade API, we can publish a policy to the exchange.
Setup
Configuring settings.xml for Maven
Anypoint Exchange provides an API to publish or consume assets using a Maven client. You must have a unique artifact name and organization ID to publish your asset. See the Maven facade API Exchange asset for more details.
Configure the server with your Anypoint Exchange Username and Password.
You can also use the token instead. To obtain the token, open this URL in the browser after logging into Anypoint platform: https://anypoint.mulesoft.com/accounts/api/profile
Search for access_token entry and use that value instead of Password, For the username, use the literal "~~~Token~~~"
Below is the example of the settings.xml configuration.
The server id provided will need to be used in pom.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>Repository</id>
<username>AnypointUsername</username>
<password>AnypointPassword</password>
<!--<username>~~~Token~~~</username>
<password>Paste your token here</password>-->
</server>
</servers>
</settings>
Policy Development
Creating a policy requires creating several files like <policy>.yaml and template.xml, etc. We also need to have a proper structure for the policy project.
The easiest way to create the proper structure along with the files is by using the maven archetype provided by Mulesoft.
Include the following section in your settings.xml to make the archetype available:
<profiles>
<profile>
<id>archetype-repository</id>
<repositories>
<repository>
<id>archetype</id>
<name>Mule Repository</name>
<url>https://repository-master.mulesoft.org/nexus/content/repositories/public</url>
<releases>
<enabled>true</enabled>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
To generate the skeleton using the archetype, use the following command:
mvn -Parchetype-repository archetype:generate -DarchetypeGroupId=org.mule.tools -DarchetypeArtifactId=api-gateway-custom-policy-archetype -DarchetypeVersion=1.1.0 -DgroupId=${orgId} -DartifactId=${policyName} -Dversion=1.0.0 -Dpackage=mule-policy
Replace:
${orgId} with Anypoint Platform Organization Id — Can be obtained from Access Management > Organization >> Organization ID value from the page
${policyName} — Name of the custom policy. Lets say we named it policy1 for this example
After running the command, a project will be created with pom, mule-atrifact.json, template.xml, and policy1.yaml.
pom.xml Modification
POM Will contain the configurations as provided in the maven archetype. The generated POM will have maven-deploy-plugin, which will be required to upload the policy. It will also have distributionManagement, which is defined as pointing to the user’s Exchange — this is used to publish the asset (policy) using Maven. There are few changes that we need to do in our pom.xml to be aligned with setting.xml.
The <id> value in settings.xml servers/server/id should match the Repository used in your POM.
For our example, we have set the id in settings.xml as "Repository," so we need to set the repositories/repository/id and distributionManagement/repository/id with the same value i.e. "Repository."
This will enable the Exchange Maven Facade API to download/upload files.
Also, for our maven-deploy-plugin, we will need to update the executions/execution/configuration/repositoryId value with "Repository."
This is what the modified pom.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Your Org ID</groupId>
<artifactId>policy3</artifactId>
<version>1.0.0</version>
<name>policy3</name>
<description>Policy 3</description>
<packaging>mule-policy</packaging>
<properties>
<mule.maven.plugin.version>3.2.7</mule.maven.plugin.version>
<exchange.url>https://maven.anypoint.mulesoft.com/api/v1/organizations/YourOrgIdWillbeHere/maven</exchange.url>
</properties>
<repositories>
<repository>
<id>Repository</id>
<name>MuleSoft Exchange Environment</name>
<url>${exchange.url}</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>${mule.maven.plugin.version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<execution>
<id>upload-template</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<repositoryId>Repository</repositoryId>
<url>${exchange.url}</url>
<file>${project.basedir}/${project.artifactId}.yaml</file>
<generatePom>false</generatePom>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<packaging>yaml</packaging>
<classifier>policy-definition</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>Repository</id>
<name>Repository</name>
<url>${exchange.url}</url>
<layout>default</layout>
</repository>
</distributionManagement>
<pluginRepositories>
<pluginRepository>
<id>mule-plugin</id>
<name>Mule Repository</name>
<url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
</pluginRepository>
</pluginRepositories>
</project>
Note that the Id ("Repository") for the Mule Exchange repository is consistent across settings.xml and pom.xml.
Modification of Policy YAML
For this post, we will use the default implementation that was generated using the archetype. In the next posts of this series, we will explore more on this.
Modification of template.xml
For this post, we will use the default implementation that was generated using the archetype. This policy will set payload "Hello World!"
In the next posts of this series, we will explore the policy implementation with various use cases.
Package the Policy
mule-maven-plugin will be used to package the policy. Generating the policy project with the Maven archetype will, by default, include this as a plugin.
Use command mvn clean install to package the policy.
This will create a JAR file into the target directory within your project’s folder. It will also verify that all the necessary files were provided for the packaging and that the information provided in the mule-artifact and in the policy YAML is valid.
Upload the Policy Assets to Exchange
Creating your custom policy project using the provided Maven archetypes, all the necessary plugins for uploading the policy to Exchange are already defined for you.
We need to make sure that your exchange URL is properly defined in POM. Note that for EU, we have a different convention. In general, we will have the below format:
<properties>
<exchange.url>https://maven.anypoint.mulesoft.com/api/v1/organizations/{OrgId}/maven</exchange.url>
</properties>
Next, we need to verify that the Server ID in settings.xml and repository ID's for Exchange used in POM are aligned. We have already taken care of this above.
Use command mvn deploy to publish the policy to Exchange.
The custom policy is now available for you to apply to APIs that belong to the specified organization. You can also view them in Exchange.
Apply the Policy to any API Through API Manager
Go to the API in API manager for which you want to add this policy.
Select your custom policy from the list. (Note that it will have a label of custom over it), Configure your policy and apply it.
Now you can test your API.
On using the default implementation of the custom policy, we will get a "Hello World!" response.
Next...
Next in this series, we will implement use cases where we can use a custom policy. Stay tuned!