Contact Us 1-800-596-4880

Application Validator Service

Where possible, we changed noninclusive terms to align with our company value of Equality. We maintained certain terms to avoid any effect on customer implementations.

The Application Validator Service enables you to create your own custom validators that prevent your application from being deployed if certain conditions are not met. Depending on the Mule Runtime Agent configuration, the service invokes your custom validators to enforce business rules, such as signing validation, naming conventions, or moratorium dates.

Application Validation Flowchart

Create an Application Validator

Follow these steps to create a custom validator that checks the value of an application property and stops the deployment if the property does not meet the specified criteria:

Create a Maven Project

Open a terminal, navigate to the folder where you want to create the Java project, and type the following command:

mvn archetype:generate \
	-DgroupId=org.example.agent \
	-DartifactId=mule-agent-hello-validator \
	-DarchetypeArtifactId=maven-archetype-quickstart \
	-DinteractiveMode=false

Maven Directory Layout

The previous command creates the following project directory structure:

./mule-agent-hello-validator
./mule-agent-hello-validator/pom.xml
./mule-agent-hello-validator/src
./mule-agent-hello-validator/src/test
./mule-agent-hello-validator/src/test/java
./mule-agent-hello-validator/src/test/java/org
./mule-agent-hello-validator/src/test/java/org/example
./mule-agent-hello-validator/src/test/java/org/example/agent
./mule-agent-hello-validator/src/test/java/org/example/agent/AppTest.java
./mule-agent-hello-validator/src/main
./mule-agent-hello-validator/src/main/java
./mule-agent-hello-validator/src/main/java/org
./mule-agent-hello-validator/src/main/java/org/example
./mule-agent-hello-validator/src/main/java/org/example/agent
./mule-agent-hello-validator/src/main/java/org/example/agent/App.java

Create the Project Object Model (POM) File

Create a POM file with the following configuration details:

Properties

  1. Access the generated folder and locate the generated pom.xml file.

  2. Add the following properties:

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <mule.agent.version>2.4.28</mule.agent.version>
    <javax.servlet-api.version>3.1.0</javax.servlet-api.version>
    <javax.ws.version>2.0</javax.ws.version>
    <log4j.version>2.17.1</log4j.version>
    <guice.version>5.0.1</guice.version>
    <javax.inject.version>1</javax.inject.version>
</properties>

The previous properties represent the versions used for the following required dependencies:

mule-agent-api

Java API for the Mule Agent Plugin

javax.ws.rs-api

Java API for RESTful Web Services

javax.servlet-api

Java Servlet API

javax.inject

The javax.inject API

guice

Google Guice Core Library

log4j-api

The Apache Log4j API

Dependencies

Add the com.mulesoft.agent:mule-agent-api dependency:

        <dependency>
            <groupId>com.mulesoft.agent</groupId>
            <artifactId>mule-agent-api</artifactId>
            <version>${mule.agent.version}</version>
            <scope>provided</scope>
        </dependency>

Add the javax.ws.rs:javax.ws.rs-api dependency:

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>${javax.ws.version}</version>
        </dependency>

Add the javax.servlet:javax.servlet-api dependency:

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javax.servlet-api.version}</version>
        </dependency>

Add the javax.inject:javax.inject dependency:

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>${javax.inject.version}</version>
        </dependency>

Add the com.google.inject:guice dependency:

        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>${guice.version}</version>
        </dependency>

Add the log4j dependencies:

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j.version}</version>
            <scope>compile</scope>
        </dependency>

Repositories

Add the MuleSoft releases and snapshots repositories:

    <repositories>
        <repository>
            <id>mulesoft-ci-releases</id>
            <name>Mulesoft Release Repository</name>
            <url>https://repository-master.mulesoft.org/nexus/content/repositories/releases-ee/</url>
        </repository>
        <repository>
            <id>mulesoft-ci-snapshots</id>
            <name>MuleSoft Snapshot Repository</name>
            <url>https://repository-master.mulesoft.org/nexus/content/repositories/ci-snapshots/</url>
        </repository>
    </repositories>

Create the Validator Class

  1. Rename the default class to MuleAgentHelloValidator:

    Before: mule-agent-hello-validator/src/main/java/org/example/App.java

    After: mule-agent-hello-validator/src/main/java/org/example/MuleAgentHelloValidator.java

  2. Add the following annotations:

    @Named("MuleAgentHelloValidator")
    @Singleton
  3. Add the following property to obtain a named logger based on the validator class:

    private static final Logger LOGGER = LogManager.getLogger(MuleAgentHelloWorld.class);
  4. Implement the artifact validator interface:

    public class MuleAgentHelloWorld implements ApplicationValidator {
    
        private static final Logger LOGGER = LogManager.getLogger(MuleAgentHelloWorld.class);
    
    
        // Type represents a group of validator implementations
        public String getType() {
            return "helloValidator";
        }
    
    
        // Custom name for the implementation.
        // Represent a specific use case related to the validator type
        // Must be unique in the type.
        public String getName() {
            return "defaultHelloValidator";
        }
    
        public void validate(Map<String, Object> args) throws ArtifactValidationException {
    
        }
    }
  5. Add the args parameter, which contains the validator configuration provided in the mule-agent.yml file:

      services:
    	mule.agent.artifact.validator.service:
    		enabled: true
    		validators:
    		- type: helloValidator
    			name: defaultHelloValidator
    			enabled: true
    			args:
    				business: finance
    				welcomeMessage: 'Hi, welcome to Finance Cluster Runtimes'
    				errorMessage: 'I am sorry, you are not allowed to deploy in this Cluster'

    It also contains the following values that are injected by the service:

Key Description

_APPLICATION_NAME

A string value that represents the name of the application.

_APPLICATION_FILE_PATH

A string value that represents the path of the temporary file used to deploy the application.

_APPLICATION_PROPERTIES

A Map<String, String> that represents the application properties.

Implement Business Logic

In the following example, every application deployed in the Mule runtime must have an application property called business. Its value represents the department owner of the application.

    string applicationBusiness =
       (applicationProperties == null)
          ? null
          : applicationProperties.get("business");

    if (applicationBusiness != null && applicationBusiness.equals(allowedBusiness)) {
        LOGGER.info(welcomeMessage);
        return;
    }

    throw new ArtifactValidationException(errorMessage);

Implement Custom Exceptions

Create a custom exception that represents the previous error.

In the package org.example, add a new package called exceptions and create the following class:

public class BusinessNotAllowedException extends ApplicationValidationException {

    public BusinessNotAllowedException(String message) {
        super(message);
    }
}

The project directory layout shows the following:

./mule-agent-hello-validator/src/main/java/org/example/agent/exceptions
./mule-agent-hello-validator/src/main/java/org/example/agent/exceptions/BusinessNotAllowedException.java

Replace the generic ApplicationValidationException to BusinessNotAllowedException:

    throw new BusinessNotAllowedException(errorMessage);

Add the Guice Configuration

  1. Create the BaseModuleProvider class.

    In the package org.example, add a new package called configuration.guice and create the following class:

    public class MuleAgentHelloValidatorProvider extends BaseModuleProvider {
        @Override
        protected void configureModule(Binder binder) {
            bindNamedSingleton(binder, ApplicationValidator.class, MuleAgentHelloValidator.class);
        }
    }
  2. Create the BaseModuleProvider class.

    In the directory src/main, add a new folder called META-INF/services and create the following file:

    Name: com.mulesoft.agent.configuration.guice.ModuleProvider

    Content: com.example.configuration.guice.MuleAgentHelloValidatorProvider

The project directory layout shows the following:

./mule-agent-hello-validator/src/main/resources
./mule-agent-hello-validator/src/main/resources/META-INF
./mule-agent-hello-validator/src/main/resources/META-INF/services
./mule-agent-hello-validator/src/main/resources/META-INF/services/com.mulesoft.agent.configuration.guice.ModuleProvider
./mule-agent-hello-validator/src/main/java/org/example/agent/configuration
./mule-agent-hello-validator/src/main/java/org/example/agent/configuration/guice
./mule-agent-hello-validator/src/main/java/org/example/agent/configuration/guice/MuleAgentHelloValidatorProvider.java

Build the Application Validator

Run the following command:

mvn clean install

A JAR file is generated in the target directory:

./mule-agent-hello-validator/target
./mule-agent-hello-validator/target/mule-agent-hello-validator-1.0-SNAPSHOT.jar

Install the Application Validator

  1. Place the JAR file in $MULE_HOME/server-plugins/mule-agent-plugin/lib.

  2. Access the args parameter keys and values and print them to the console:

    public void validate(Map<String, Object> args) throws ApplicationValidationException {
    
        // Values injected by the MuleAgentApplicationValidator service
        String applicationName = (String) args.get("_APPLICATION_NAME");
        String applicationFilePath = (String) args.get("_APPLICATION_FILE_PATH");
        Map<String, String> applicationProperties = (Map) args.get("_APPLICATION_PROPERTIES");
    
        // Validator configuration values
        String business = (String) args.get("business");
        String welcomeMessage = (String) args.get("welcomeMessage");
        String errorMessage = (String) args.get("errorMessage");
    
        LOGGER.info("Values injected by the service:");
        LOGGER.info("\tApplication name: {}", applicationName);
        LOGGER.info("\tApplication file path: {}", applicationFilePath);
        LOGGER.info("\tApplication properties: {}", applicationProperties);
    
        LOGGER.info("Validator configurations:");
        LOGGER.info("\tBusiness: {}", business);
        LOGGER.info("\tWelcome message: {}", welcomeMessage);
        LOGGER.info("\tError message: {}", errorMessage);
    }

Update the mule-agent.yml File

Add the validation configuration in the service:

services:
	mule.agent.artifact.validator.service:
		enabled: true
		validators:
		- type: helloValidator
			name: defaultHelloValidator
			enabled: true
			args:
				business: finance
				welcomeMessage: 'Hi, welcome to Finance Cluster Runtimes'
				errorMessage: 'I am sorry, you are not allowed to deploy in this Cluster'

Start Mule Runtime

Start Mule Runtime and verify that the validator configuration was successful. The console shows the following logs:

AgentArtifactValidatorService: Total validators loaded: 1
AgentArtifactValidatorService: Validators listed by type:
AgentArtifactValidatorService: 	Type: helloValidator Names: [defaultHelloValidator]

Deploy an Application

Once the validator is built and installed, the Agent Validator Service invokes the custom validator when you deploy an application:

Curl command:

curl -X PUT 'http://localhost:9999/mule/applications/app-01' \
-H 'Content-Type: application/json' \
-d '{
  "url": "file:/tmp/app-01.jar",
  "configuration": {
    "mule.agent.application.properties.service": {
      "applicationName": "app-01",
      "properties": {
          "business": "finance"
      }
    }
  }
}'

Response:

{
  "application": {
    "name": "app-01"
  },
  "status": "Deployment attempt started"
}

Console logs:

MuleAgentHelloValidator: Values injected by the service:
MuleAgentHelloValidator:   Application name: app-01
MuleAgentHelloValidator:   Application file path: /tmp/mule-received-artifact-1793122713159733968/app-01.jar
MuleAgentHelloValidator:   Application properties: {business=finance}
MuleAgentHelloValidator: Validator configurations:
MuleAgentHelloValidator:   Allowed Business: finance
MuleAgentHelloValidator:   Welcome message: Hi, welcome to Finance Cluster Runtimes
MuleAgentHelloValidator:   Error message: I am sorry you not allowed to be deployed in this Cluster
MuleAgentHelloValidator: Hi, welcome to Finance Cluster Runtimes

Encrypt Values in the Validator Configuration

If the validator requires a secret provided in the mule-agent.yml, you can use the amc_setup.sh script to encrypt secrets, passwords, or any other value. For more information, visit Encrypt Passwords.

  1. Encrypt a single value

    Set the AGENT_VAR_master_password environment variable to the main password:

    export AGENT_VAR_master_password=myPassword

  2. Run the encryption utility:

    $MULE_HOME/bin/amc_setup --encrypt my-secret-value

    Output:

    Mule Agent Installer
    -----------------------------
    
    
    	INFO: The encrypted value to paste on the mule-agent.yml file is: '![PBEWITHSHA1ANDDESEDE,wFE1D5V4DMb0uG77mzU+gibrlmnj3Kzb]'
  3. Add the encrypted value in the validator configuration services:

  mule.agent.artifact.validator.service:
    enabled: true
    validators:
    - type: helloValidator
      name: defaultHelloValidator
      enabled: true
      args:
        business: finance
        welcomeMessage: 'Hi, welcome to Finance Cluster Runtimes'
        errorMessage: 'I am sorry you not allowed to be deployed in this Cluster'
        secret: '![PBEWITHSHA1ANDDESEDE,wFE1D5V4DMb0uG77mzU+gibrlmnj3Kzb]'

Decrypt Values in the Validator

You can use the encryption service to decrypt values.

  1. Inject the encryption service into your validator class:

        @Inject
        EncryptionService encryptionService;
  2. Decrypt the value:

    String secret = (String) args.get("secret");
    
    String secretPlainText = null;
    
    try {
       secretPlainText = encryptionService.decrypt(secret);
    } catch (AgentEncryptionException e) {
       LOGGER.error(e);
    }
    
    LOGGER.info("\tSecret: {}", secret);
    LOGGER.info("\tSecret (plain text): {}", secretPlainText);

Use case: Pass Encrypted Values to the Validator

Curl command:

curl -X PUT 'http://localhost:9999/mule/applications/app-01' \
-H 'Content-Type: application/json' \
-d '{
  "url": "file:/tmp/app-01.jar",
  "configuration": {
    "mule.agent.application.properties.service": {
      "applicationName": "app-01",
      "properties": {
          "business": "finance"
      }
    }
  }
}'

Response:

{
  "application": {
    "name": "app-01"
  },
  "status": "Deployment attempt started"
}

Console logs:

AgentApplicationService: Deploying the app-01 application from URL file:/tmp/app-01.jar
MuleAgentHelloValidator: Values injected by the service:
MuleAgentHelloValidator: Application name: app-01
MuleAgentHelloValidator: Application file path: /tmp/mule-received-artifact-6683649864468336756/app-01.jar
MuleAgentHelloValidator: Application properties: {business=finance}
MuleAgentHelloValidator: Validator configurations:
MuleAgentHelloValidator: Allowed Business: finance
MuleAgentHelloValidator: Welcome message: Hi, welcome to Finance Cluster Runtimes
MuleAgentHelloValidator: Secret: ![PBEWITHSHA1ANDDESEDE,wFE1D5V4DMb0uG77mzU+gibrlmnj3Kzb]
MuleAgentHelloValidator: Secret (plain text): my-secret-value
MuleAgentHelloValidator: Hi, welcome to Finance Cluster Runtimes