Reading Time: 11 minutes

This is the final article in a mini-series on Runtime Fabric. In this blog, we will review the basic building blocks for the Runtime Fabric CI/CD deployment process, then provide an end-to-end example using Git, Jenkins, and Nexus.

Runtime Fabric deployment process

The Runtime Fabric deployment process has two steps. First the application jar needs to be deployed to Exchange. The second step is to deploy the jar from Exchange to Runtime Fabric.

latest report
Learn why we are the Leaders in API management and iPaaS

The CI/CD tool for Runtime Fabric deployment is the “mule-maven-plugin.”

Check this document to see the specifics of the plugin. The main element inside the plugin is <runtimeFabricDeployment> as documented here. A full maven POM  is provided in the example at the end of this document.

Once POM.xml is properly configured, it will be invoked twice:

  • “mvn clean deploy” to deploy the app to Exchange
  • “mvn clean deploy -DmuleDeploy” to deploy the app from Exchange to Runtime Fabric.

Maven relies on the POM GAV (groupId, artifactId, version) coordinate to locate the jar in Exchange. 

You can run the second command multiple times to deploy from Exchange to Runtime Fabric. However, the first command should be run only once with the same GAV. We’ll discuss in detail why that is the case in the next section.

The connection between Exchange and Runtime Fabric

With Cloudhub and an on-prem Mule server, applications are deployed to Mule runtime directly. Runtime Fabric deployment requires a two-step process that involves Anypoint Exchange.

Runtime Fabric runs on top of the Kubernetes container platform. The Mule Runtime and the Mule applications run inside the pods of the containers. When these pods crash for whatever reason, the restart process needs to reinstate these pods with the pre-existing Mule runtime and the applications. The container may have a temp cache that stores some of these jars so the pods can be reinstated quickly. But that’s not guaranteed. Therefore a persistent store is needed to guarantee Mule applications can be re-deployed when an error occurs in the container or the pods. That’s how Exchange became the persistent store for these jars.

Requiring application jars to be deployed to Exchange does have a subtle effect on the traditional role of artifact repositories in the CI/CD process. We’ll explore the main behavior differences of Exchange from a regular artifact repository next.

Due to specific rules of Exchange, you can deploy an app to Exchange only once with the same Maven coordinate (GAV). If you deploy an app again with the same GAV, you will get an error that the application already exists in Exchange. There is no option to overwrite it.

What if you want to re-deploy the application with the same GAV? In Exchange there is a special rule, you may physically delete an artifact from Exchange within seven days after the initial upload.  

As discussed in the beginning section, Runtime Fabric wants to keep the jar in Exchange in case it needs to reinstate a “pod” inside the container. Technically, you should not delete the jars after it is deployed to Runtime Fabric runtime. These jars are intended to be hidden inside Exchange. However, there are three ways to access these assets if you have to do so in Exchange:

Method 1: Directly accessing the jar with URL

Using this URL pattern https://anypoint.mulesoft.com/exchange/{your-org-id}/{artifactId}

For example, assume you have <artifactId>hello-world-rtf</artifactId> in your POM file, your org-ID is “23a3axxx-5…d419xxx”, then you can view your asset jar as https://anypoint.mulesoft.com/exchange/23a3axxx-5…d419xxx/hello-world-rtf

Method 2: Search for the asset in Exchange

First you need to switch to “old search” in Exchange (see picture below), then enter this URL https://anypoint.mulesoft.com/exchange/?type=app, all of your app jars should be displayed. Keep in mind, this does not work with the “new search” in Exchange.

Method 3: Searching from Runtime Manager

The third way to look for the app jar in the Exchange is to search from Runtime Manager. First, find the Runtime Fabric app from Runtime Manager (you can use any Runtime Fabric app), next to the “Application File” field, select “Import file from Exchange.” Enter your search (for example, “hello”) and follow the link to see the asset in Exchange.

Basic CI/CD Example with Jenkins, Git, and Nexus

This is a simple but full Runtime Fabric CI/CD example. It illustrates the basic plumbing to deploy a Runtime Fabric project using Jenkins, Git and Nexus. 

To use this POM, make sure you have the following defined in the .m2/settings.xml. Pay attention to “Exchange2.” Although you can customize the name, you need to make sure it is named exactly the same in settings.xml and in your pom.xml file.

<server>
      <id>Exchange2</id>
      <username>xxx</username>
      <password>xxx</password>
    </server>

Full POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>23a3axxx-...419xxx</groupId>
   <artifactId>hello-world-rtf</artifactId>
   <version>1.0.1-SNAPSHOT</version>
   <packaging>mule-application</packaging>
   <!-- <name> normally is the same as artifactId, 
      It’s intentionally made different in this example-->
   <name>hello-rtf</name>
   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <app.runtime>4.3.0</app.runtime>
      <mule.maven.plugin.version>3.3.5</mule.maven.plugin.version>
      <maven.deploy.plugin.version>2.8.1</maven.deploy.plugin.version>
      <provider>MC</provider>
      <target>my-fabric</target>
      <mule.env>dev</mule.env>
   </properties>
   <build>
      <plugins>
         <plugin>
            <groupId>org.mule.tools.maven</groupId>
            <artifactId>mule-maven-plugin</artifactId>
            <version>${mule.maven.plugin.version}</version>
            <extensions>true</extensions>
            <configuration>
               <runtimeFabricDeployment>
                  <uri>https://anypoint.mulesoft.com</uri>
                  <muleVersion>${app.runtime}</muleVersion>
                  <server>Exchange2</server>
                  <!-- user <server> above or add your user/pass below
                        <username>xxx </username>
                        <password>xxx</password>
                  -->
                  <applicationName>${project.artifactId}-${mule.env}</applicationName>
                  <environment>${mule.env}</environment>
                  <provider>${provider}</provider>
                  <target>${target}</target>
                  <properties>
                     <!--anypoint.platform.client_id>xxx</anypoint.platform.client_id-->
                     <!--anypoint.platform.client_secret>xxx</anypoint.platform.client_secret-->
                     <anypoint.platform.analytics_base_uri>https://analytics-ingest.anypoint.mulesoft.com</anypoint.platform.analytics_base_uri>
                     <anypoint.platform.base_uri>https://anypoint.mulesoft.com/</anypoint.platform.base_uri>
                     <mule.env>${mule.env}</mule.env>
                  </properties>
                  <deploymentSettings>
                     <cpuReserved>100m</cpuReserved>
                     <cpuMax>1000m</cpuMax>
                     <memoryReserved>800Mi</memoryReserved>
                     <memoryMax>999Mi</memoryMax>
                     <replicationFactor>1</replicationFactor>
                  </deploymentSettings>
               </runtimeFabricDeployment>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <dependencies>
      <dependency>
         <groupId>org.mule.connectors</groupId>
         <artifactId>mule-http-connector</artifactId>
         <version>1.5.22</version>
         <classifier>mule-plugin</classifier>
      </dependency>
      <dependency>
         <groupId>org.mule.connectors</groupId>
         <artifactId>mule-sockets-connector</artifactId>
         <version>1.2.0</version>
         <classifier>mule-plugin</classifier>
      </dependency>
   </dependencies>
   <repositories>
      <repository>
         <id>anypoint-exchange-v2</id>
         <name>Anypoint Exchange</name>
         <url>https://maven.anypoint.mulesoft.com/api/v2/maven</url>
         <layout>default</layout>
      </repository>
      <repository>
         <id>mulesoft-releases</id>
         <name>MuleSoft Releases Repository</name>
         <url>https://repository.mulesoft.org/releases/</url>
         <layout>default</layout>
      </repository>
   </repositories>
   <pluginRepositories>
      <pluginRepository>
         <id>mulesoft-releases</id>
         <name>mulesoft release repository</name>
         <layout>default</layout>
         <url>https://repository.mulesoft.org/releases/</url>
         <snapshots>
            <enabled>false</enabled>
         </snapshots>
      </pluginRepository>
   </pluginRepositories>
   <profiles>
      <profile>
         <id>nexus</id>
         <distributionManagement>
            <repository>
               <id>nexus-repo</id>
               <url>http://localhost:8081/repository/maven-releases/</url>
            </repository>
            <snapshotRepository>
               <id>nexus-repo</id>
               <url>http://localhost:8081/repository/maven-snapshots/</url>
            </snapshotRepository>
         </distributionManagement>
      </profile>
   </profiles>
   <distributionManagement>
      <repository>
         <id>Exchange2</id>
         <name>Corporate Repository</name>
         <url>https://maven.anypoint.mulesoft.com/api/v1/organizations/${project.groupId}/maven</url>
         <layout>default</layout>
      </repository>
   </distributionManagement>
</project>

Basic Jenkins pipeline:

pipeline {
  agent any
  stages {
    stage('deploy-to-nexus') {
      steps {
        git 'https://github.com/gituser123/hello-world.git'
        // use profile nexus (-P nexus) to deploy to Nexus.
        sh "mvn clean deploy -P nexus"
      }
    }
    stage('deploy-to-exchange') {
      steps {
        // deploys the same binary zip file exchange
        // mvn clean deploy works fine, 
        // it will rebuilt an equivalent binary zip file
        sh "mvn deploy"
      }
    }
    stage('deploy-to-rtf') {
      steps {
        // deploy from Exchange to RTF runtime.
        sh "mvn deploy -DmuleDeploy -Denvironment=dev"
      }
      post {
        success {
          sh 'echo all done!'
        }
      }
    }
  }
}

Conclusion

This blog provides the basic Jenkins pipeline and POM elements that can be expanded and used in an enterprise CI/CD framework.

Get started with Runtime Fabric by signing up for your free trial of Anypoint Platform.

Series Navigation<< How to install Runtime Fabric on-premises