Releasing MuleSoft API – DZone – Uplaza

MuleSoft Anypoint is an enterprise platform of an API event-driven structure that enables builders to create design and construct an API, and to call a couple of capabilities the place you may share API templates and software property. It additionally has a central net interface to handle, combine, safe, and monitor API efficiency.

Open API Specification

MuleSoft API improvement helps Open API specification.

The Open API Specification (OAS) is a normal observe of programming language and agonistic interface for HTTP APIs and gives service content material discovery capabilities with out precise entry to code ,documentation, community site visitors inspection.

For this tutorial, we cannot be overlaying the creation of the open API specification, however simply to notice: an Open API spec file must be created and outlined contained in the folder content material. 

MuleSoft Versioning

MuleSoft makes use of 3 digits semantic versioning scheme which denotes the key, minor, and patch launch.

The Main model is for while you make incompatible or breaking API modifications. The Minor model is for while you add performance in a backward-compatible method. The Patch model is while you make modifications like documentation replace with out altering the spec. 

The API model is totally different from the above versioning scheme and is specified within the OAS definition. An API comprises every asset model signifying main/minor updates. Model v1 can comprise quite a few asset variations; for instance, 1.0.0, 1.0.1, 1.0.2, and so forth., and model v2 can comprise asset variations, example2.0.0, 2.0.1, 2.0.2, and so forth.

Asset Lifecycle States

For the Asset Growth Lifecycle, we shall be utilizing the MuleSoft lifecycle states beneath.

Growth State

That is an iterative technique of design and improvement.

  • Pattern asset in improvement state config file:
{
	"assetId": "hello-worldsample-v1",
    "status": "development",
	"version": "1.0.1",
	"classifier": "oas"
}

Steady State

The asset is prepared for consumption and in MuleSoft that is denoted by setting the standing to "published" which truly means steady.

  • Pattern asset within the steady state config file:
{
	"assetId": "hello-worldsample-v1",
    "status": "published",
	"version": "1.0.1",
	"classifier": "oas"
}

Deprecated State

Deprecated flags the API and can be utilized to earmark the API for deletion. We cannot be utilizing this state on this tutorial.

  • Asset Id: Id of an asset (API) printed to the Alternate (API Catalog)
  • Asset model: Model of the asset (API) printed to the Alternate (API catalog)
  • Classifier: The kind of API specification; on this case, it’s OAS (Open API specification)

Automated launch tags allotted in line with asset state:

ASSET STATE FOLDER CUSTOM RELEASE VERSIONING LOGIC SAMPLE RELEASE TAG

Growth

international config file

develop-mulesoftAPIVersion.timestamp

develop-1.0.1.166720192

Steady

international config file

stable-mulesoftAPIVersion.timestamp

stable-1.0.1.166720192

Customized Launch Tagging Scheme

On this tutorial, we now have devised a customized tagging scheme that we will make the most of throughout our launch section to tag the codebase with this practice tag. This helps us to trace the actual MuleSoft launch improvement all the best way to the deployment of an API to a selected surroundings because it will get promoted to the manufacturing surroundings. 

Ideally, you do not have to observe the identical logic for tagging. You’ll be able to devise your personal customized primarily based on the Asset and environment-related deployments in MuleSoft. 

Since we shall be configuring a customized tag primarily based on a selected surroundings deployment, the MuleSoft model shall be used contained in the tag indicated beneath with mulesoftAssetVersion with the offered pattern as 1.0.1.

  • Automated launch tags in line with surroundings deployment:
ENVIRONMENT FOLDER CUSTOM RELEASE VERSIONING LOGIC SAMPLE RELEASE TAG

Growth

dev

dev-deploy-mulesoftAssetVersion.timestamp

dev-deploy-1.0.1.166720192

High quality Assurance

qa

qa-deploy-mulesoftAssetVersion.timestamp

qa-deploy-1.0.1.166720192

Manufacturing

prod

prod-deploy-mulesoftAssetVersion.timestamp

prod-deploy-1.0.1.166720192

For this tutorial, we now have arrange the beneath automated customized launch versioning and tagging scheme.

The code improvement is predicated on Trunk primarily based improvement with a single stream of improvement. The sequence of modifications as indicated within the beneath diagram begins when a developer cuts a characteristic department for his or her improvement functions. They’ve the flexibleness to amend the modifications within the international config (sits outdoors the surroundings folders) or the OAS file for improvement and publishing for the actual asset to the MuleSoft Alternate. On the finish of the event, they will set the Asset state to printed or improvement and create a pull request to merge onto the grasp department. 

As soon as the asset is accessible on an change, the developer can configure the environment-related asset config recordsdata or API coverage recordsdata that are environment-specific and allow the developer to devour any of the printed asset variations within the environment-specific asset config for API deployment functions solely. For instance, the Dev surroundings can deploy 1.0.3 of an asset, whereas the QA surroundings can use 1.0.2 and the prod can deploy 1.0.1. API insurance policies may be utilized in a similar way whereas Dev and QA use a unique set of API insurance policies and Prod can use a unique set of API insurance policies.

The Azure CI/CD pipeline has been arrange in a means that after the pull the request for merge to grasp has been authorized, it routinely senses the modifications for the states within the international asset config file and environment-specific file modifications and triggers the deployment of an Asset or MuleSoft API primarily based on the modifications utilized to sure recordsdata then creates a tag primarily based on a set of modifications that the developer has initiated.  

MuleSoft Customized Launch Model Tagging Scheme

For the reason that Azure CI/CD pipeline is outdoors the scope of this tutorial, we cannot be overlaying this on this tutorial.

Create Folder Construction

To create a folder construction in line with your surroundings necessities, we now have created the beneath folder construction.

Mother or father Folder Identify

You’ll be able to set this to the title of your API and main model; for instance, helloWorldSample-V1 (notice that V1 on this occasion signifies the key model of the API). 

  • config.json (sitting outdoors the surroundings folders) – Used for the event and publishing of the actual asset to the MuleSoft change
  • hello-oas.yaml (sitting outdoors the surroundings folders) – API OAS file for improvement and publishing for the actual asset to MuleSoft runtime
  • README.md – Learn me file for description, and tutorial notes in regards to the repository content material
  • dev env
    • config.json – Used for an API deployment on MuleSoft with the actual related  asset  title and model specified inside this file
    • coverage.json – Used to outline customized API coverage payload that can utilized to the API on the surroundings
    • tls-context.json – Used to outline environment-level customized TLS context for binding to inbound / outbound API requests.
  • qa env – Similar folder construction as dev env; Word: the precise content material of particular person JSON recordsdata will fluctuate in line with environment-specific necessities.
  • prod env – Similar folder construction as dev env; Word: the precise content material of particular person JSON recordsdata will fluctuate in line with environment-specific necessities.

Content material of Recordsdata

  • Config.json (sitting outdoors the surroundings folders):
{
	"assetId": "helloWorldSample-v1",
    "status": "published", #change this to "development" in case you are creating the asset.
	"version": "1.0.1",
	"classifier": "oas"
}
  • hello-oas.yaml (sitting outdoors the surroundings folders):

You’ll be able to create the pattern hello-oas.yaml file or an instance file by referring to this hyperlink.

{
	"assetId": "helloWorldSample-v1",
	"version": "1.0.1",
	"classifier": "oas"
}
  • coverage.json (pattern coverage file):
{
  "policy": [
     {
      "configurationData": {
        "clusterizable": true,
        "exposeHeaders": true,
        "rateLimits": [
          {
            "timePeriodInMilliseconds": 5000,
            "maximumRequests": 1000
          }
        ]
      },
      "order": 1,
      "pointcutData": null,
      "assetId": "rate-limiting",
      "assetVersion": "1.0.0",
      "groupId": "$(groupId)"
    },
    {
      "configurationData": {
        "credentialsOriginHasHttpBasicAuthenticationHeader": "customExpression",
        "clientIdExpression": "#[attributes.headers['client_id']]",
        "clientSecretExpression": "#[attributes.headers['client_secret']]"
      },
      "order": 2,
      "disabled": false,
      "pointcutData": null,
      "groupId": "$(groupId)",
      "assetId": "client-id-enforcement",
      "assetVersion": "1.3.2"
    }
  ]
}
  • tls-context.json (pattern JSON file) – Word: “masked $(variables)” to be handed by way of pipeline; you may change this to some other legitimate variable or worth. 
{
  "tlsContext_InputParameters": {
    "technology": "mule4",
    "endpoint": {
      "type": "rest",
      "deploymentType": "CH",
      "proxyUri": "https://0.0.0.0:8092/api",
      "isCloudHub": true,
      "referencesUserDomain": false,
      "responseTimeout": null,
      "muleVersion4OrAbove": true,
      "tlsContexts": {
        "inbound": {
          "tlsContextId": "$(inboundtlsContextId)",
          "name": "$(inboundTlsname)",
          "secretGroupId": "$(inboundsecretGroupId)"
        },
        "outbound": {
          "tlsContextId": "$(outboundtlsContextId)",
          "name": "$(outboundTlsname)",
          "secretGroupId": "$(outboundsecretGroupId)"
        }
      }
    }
  }
}

Seize Config Adjustments

For this, we used Python code to seize the listing of modifications after which generate a JSON file primarily based on the listing of modifications.

Import Libraries

import subprocess;
from subprocess import Popen, PIPE;
import sys;
import getopt;
import os;

Create JSON Capabilities

import json;

def get_json_key_value(filename, key):
    with open(filename, 'r') as config_file:
        config_data = json.load(config_file)
        return (config_data[''+key+''])

def create_json_file(json_data, json_file):
    jsonString = json.dumps(json_data)
    jsonFile = open(json_file, "w")
    jsonFile.write(jsonString)
    jsonFile.shut()

Create cmd Capabilities

from subprocess import *;
from os import chdir

def run_cmd(git_command, use_shell=True):
    """Run's the given git command, throws exception on failure"""
    return check_output(git_command, shell=use_shell)

def create_folder(path):
    '''Test if listing exists, if not, create it'''
    import os

    # You must change 'take a look at' to your most well-liked folder.
    CHECK_FOLDER = os.path.isdir(path)

    # If folder would not exist, then create it.
    if not CHECK_FOLDER:
        os.makedirs(path)
        print("created folder : ", path)

    else:
        print(path, "folder already exists.")

Create an Array

 Create an array for the modified recordsdata and a tags dictionary inside an array.

modified_files = []
tag_dict = []
counter = 0

# Output folder path
outputFolder = ".output"

Create Timestamp Operate

import calendar;
import time;

def get_timestamp():
    return calendar.timegm(time.gmtime())

Get and append the array of modified recordsdata utilizing the Git command to collect the listing of file modifications.

  modified_file_list = (subprocess.Popen(['git show --pretty"=format:" --name-only'], shell=True,stdout=subprocess.PIPE).talk()[0].decode('utf-8').strip())
  modified_files.append(modified_file_list.cut up())
# Create dictionary for modified recordsdata and assign tags
    for modified_file in modified_files:
        for file in modified_file:
            counter += 1
            ## For Asset Standing set to improvement
            if (((file == "config.json") or (file.endswith('.yaml'))) and ((get_json_key_value("config.json", "status")) == 'improvement')):
                tag_dict.append({'order': counter, 'fileChanged': file, 'tag': 'develop-'+(
                    get_json_key_value("config.json", "version"))+'.'+str(get_timestamp())})
            ## For Asset Standing set to printed
            if (((file == "config.json") or (file.endswith('.yaml'))) and ((get_json_key_value("config.json", "status")) == 'printed')):
                tag_dict.append({'order': counter, 'fileChanged': file, 'tag': 'stable-'+(
                    get_json_key_value("config.json", "version"))+'.'+str(get_timestamp())})
            ## For Growth surroundings deployment
            if (file.startswith('dev/')):
                tag_dict.append({'order': counter, 'fileChanged': file, 'tag': 'dev-deploy-'+(
                    get_json_key_value("config.json", "version"))+'.'+str(get_timestamp())})
            ## For QA surroundings deployment
            if (file.startswith('qa/')):
                tag_dict.append({'order': counter, 'fileChanged': file, 'tag': 'qa-deploy-'+(
                    get_json_key_value("config.json", "version"))+'.'+str(get_timestamp())})
            ## For Prod surroundings deployment
            if (file.startswith('prod/')):
                tag_dict.append({'order': counter, 'fileChanged': file, 'tag': 'prod-deploy-'+(
                    get_json_key_value("config.json", "version"))+'.'+str(get_timestamp())}

Create Output Folder

# Create .output folder if it doesn't exisit
create_folder(outputFolder)
  

Create JSON Tags File

# Create Tags json file
create_json_file(tag_dict, outputFolder+"/git_tags.json")

If all is configured correctly, the script will generate the beneath JSON tags file.

[
  {
    "order": 1,
    "fileChanged": "config.json",
    "tag": "stable-1.0.0.1663027933"
  },
  {
    "order": 2,
    "fileChanged": "dev/config.json",
    "tag": "dev-deploy-1.0.0.1663027933"
  },
  {
    "order": 3,
    "fileChanged": "qa/config.json",
    "tag": "qa-deploy-1.0.0.1663027933"
  },
  {
    "order": 4,
    "fileChanged": "prod/config.json",
    "tag": "prod-deploy-1.0.0.1663027933"
  }
]

We then seize the suitable Tags utilizing the bash script after which assign it variables utilizing jq.

The variables can then be used within the pipeline to routinely set off additional deployment duties. 

 # Use jq to learn the Json Tags and assign it to the variable
 API_STATUS=`${JQ_TOOL_PATH}jq -r '.[]| choose(.tag | startswith("develop-") or startswith("stable-")) |.tag' ${API_CONFIG_FILE}`
 DEV_DEPLOY_STATUS=`${JQ_TOOL_PATH}jq -r '.[]| choose(.tag | startswith("dev-deploy-"))|.tag' ${TAG_FILE}`
 QA_DEPLOY_STATUS=`${JQ_TOOL_PATH}jq -r '.[]| choose(.tag | startswith("qa-deploy-"))|.tag' ${TAG_FILE}`
 PROD_DEPLOY_STATUS=`${JQ_TOOL_PATH}jq -r '.[]| choose(.tag | startswith("prod-deploy-"))|.tag' ${TAG_FILE}`
 
 # Assign Azure Variables
 echo "##vso[task.setvariable variable=TAG_API_STATUS;]${API_STATUS}"
 echo "##vso[task.setvariable variable=TAG_dev_DEPLOY_STATUS;]${DEV_DEPLOY_STATUS}"
 echo "##vso[task.setvariable variable=TAG_qa_DEPLOY_STATUS;]${QA_DEPLOY_STATUS}"
 echo "##vso[task.setvariable variable=TAG_prod_DEPLOY_STATUS;]${PROD_DEPLOY_STATUS}"

We used the Pipeline process beneath in Azure DevOps to create a tag on the finish of the deployment duties.

Assign the Tag with the suitable variable on the finish of the deployment, as within the instance beneath.

Conclusion

As soon as the pipeline has run efficiently you may take a look at this by altering any of the environment-level recordsdata and merging them to the grasp by way of pull request. The remainder of the steps are principally automated. Then you may browse to the code repository tags part after which it is best to see the beneath tag for instance. 

Share This Article
Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Exit mobile version