(Click to open topic with navigation)
Plugin types can optionally define validation constraints for the polling interval and plugin configuration. These parameters are then checked against the defined constraints during the creation of a new plugin. If the validation fails, meaning the configuration provided does not pass the constraints defined by the plugin type, the plugin will fail to be created with error messages based on the parameters and constraints defined.
Defining constraints
To define constraints for a plugin type and therefore for all plugins created using it, use the following syntax:
import com.adaptc.mws.plugins.* class ConstrainedPlugin extends AbstractPlugin { static constraints = { // Set plugin's default polling interval pollInterval defaultValue:60 // The "myParam" configuration parameter is automatically required and cannot be blank myParam blank:false // The "myEnum" configuration parameter is not required and must set to one of the values in the list myEnum required:false, inList:["val1", "val2", "val3] // Insert additional constraints here… } }
In the table below, all available constraints are shown, as well as the expected value type, an example, the default message code, and the message suffix. The message columns are described in greater detail in the Messaging section below.
Constraint | Default value | Type | Example value | Default message code | Message suffix | Description |
---|---|---|---|---|---|---|
blank | -- | Boolean | true | default.blank.message | blank | If false, the parameter (if present) cannot be a blank string. |
creditCard | -- | Boolean | true | default.invalid.creditCard.message | creditCard.invalid | If true, uses org.apache.commons.validator.CreditCardValidator to determine if the parameter (if present) is a valid credit card number. |
defaultValue | -- | Object or Closure | 60 | -- | -- | If the parameter is not present, it will be set to this default value. Does not return any error messages. See Default value below for more information. |
-- | Boolean | true | default.invalid.email.message | email.invalid | If true, the parameter (if present) must be a valid email address. | |
inList | -- | List | ["first", "second"] | default.not.inlist.message | not.inList | The parameter (if present) must be set to one of the values specified. |
matches | -- | String | "[a-z][A-Z]+" | default.doesnt.match.message | matches.invalid | The parameter (if present) must match the specified regular expression. |
max | -- | Integer | 10 | default.invalid.max.message | max.exceeded | The parameter (if present) must not be greater than the defined value. |
*maxSize | -- | Integer | 10 | default.invalid.max.size.message | maxSize.exceeded | The parameter's (if present) size must not be greater than the defined value. |
min | -- | Integer | 1 | default.invalid.min.message | min.notmet | The parameter (if present) must not be less than the defined value. |
*minSize | -- | Integer | 1 | default.invalid.min.size.message | minSize.notmet | The parameter's (if present) size must not be less than the defined value. |
notEqual | -- | Object | "Invalid Value" | default.not.equal.message | notEqual | The parameter (if present) must not be set to the defined value. |
nullable | true | Boolean | false | default.null.message | nullable | If true, the parameter (if present) must be non-null value. See required for how to enforce the parameter to be present. |
password | -- | Boolean | true | -- | -- | If true, the parameter (if present) is hidden from the user both on input and display when managing plugin configuration. It is not, however, hidden in the REST API. Does not return any error messages. |
range | -- | Range | 1..10 | default.invalid.range.message | range.toosmall/range.toobig | Uses a groovy range to validate that the value is within a specified range. |
required | true | Boolean | false | default.required.message | required | If true, the parameter must be present and non-null for the plugin to be created successfully. Implies the nullable:false constraint. |
scale | -- | Integer | 2 | -- | -- | Only valid for Double parameters. Rounds the parameter (if present) to the specified number of digits. Does not return any error messages. |
*size | -- | Range | 2 | default.invalid.size.message | size.toosmall/size.toobig | Uses a groovy range to restrict the size of a collection, string, or a number. |
*type | -- | Class | Integer.class | typeMismatch | typeMismatch | See Type inferencing and conversion below. |
url | -- | Boolean | true | default.invalid.url.message | url.invalid | If true, uses org.apache.commons.validator.UrlValidator to determine if the parameter (if present) is a valid URL. Does not support exec or file scheme URLs. |
scriptableUrl | -- | Boolean | true | default.invalid.scriptable.url.message | scriptableUrl.invalid | Identical to the url validator, but adds support for exec and file scheme URLs. |
validator | -- | Closure | (See Custom validator) | default.invalid.validator.message | validator.error | See Custom validator below. |
widget | -- | String | "textarea" | -- | -- | By default, all strings render as a text field when creating or editing plugins. Setting this to "textarea" causes it to render as a text area with multi-line support. This is only valid for string configuration parameters. |
* The user interface (see Plugin Management) does not support parameters whose type is a subclass of Collection (a List, for example). Such parameters are therefore not recommended.
The polling interval constraints must always apply to Integer types. If this specification is violated, the plugin type cannot be added or updated.
When defined constraints are violated for a plugin, error messages are retrieved based on the configuration parameters and the applied constraints using i18n Messaging codes (see i18n Messaging). First, the most specific error message will be attempted to be resolved from a message code generated from the plugin type name, the configuration parameter, and the constraint. This code takes the format of pluginTypeName.parameterName.suffix where the plugin type's name has a lowercase first letter and the suffix is shown in the table above. If this message code is not defined, the default message code (as shown in the table above) will be used.
For example, if the url constraint validation failed for the "ExamplePlugin" plugin type's "endpoint" configuration parameter, the following message codes would be resolved in order:
Plugin types that have two or more uppercase letters at the start of the name will not be converted to have a lowercase first letter for error message codes. In other words, for the example just given using "VCenterPlugin" instead of "ExamplePlugin", the following message codes would be resolved in order:
VCenterPlugin.endpoint.url.invalid
default.invalid.url.message
Default messages
Default messages may be contained in any messages.properties file included in the plugin JAR file as explained in i18n Messaging (see i18n Messaging). Arguments for each constraint vary, but they always include these argument indices:
If default messages are not defined in the plugin project, the following messages will be used:
default.doesnt.match.message=The ''{0}'' configuration parameter value ({2}) does not match the required pattern ''{3}'' default.invalid.url.message=The ''{0}'' configuration parameter value ({2}) is not a valid URL default.invalid.scriptable.url.message=The ''{0}'' configuration parameter value ({2}) is not a valid scriptable URL default.invalid.creditCard.message=The ''{0}'' configuration parameter value ({2}) is not a valid credit card number default.invalid.email.message=The ''{0}'' configuration parameter value ({2}) is not a valid e-mail address default.invalid.range.message=The ''{0}'' configuration parameter value ({2}) does not fall within the valid range from {3} to {4} default.invalid.size.message=The ''{0}'' configuration parameter value ({2}) does not fall within the valid size range from {3} to {4} default.invalid.max.message=The ''{0}'' configuration parameter value ({2}) is greater than the maximum value of {3} default.invalid.min.message=The ''{0}'' configuration parameter value ({2}) is less than the minimum value of {3} default.invalid.max.size.message=The ''{0}'' configuration parameter value ({2}) exceeds the maximum size of {3} default.invalid.min.size.message=The ''{0}'' configuration parameter value ({2}) is less than the minimum size of {3} default.invalid.validator.message=The ''{0}'' configuration parameter value ({2}) does not pass custom validation default.not.inlist.message=The ''{0}'' configuration parameter value ({2}) is not contained within the list [{3}] default.blank.message=The ''{0}'' configuration parameter cannot be blank default.not.equal.message=The ''{0}'' configuration parameter value ({2}) cannot be equal to ''{3}'' default.null.message=The ''{0}'' configuration parameter cannot be null default.required.message=The ''{0}'' configuration parameter is required and cannot be null typeMismatch=The ''{0}'' configuration parameter value ({2}) does not match the required type ''{3}''
Labels and help messages
Message codes may also be provided for configuration parameters to aid the admin user with human readable property labels and help messages. Similar to the validation error message codes, labels and help message codes may be defined using the pluginTypeName.parameterName.label and pluginTypeName.parameterName.help message codes. These values are used only in plugin type management (see Plugin Type Management) and are not exposed through the REST API.
Type inferencing and conversion
Due to the dynamic nature of configuration parameters, the expected type or class of values for each parameter are inferred from constraints. The following rules govern how type is inferred, in priority order:
Only the String, Date, Double, Integer, and Boolean classes are supported for the *type constraint. If Float or Long is desired, use Double and Integer respectively as the type.
If the configuration parameter values can be converted to the expected types, this will occur automatically. Otherwise, the *type constraint is violated and the applicable error messages will be generated.
In cases where the built-in constraints prove inadequate for validation, custom validators may be used. The validator constraint expects a Groovy Closure parameter which has one or (optionally) two arguments: the value of the configuration parameter and the plugin object. With these parameters, complex validation logic may be defined. Additionally, custom message codes and arguments may be defined by validator constraints and these will be used in generating error messages when validation fails.
For example, suppose that the parameter "user" cannot be set to the same value as parameter "creator." Additionally, the "creator" parameter must not be equal to either "bob" or "joe." The existing constraints are inadequate to fulfill this use case, but the following code using validators would perform exactly as expected:
import com.adaptc.mws.plugins.* class ConstrainedPlugin extends AbstractPlugin { static constraints = { user validator:{ val, obj -> if (val==obj.config.creator) return "invalid.equal.to.creator" } creator validator:{ val -> if ("val"=="joe") return ["invalid.equal", "joe"] if (val=="bob") return ["invalid.equal", "bob"] } } }
In the examples above, the message codes and output on validation failure is shown below:
Message codes ------------------------------------ constrainedPlugin.user.invalid.equal.to.creator=The user configuration parameter value ({2}) must not be equal to the creator parameter. constrainedPlugin.creator.invalid.equal=The creator configuration parameter must not be equal to {3}.
Output error messages ------------------------------------ For user = "jill", creator = "jill" "The user configuration parameter value (jill) must not be equal to the creator parameter." For user = "jill", creator = "bob" "The creator configuration parameter must not be equal to bob." For user = "jill", creator = "joe" "The creator configuration parameter must not be equal to joe."
The validator Closure may return:
All validator constraints automatically have the appConfig property available, which contains the application configuration as discussed in the Configuration section (see Configuration). The suite property contains the value of the configured MWS suite. Additionally, services may be retrieved as explained in the next section.
Retrieving services
At times it may be necessary to use Bundled Services in custom validators. A method named getService which takes a single string parameter of the name of the service (as used during injection) is provided to be used in these cases. For example, if a plugin needs a valid server certificate file, the SSL Service may be used as follows:
import com.adaptc.mws.plugins.* class ConstrainedPlugin extends AbstractPlugin { static constraints = { certificateFile validator:{ val -> ISslService sslService = getService("sslService") try { sslService.getSocketFactory(val) } catch(Exception e) { // Certificate file is invalid, return an error return ["invalid", e.message] } } } }
The getService method does not work with translators, custom components, RM services, or the Individual Datastore.
The default value for a configuration parameter might depend on the MWS configuration or other properties. Therefore, the defaultValue constraint can be set to a closure. The defaultValue closure does not take any parameters and must return the object to be used as the default value.
For example, if the default value of a parameter must be true if and only if MWS is configured for the Cloud suite, then the following constraints would satisfy these conditions:
import com.adaptc.mws.plugins.* class ConstrainedPlugin extends AbstractPlugin { static constraints = { myParameter required: true, type: Boolean, defaultValue: { return suite == Suite.CLOUD } } }
As with validator closures, defaultValue closures have access to appConfig, suite, and getService.
Related Topics