Value Providers | MuleSoft Documentation
# Value Providers
When developing a connector, you can let the end user select a parameter from a set of values. This makes it easier for the user to know what to configure, and you can be sure that the configured values will be correct.
You can provide this functionality for known values by using a Java Enum as a parameter. The SDK automatically takes all the values from the Enum so they can be provided as a combo-selector in the UI.
To include values that are not known, such as custom values, you should use Value Providers, instead.
Note that unlike Metadata, which is meant to discover the dynamic types of a parameter, this feature is designed to provide the possible values of a parameter.
## Java Enum
Assume that you are developing a connector for a Content Publishing Service that can publish content with these roles:


To provide these roles, you simply create a `UserRole` Enum and expose it as a parameter of the `publishAs` operation, for example:
Example: Java Enum the Defines Known Roles
```
public enum UserRole {
  ADMIN, READER, WRITER
}
```

The operation method in the next example lets the user publish content using a certain `UserRole`.
```
public void publishAs(@Content Object content, UserRole roleEnum){
  System.out.println("Publishing " + content + " with Role: " + roleEnum);
}
```

This solution is easy and effective, but it carries several limitations and problems:
  * Does not support custom values: Because the parameter is based on a Enum, you cannot define a custom value. For example, if the service to which you are connecting can be configured with custom roles, you will not be able to continue using the `UserRole` Enum because it will limit the connector’s capabilities.
  * The values are defined statically: You cannot change the values depending on a connection or configuration.
  * Java Enums have naming restrictions: You cannot have an Enum value starting with a Number or special characters.


If need custom roles but do not want to lose the drop-down list of known User Roles, you can use Value Providers for dynamic values and known values.
## Value Providers
Value Providers is a mechanism for providing values in a dynamic and smart way for any parameter in any component of a connector: Operations, Sources, Configurations, Connection Providers, scopes, and so on.
### To Implement Value Providers
This example produces the same behavior as the Enum solution above, but it provides the benefit of an open set of values. It will support a custom value.
  1. Create a Java Class implementing `ValueProvider`.
When implementing this interface, you must implement the `resolve()` method, which returns a set of values.
```
public class StaticUserRoleValueProvider implements ValueProvider {
  @Override
  public Set<Value> resolve() {
    return ValueBuilder.getValuesFor("ADMIN", "READER", "WRITER");
  }
}
```

  2. Mark the parameter that requires dynamic values with the `@OfValues()` annotation.
`@OfValues` requires a `ValueProvider` implementation that is bound to the parameter. For example, the following operation method `publishAs` includes such binding:
```
public void publishAs(@Content Object content,
@OfValues(StaticUserRoleValueProvider.class) String userRole){ **(1)**
  System.out.println("Publishing " + content + " with Role: " + userRole);
}
```

  3. Now, you can use it in Studio to start retrieving values.


### Value Providers with Connections or Configurations
Value Providers can receive connections and configurations. This makes it possible to resolve values based on the current connection and configuration.
You cannot inject connections and configurations into Value Providers that are located in connection and configuration parameters.   
---  
#### Receiving a Connection or Configuration
You use the `@Connection` and `@Config` annotations to declare the use of connections and configurations inside a Value Provider. To work, a Value Provider that uses these annotations depends on a _valid_ configuration or connection. The SDK ensures that the resolving logic will not be executed unless the connection and configuration are valid.
```
public class ConnectedValueProvider implements ValueProvider {
 @Connection
 ServiceConnection connection;
 @Config
 ServiceConfig config;
 @Override
 public Set<Value> resolve() throws ValueResolvingException {
  //Do whatever is required with the connection or config
  List<String> result = connection.retrieveInfo();
  return ValueBuilder.getValuesFor(result);
 }
}
```

The injected connections and configurations must be of a type that is compatible with those defined in the operation or source where the Value Provider is referenced.   
---  
### Example 2: Connected Value Provider Use Case
In the Roles example above, the service could define custom roles, but it was not possible for the connector to communicate those roles.
Once the Value Provider is implemented to resolve values through a working connection, it becomes possible to fetch the available roles and communicate them through the Value Provider:
```
public class UserRoleValueProvider implements ValueProvider {
 @Connection
 ServiceConnection connection;
 @Override
 public Set<Value> resolve() throws ValueResolvingException {
  return ValueBuilder.getValuesFor(connection.getAvailableRoles());
 }
}
```

### Value Providers that Depend on Other Parameters
In addition to injecting connections and configurations, Value Providers can depend on other parameters of the _same context_. The SDK ensures that the Value Provider resolving logic will not be executed until the required parameters are configured.
The words "_same context_ " mean that if the Value Provider is used in a component, the required parameter must exist in that component. For example, if the configuration `FancyConfig` with a Value Provider in the parameter `dynamicParam` requires the value of the parameter `aConfigParam`, `aConfigParam` must exist in the `FancyConfig` configuration.
The use of expressions in the required parameters might disable the execution of the Value Provider due to the impossibility of resolving the expression without an active event.   
---  
#### Declaring Required Parameters
As with connectors and configurations, you use the `@Parameter` annotation to declare a parameter that is required for executing the resolving logic. You use the annotation in a field of the Value Provider with the **same type and name** as the required parameter, such as `String requiredParam` in these examples:
Example External parameters: Operation declaring two params, one with a value provider
```
public void operationWithValueProvider(String requiredParam, @OfValues(ValueProviderWithRequiredParams.class) String dynamicParam){
}
```

Example External parameters: Value provider requiring the `requiredParam` parameter.
```
public class ValueProviderWithRequiredParams implements ValueProvider {
  @Parameter
  String requiredParam;
  @Override
  public Set<Value> resolve() {
   return ValuesBuilder.getValuesFor(param);
  }
}
```

##### What Happens If The Required Parameter Is Not Configured?
If the parameter is defined as required in the component but is not configured by the end user, the Value Provider will not execute. However, if the parameter is defined as optional, the Value Provider will be executed with a `Null` value, so you will need to handle the nullability.
##### Example 3: Value Provider with Context Parameters
Consider the case where you want to have a Date Picker for the day and month. You can easily represent them with two Enums, but not all months have the same number of days. So the representation might allow the user to configure invalid dates.
To fix this issue:
  1. Define an operation that exposes a Date Picker.
The operation receives two parameters, an `monthEnum` that statically communicates all the available months and a `day` that is used to communicate the day of the month.
Publish On Date Operation
```
public void publishOnDate(Month monthEnum, @OfValues(DayValueProvider.class) String day) {
}
```

  2. Define the `Month` Enum.
The `Month` contains all the available months and identifies the number of days in each month.
MonthEnum Enum
```
public enum Month {
  JANUARY(31), FEBRUARY(28), MARCH(31), APRIL(30), MAY(31), JUNE(30),
  JULY(31), AUGUST(31), SEPTEMBER(30), OCTOBER(31), NOVEMBER(30), DECEMBER(31);
  private int dayCount;
  MonthEnum(int i) {
    dayCount = i;
  }
  public int getDayCount() {
    return dayCount;
  }
}
```

  3. Create a Value Provider that consumes the selected Month.
Depending on the selected month, the Value Provider will dynamically provide all the available days in that month. The `DayValueProvider` indicates that it requires the parameter `monthEnum` to work.
```
public class DayValueProvider implements ValueProvider {
  @Parameter
  Month monthEnum; **(1)**
  @Override
  public Set<Value> resolve() {
   return ValueBuilder.getValuesFor(getNumbersFrom(1, monthEnum.getDayCount())
       .stream()
       .map(num -> String.format("%02d", num)));
  }
  List<Integer> getNumbersFrom(int init, int end){
    List<Integer> numbers = new ArrayList<>(end - init);
    for (int i = init; i <= end; i++) {
      numbers.add(i);
    }
    return numbers;
  }
}
```

  4. Result!
As shown in the animation below, the `Day` selector gets populated dynamically based on the `Month enum` parameter value.
3. Create a Value Provider that consumes the selected Month.
Depending on the selected month, the Value Provider will dynamically provide all the available days in that month. The `DayValueProvider` indicates that it requires the parameter `monthEnum` to work.
```
public class DayValueProvider implements ValueProvider {
  @Parameter
  Month monthEnum; **(1)**
  @Override
  public Set<Value> resolve() {
   return ValueBuilder.getValuesFor(getNumbersFrom(1, monthEnum.getDayCount())
       .stream()
       .map(num -> String.format("%02d", num)));
  }
  List<Integer> getNumbersFrom(int init, int end){
    List<Integer> numbers = new ArrayList<>(end - init);
    for (int i = init; i <= end; i++) {
      numbers.add(i);
    }
    return numbers;
  }
}
```

  4. Result!
As shown in the animation below, the `Day` selector gets populated dynamically based on the `Month enum` parameter value.


#### Value Structure
Value Providers return a set of Values. A `Value` is a simple structure composed of these properties:
  * `id` : A unique identifier for this value. This is required.
  * `displayName`: A name that will be displayed in the UI. This is optional. By default, the ID will be used as the Display Name.


#### How to create a Value
There is a unique way to create values by using `ValueBuilder`.
```
ValueBuilder adminValueBuilder = ValueBuilder.newValue("ADMIN_USR_ROLE"); **(1)**
adminValueBuilder.withDisplayName("Admin"); **(2)**
Value adminValue = newValue.build(); **(3)**
```

You must create the `ValueBuilder` with the ID of the `Value`.  
---  
Optionally, you can enrich the value with a Display Name.  
Build the builder to return a `Value` instance.  
## ValueBuilder Utils
`ValueBuilder` provides utilities to make it easier to create values for certain cases.
If you have a `List<String>`, `String[]`, `Stream<String>`, or `Map<String, String>` with values that need to be transformed to Values, the easiest way to make this transformation is to use `getValuesFor()`.
```
// Array Case
Set<Value> arrayCase = ValueBuilder.getValuesFor("Admin", "Writer");
// List Case
List<String> valueList = new ArrayList<>();
valueList.add("Admin");
valueList.add("Writer");
Set<Value> listCase = ValueBuilder.getValuesFor(valueList);
// Stream Case
Set<Value> streamCase = ValueBuilder.getValuesFor(valueList.stream());
// Map Case
// The Key will be considered as ID and the Value as Display Name
Map<String, String> valueMap = new HashMap<>();
valueMap.put("ADMIN_USR_ROLE", "Admin");
valueMap.put("WRITER_USR_ROLE") "Writer");
Set<Value> mapCase = ValueBuilder.getValuesFor(valueMap);
```