Application Validator Service | MuleSoft Documentation
# 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.
## 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.
  * Create the Project Object Model (POM) file.
  * Create the validator class.
  * Implement business logic.
  * Implement custom exceptions.
  * Add the Guice configuration.
  * Build the application validator.
  * Install the application validator.
  * Update the `mule-agent.yml` file.
  * Start Mule Runtime.


### 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  
Google Guice Core Library  
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);
  }
}
```
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"
}
```
## 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
```

## See Also
  * Runtime Manager Agent
  *   * JAR Signature Validator