[ 
https://issues.apache.org/jira/browse/UNOMI-883?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Serge Huber updated UNOMI-883:
------------------------------
    Description: 
h2. Description
This ticket is about implementing a unified approach to validate conditions 
across different services to prevent invalid conditions from being stored and 
ensure developer experience. We have always provided type for the values, so 
these can also be used to validate the condition parameter values, but the idea 
is to go further to add an optional validation sub-object to specify additional 
validation requirements. The aim is to, for example, make sure developers don't 
forget parameters such as "operator" for the "booleanCondition", which could 
lead to difficult to understand errors.

h3. Implementation Details

h4. Core Features
The new ConditionValidation class provides the following validation 
capabilities:

*Parameter Types Support:*
* STRING
* INTEGER
* LONG
* FLOAT
* DOUBLE
* BOOLEAN
* DATE
* CONDITION
* OBJECT

*Validation Features:*
# Required Parameters
** Ability to mark parameters as mandatory
# Allowed Values
** Define a set of valid values for a parameter
# Condition Tags
** Specify allowed condition tags
** Filter conditions based on tags
# Condition Type Restrictions
** Define disallowed condition types
# Exclusive Parameters
** Support for mutually exclusive parameters
** Group exclusive parameters together
# Recommended Parameters
** Mark parameters as recommended but not required
# Custom Type Support
** Specify custom Java types for OBJECT parameters

h3. Example Condition Type Definition
{code:json}
{
  "metadata": {
    "id": "propertyCondition",
    "name": "Property Condition",
    "description": "Compares a property value"
  },
  "parameters": [
    {
      "name": "propertyName",
      "type": "string",
      "validation": {
        "required": true
      }
    },
    {
      "name": "comparisonOperator",
      "type": "string",
      "validation": {
        "required": true,
        "allowedValues": ["equals", "notEquals", "greaterThan", "lessThan", 
"exists", "missing"]
      }
    },
    {
      "name": "propertyValue",
      "type": "string",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    }
  ]
}
{code}

h3. Service Integration
The validation service has been integrated with:
* SegmentService
* RulesService
* GoalsService

h3. Benefits
* Centralized validation logic
* Consistent validation across services
* Clear distinction between required and recommended parameters
* Support for complex parameter relationships
* Type safety through custom type validation

h2. Related Documentation
* API Documentation: ConditionValidation class
* Integration Examples: See SegmentServiceImpl, RulesServiceImpl, and 
GoalsServiceImpl
* Test Cases: Validation scenarios in respective service tests

h2. Detailed Condition Type Examples

h3. Boolean Condition Type
{code:json}
{
  "metadata": {
    "id": "booleanCondition",
    "name": "Boolean Condition",
    "description": "Combines multiple conditions with a logical operator"
  },
  "parameters": [
    {
      "id": "operator",
      "type": "string",
      "validation": {
        "required": true,
        "allowedValues": ["and", "or"]
      }
    },
    {
      "id": "subConditions",
      "type": "condition",
      "multivalued": true,
      "validation": {
        "required": true
      }
    }
  ]
}
{code}

h3. Profile Property Condition Type
{code:json}
{
  "metadata": {
    "id": "profilePropertyCondition",
    "name": "Profile Property Condition",
    "description": "Evaluates a profile property against various comparison 
criteria"
  },
  "parameters": [
    {
      "id": "propertyName",
      "type": "string",
      "validation": {
        "required": true
      }
    },
    {
      "id": "comparisonOperator",
      "type": "string",
      "validation": {
        "required": true,
        "allowedValues": [
          "equals",
          "notEquals",
          "lessThan",
          "greaterThan",
          "lessThanOrEqualTo",
          "greaterThanOrEqualTo",
          "between",
          "exists",
          "missing",
          "contains",
          "notContains",
          "startsWith",
          "endsWith",
          "matchesRegex"
        ]
      }
    },
    {
      "id": "propertyValue",
      "type": "string",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    },
    {
      "id": "propertyValueInteger",
      "type": "integer",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    },
    {
      "id": "propertyValueDate",
      "type": "date",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    }
  ]
}
{code}

The actual implemented validation features include:

1. Basic Parameter Validation:
* Required parameters
* Recommended parameters
* Parameter type validation (STRING, INTEGER, LONG, FLOAT, DOUBLE, BOOLEAN, 
DATE, CONDITION, OBJECT)

2. Value Constraints:
* Allowed values (enumeration)
* Custom type validation for OBJECT type

3. Condition-Specific Validation:
* Allowed condition tags
* Disallowed condition types
* Nested condition validation

4. Parameter Relationships:
* Exclusive parameters
* Exclusive parameter groups

5. Collection Support:
* Multivalued parameter validation
* Collection type validation
* Empty collection validation for required parameters

The implementation does not include some of the features I incorrectly included 
in my previous examples:
* Pattern matching for strings
* Numeric range validation
* Complex date format validation
* Inter-parameter dependencies beyond exclusive groups
* Conditional validation based on other parameter values

Would you like me to provide more specific examples of how to use any of these 
actually implemented features?


  was:
h2. Description
This ticket is about implementing a unified approach to validate conditions 
across different services to prevent invalid conditions from being stored and 
ensure developer experience. 

h3. Implementation Details

h4. Core Features
The new ConditionValidation class provides the following validation 
capabilities:

*Parameter Types Support:*
* STRING
* INTEGER
* LONG
* FLOAT
* DOUBLE
* BOOLEAN
* DATE
* CONDITION
* OBJECT

*Validation Features:*
# Required Parameters
** Ability to mark parameters as mandatory
# Allowed Values
** Define a set of valid values for a parameter
# Condition Tags
** Specify allowed condition tags
** Filter conditions based on tags
# Condition Type Restrictions
** Define disallowed condition types
# Exclusive Parameters
** Support for mutually exclusive parameters
** Group exclusive parameters together
# Recommended Parameters
** Mark parameters as recommended but not required
# Custom Type Support
** Specify custom Java types for OBJECT parameters

h3. Example Condition Type Definition
{code:json}
{
  "metadata": {
    "id": "propertyCondition",
    "name": "Property Condition",
    "description": "Compares a property value"
  },
  "parameters": [
    {
      "name": "propertyName",
      "type": "string",
      "validation": {
        "required": true
      }
    },
    {
      "name": "comparisonOperator",
      "type": "string",
      "validation": {
        "required": true,
        "allowedValues": ["equals", "notEquals", "greaterThan", "lessThan", 
"exists", "missing"]
      }
    },
    {
      "name": "propertyValue",
      "type": "string",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    }
  ]
}
{code}

h3. Service Integration
The validation service has been integrated with:
* SegmentService
* RulesService
* GoalsService

h3. Benefits
* Centralized validation logic
* Consistent validation across services
* Clear distinction between required and recommended parameters
* Support for complex parameter relationships
* Type safety through custom type validation

h2. Related Documentation
* API Documentation: ConditionValidation class
* Integration Examples: See SegmentServiceImpl, RulesServiceImpl, and 
GoalsServiceImpl
* Test Cases: Validation scenarios in respective service tests

h2. Detailed Condition Type Examples

h3. Boolean Condition Type
{code:json}
{
  "metadata": {
    "id": "booleanCondition",
    "name": "Boolean Condition",
    "description": "Combines multiple conditions with a logical operator"
  },
  "parameters": [
    {
      "name": "operator",
      "type": "string",
      "validation": {
        "required": true,
        "allowedValues": ["and", "or", "not"]
      }
    },
    {
      "name": "subConditions",
      "type": "array",
      "validation": {
        "required": true,
        "type": "CONDITION",
        "allowedConditionTags": ["profileCondition", "sessionCondition", 
"eventCondition"],
        "disallowedConditionTypes": ["pastEventCondition"]  // Example of 
condition types that shouldn't be nested
      }
    }
  ]
}
{code}

h3. Profile Property Condition Type
{code:json}
{
  "metadata": {
    "id": "profilePropertyCondition",
    "name": "Profile Property Condition",
    "description": "Evaluates a profile property against various comparison 
criteria"
  },
  "parameters": [
    {
      "name": "propertyName",
      "type": "string",
      "validation": {
        "required": true
      }
    },
    {
      "name": "comparisonOperator",
      "type": "string",
      "validation": {
        "required": true,
        "allowedValues": [
          "equals",
          "notEquals",
          "lessThan",
          "greaterThan",
          "lessThanOrEqualTo",
          "greaterThanOrEqualTo",
          "between",
          "exists",
          "missing",
          "contains",
          "notContains",
          "startsWith",
          "endsWith",
          "matchesRegex",
          "in",
          "notIn"
        ]
      }
    },
    {
      "name": "propertyValue",
      "type": "string",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"  // Part of the value group - only one 
value type can be used
      }
    },
    {
      "name": "propertyValues",
      "type": "array",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"  // Part of the value group - only one 
value type can be used
      }
    },
    {
      "name": "propertyValueInteger",
      "type": "integer",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    },
    {
      "name": "propertyValueDate",
      "type": "date",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    },
    {
      "name": "propertyValuesInteger",
      "type": "array",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup",
        "type": "INTEGER"
      }
    },
    {
      "name": "propertyValuesDate",
      "type": "array",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup",
        "type": "DATE"
      }
    },
    {
      "name": "propertyValueRegex",
      "type": "string",
      "validation": {
        "recommended": true,
        "exclusive": true,
        "exclusiveGroup": "valueGroup"
      }
    }
  ]
}
{code}

h3. Usage Examples

h4. Boolean AND condition with profile properties
{code:json}
{
  "type": "booleanCondition",
  "parameterValues": {
    "operator": "and",
    "subConditions": [
      {
        "type": "profilePropertyCondition",
        "parameterValues": {
          "propertyName": "age",
          "comparisonOperator": "greaterThan",
          "propertyValueInteger": 25
        }
      },
      {
        "type": "profilePropertyCondition",
        "parameterValues": {
          "propertyName": "interests",
          "comparisonOperator": "contains",
          "propertyValue": "sports"
        }
      }
    ]
  }
}
{code}

h4. Profile property condition with multiple values
{code:json}
{
  "type": "profilePropertyCondition",
  "parameterValues": {
    "propertyName": "age",
    "comparisonOperator": "between",
    "propertyValuesInteger": [25, 35]
  }
}
{code}

h4. Profile property condition with date comparison
{code:json}
{
  "type": "profilePropertyCondition",
  "parameterValues": {
    "propertyName": "lastVisit",
    "comparisonOperator": "greaterThan",
    "propertyValueDate": "2024-01-01T00:00:00Z"
  }
}
{code}

h4. Profile property condition with regex
{code:json}
{
  "type": "profilePropertyCondition",
  "parameterValues": {
    "propertyName": "email",
    "comparisonOperator": "matchesRegex",
    "propertyValueRegex": "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
  }
}
{code}

Key points about these examples:

1. *Boolean Condition:*
* Supports nested conditions with type validation
* Can restrict allowed/disallowed condition types
* Validates condition tags

2. *Profile Property Condition:*
* Uses exclusive groups for different value types
* Supports multiple comparison operators
* Handles different data types (string, integer, date)
* Supports both single and multi-valued properties
* Includes regex matching capability

3. *Validation Features Demonstrated:*
* Required vs. recommended parameters
* Allowed values constraints
* Exclusive parameter groups
* Type-specific validations
* Array type validations

Would you like me to explain any specific aspect of these examples in more 
detail?



> Implement Unified Condition Validation Service for Enhanced Developer 
> Experience and Error Prevention
> -----------------------------------------------------------------------------------------------------
>
>                 Key: UNOMI-883
>                 URL: https://issues.apache.org/jira/browse/UNOMI-883
>             Project: Apache Unomi
>          Issue Type: Sub-task
>          Components: unomi(-core)
>    Affects Versions: unomi-3.0.0
>            Reporter: Serge Huber
>            Priority: Major
>             Fix For: unomi-3.0.0
>
>
> h2. Description
> This ticket is about implementing a unified approach to validate conditions 
> across different services to prevent invalid conditions from being stored and 
> ensure developer experience. We have always provided type for the values, so 
> these can also be used to validate the condition parameter values, but the 
> idea is to go further to add an optional validation sub-object to specify 
> additional validation requirements. The aim is to, for example, make sure 
> developers don't forget parameters such as "operator" for the 
> "booleanCondition", which could lead to difficult to understand errors.
> h3. Implementation Details
> h4. Core Features
> The new ConditionValidation class provides the following validation 
> capabilities:
> *Parameter Types Support:*
> * STRING
> * INTEGER
> * LONG
> * FLOAT
> * DOUBLE
> * BOOLEAN
> * DATE
> * CONDITION
> * OBJECT
> *Validation Features:*
> # Required Parameters
> ** Ability to mark parameters as mandatory
> # Allowed Values
> ** Define a set of valid values for a parameter
> # Condition Tags
> ** Specify allowed condition tags
> ** Filter conditions based on tags
> # Condition Type Restrictions
> ** Define disallowed condition types
> # Exclusive Parameters
> ** Support for mutually exclusive parameters
> ** Group exclusive parameters together
> # Recommended Parameters
> ** Mark parameters as recommended but not required
> # Custom Type Support
> ** Specify custom Java types for OBJECT parameters
> h3. Example Condition Type Definition
> {code:json}
> {
>   "metadata": {
>     "id": "propertyCondition",
>     "name": "Property Condition",
>     "description": "Compares a property value"
>   },
>   "parameters": [
>     {
>       "name": "propertyName",
>       "type": "string",
>       "validation": {
>         "required": true
>       }
>     },
>     {
>       "name": "comparisonOperator",
>       "type": "string",
>       "validation": {
>         "required": true,
>         "allowedValues": ["equals", "notEquals", "greaterThan", "lessThan", 
> "exists", "missing"]
>       }
>     },
>     {
>       "name": "propertyValue",
>       "type": "string",
>       "validation": {
>         "recommended": true,
>         "exclusive": true,
>         "exclusiveGroup": "valueGroup"
>       }
>     }
>   ]
> }
> {code}
> h3. Service Integration
> The validation service has been integrated with:
> * SegmentService
> * RulesService
> * GoalsService
> h3. Benefits
> * Centralized validation logic
> * Consistent validation across services
> * Clear distinction between required and recommended parameters
> * Support for complex parameter relationships
> * Type safety through custom type validation
> h2. Related Documentation
> * API Documentation: ConditionValidation class
> * Integration Examples: See SegmentServiceImpl, RulesServiceImpl, and 
> GoalsServiceImpl
> * Test Cases: Validation scenarios in respective service tests
> h2. Detailed Condition Type Examples
> h3. Boolean Condition Type
> {code:json}
> {
>   "metadata": {
>     "id": "booleanCondition",
>     "name": "Boolean Condition",
>     "description": "Combines multiple conditions with a logical operator"
>   },
>   "parameters": [
>     {
>       "id": "operator",
>       "type": "string",
>       "validation": {
>         "required": true,
>         "allowedValues": ["and", "or"]
>       }
>     },
>     {
>       "id": "subConditions",
>       "type": "condition",
>       "multivalued": true,
>       "validation": {
>         "required": true
>       }
>     }
>   ]
> }
> {code}
> h3. Profile Property Condition Type
> {code:json}
> {
>   "metadata": {
>     "id": "profilePropertyCondition",
>     "name": "Profile Property Condition",
>     "description": "Evaluates a profile property against various comparison 
> criteria"
>   },
>   "parameters": [
>     {
>       "id": "propertyName",
>       "type": "string",
>       "validation": {
>         "required": true
>       }
>     },
>     {
>       "id": "comparisonOperator",
>       "type": "string",
>       "validation": {
>         "required": true,
>         "allowedValues": [
>           "equals",
>           "notEquals",
>           "lessThan",
>           "greaterThan",
>           "lessThanOrEqualTo",
>           "greaterThanOrEqualTo",
>           "between",
>           "exists",
>           "missing",
>           "contains",
>           "notContains",
>           "startsWith",
>           "endsWith",
>           "matchesRegex"
>         ]
>       }
>     },
>     {
>       "id": "propertyValue",
>       "type": "string",
>       "validation": {
>         "recommended": true,
>         "exclusive": true,
>         "exclusiveGroup": "valueGroup"
>       }
>     },
>     {
>       "id": "propertyValueInteger",
>       "type": "integer",
>       "validation": {
>         "recommended": true,
>         "exclusive": true,
>         "exclusiveGroup": "valueGroup"
>       }
>     },
>     {
>       "id": "propertyValueDate",
>       "type": "date",
>       "validation": {
>         "recommended": true,
>         "exclusive": true,
>         "exclusiveGroup": "valueGroup"
>       }
>     }
>   ]
> }
> {code}
> The actual implemented validation features include:
> 1. Basic Parameter Validation:
> * Required parameters
> * Recommended parameters
> * Parameter type validation (STRING, INTEGER, LONG, FLOAT, DOUBLE, BOOLEAN, 
> DATE, CONDITION, OBJECT)
> 2. Value Constraints:
> * Allowed values (enumeration)
> * Custom type validation for OBJECT type
> 3. Condition-Specific Validation:
> * Allowed condition tags
> * Disallowed condition types
> * Nested condition validation
> 4. Parameter Relationships:
> * Exclusive parameters
> * Exclusive parameter groups
> 5. Collection Support:
> * Multivalued parameter validation
> * Collection type validation
> * Empty collection validation for required parameters
> The implementation does not include some of the features I incorrectly 
> included in my previous examples:
> * Pattern matching for strings
> * Numeric range validation
> * Complex date format validation
> * Inter-parameter dependencies beyond exclusive groups
> * Conditional validation based on other parameter values
> Would you like me to provide more specific examples of how to use any of 
> these actually implemented features?



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to