diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/VariableFilter.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/VariableFilter.kt index eaa4923..4cfee60 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/VariableFilter.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/VariableFilter.kt @@ -1,12 +1,22 @@ package io.zeebe.zeeqs.data.entity -enum class EqualityOperation { +enum class ComparisonOperation { EQUALS, CONTAINS } +enum class FilterOperation { + AND, + OR +} + class VariableFilter ( val name: String, val value: String, - val equalityOperation: EqualityOperation = EqualityOperation.EQUALS + val comparisonOperation: ComparisonOperation = ComparisonOperation.EQUALS +) + +class VariableFilterGroup ( + val variables: List, + val filterOperation: FilterOperation = FilterOperation.OR ) \ No newline at end of file diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessInstanceService.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessInstanceService.kt index e9d0468..a8d2431 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessInstanceService.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessInstanceService.kt @@ -12,35 +12,42 @@ class ProcessInstanceService( private val processInstancesRepository: ProcessInstanceRepository, private val variableRepository: VariableRepository) { - private fun getVariables(stateIn: List, variables: List): List { + private fun getVariables(stateIn: List, variableFilterGroup: VariableFilterGroup): List { val processInstances = processInstancesRepository.findByStateIn(stateIn).toList(); - return getVariablesByProcessInstanceKeys(processInstances, variables); + return getVariablesByProcessInstanceKeys(processInstances, variableFilterGroup); } - private fun getVariables(stateIn: List, processDefinitionKey: Long, variables: List): List { + private fun getVariables(stateIn: List, processDefinitionKey: Long, variableFilterGroup: VariableFilterGroup): List { val processInstances = processInstancesRepository.findByProcessDefinitionKeyAndStateIn(processDefinitionKey, stateIn).toList(); - return getVariablesByProcessInstanceKeys(processInstances, variables); + return getVariablesByProcessInstanceKeys(processInstances, variableFilterGroup); } - private fun getVariablesByProcessInstanceKeys(processInstances: List, variables: List): List { - val variableNames = variables.map { it.name } + private fun matchesFilter(variable: Variable, filter: VariableFilter): Boolean { + return when (filter.comparisonOperation) { + ComparisonOperation.EQUALS -> variable.name == filter.name && variable.value == filter.value + ComparisonOperation.CONTAINS -> variable.name == filter.name && variable.value.contains(filter.value) + } + } + + private fun getVariablesByProcessInstanceKeys(processInstances: List, variableFilterGroup: VariableFilterGroup): List { val processInstancesKeys = processInstances.map { it.getKey() } - val variablesList = variableRepository.findByProcessInstanceKeyInAndNameIn(processInstancesKeys, variableNames); - val filteredVariables = variablesList.filter { variable -> - variables.any { filter -> - when (filter.equalityOperation) { - EqualityOperation.EQUALS -> variable.name == filter.name && variable.value == filter.value - EqualityOperation.CONTAINS -> variable.name == filter.name && variable.value.contains(filter.value) - } + val variableNames = variableFilterGroup.variables.map { it.name } + val variablesList = variableRepository.findByProcessInstanceKeyInAndNameIn(processInstancesKeys, variableNames) + + return variablesList.filter { variable -> + if (variableFilterGroup.filterOperation == FilterOperation.AND) { + variableFilterGroup.variables.all { matchesFilter(variable, it) } + } else { + variableFilterGroup.variables.any { matchesFilter(variable, it) } } } - return filteredVariables; } - fun getProcessInstances(perPage: Int, page: Int, stateIn: List, variables: List?): List { - if(!variables.isNullOrEmpty()) { - val filteredVariables = getVariables(stateIn, variables); + + fun getProcessInstances(perPage: Int, page: Int, stateIn: List, variableFilterGroup: VariableFilterGroup?): List { + if (variableFilterGroup?.variables?.isNotEmpty() == true) { + val filteredVariables = getVariables(stateIn, variableFilterGroup); val filteredProcessInstances = processInstancesRepository.findByStateInAndKeyIn(stateIn, filteredVariables.map { it.processInstanceKey }, PageRequest.of(page, perPage)).toList(); return filteredProcessInstances; } @@ -49,9 +56,9 @@ class ProcessInstanceService( } } - fun countProcessInstances(stateIn: List, variables: List?): Long { - if(!variables.isNullOrEmpty()) { - val filteredVariables = getVariables(stateIn, variables); + fun countProcessInstances(stateIn: List, variableFilterGroup: VariableFilterGroup?): Long { + if (variableFilterGroup?.variables?.isNotEmpty() == true) { + val filteredVariables = getVariables(stateIn, variableFilterGroup); return filteredVariables.count().toLong(); } @@ -61,9 +68,9 @@ class ProcessInstanceService( } - fun getProcessInstances(perPage: Int, page: Int, stateIn: List, processDefinitionKey: Long, variables: List?): List { - if(!variables.isNullOrEmpty()) { - val filteredVariables = getVariables(stateIn, processDefinitionKey, variables); + fun getProcessInstances(perPage: Int, page: Int, stateIn: List, processDefinitionKey: Long, variableFilterGroup: VariableFilterGroup?): List { + if (variableFilterGroup?.variables?.isNotEmpty() == true) { + val filteredVariables = getVariables(stateIn, processDefinitionKey, variableFilterGroup); val filteredProcessInstances = processInstancesRepository.findByStateInAndKeyIn(stateIn, filteredVariables.map { it.processInstanceKey }, PageRequest.of(page, perPage)).toList(); return filteredProcessInstances; } @@ -72,9 +79,9 @@ class ProcessInstanceService( } } - fun countProcessInstances(stateIn: List, processDefinitionKey: Long, variables: List?): Long { - if(!variables.isNullOrEmpty()) { - val filteredVariables = getVariables(stateIn, processDefinitionKey, variables); + fun countProcessInstances(stateIn: List, processDefinitionKey: Long, variableFilterGroup: VariableFilterGroup?): Long { + if (variableFilterGroup?.variables?.isNotEmpty() == true) { + val filteredVariables = getVariables(stateIn, processDefinitionKey, variableFilterGroup); return filteredVariables.count().toLong(); } diff --git a/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/query/ProcessInstanceQueryResolver.kt b/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/query/ProcessInstanceQueryResolver.kt index 4b7af6c..10679ef 100644 --- a/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/query/ProcessInstanceQueryResolver.kt +++ b/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/query/ProcessInstanceQueryResolver.kt @@ -2,7 +2,7 @@ package io.zeebe.zeeqs.graphql.resolvers.query import io.zeebe.zeeqs.data.entity.ProcessInstance import io.zeebe.zeeqs.data.entity.ProcessInstanceState -import io.zeebe.zeeqs.data.entity.VariableFilter +import io.zeebe.zeeqs.data.entity.VariableFilterGroup import io.zeebe.zeeqs.data.repository.ProcessInstanceRepository import io.zeebe.zeeqs.data.service.ProcessInstanceService import io.zeebe.zeeqs.graphql.resolvers.connection.ProcessInstanceConnection @@ -23,11 +23,11 @@ class ProcessInstanceQueryResolver( @Argument perPage: Int, @Argument page: Int, @Argument stateIn: List, - @Argument variables: List? + @Argument variablesFilter: VariableFilterGroup? ): ProcessInstanceConnection { return ProcessInstanceConnection( - getItems = { processInstanceService.getProcessInstances(perPage, page, stateIn, variables) }, - getCount = { processInstanceService.countProcessInstances(stateIn, variables) } + getItems = { processInstanceService.getProcessInstances(perPage, page, stateIn, variablesFilter) }, + getCount = { processInstanceService.countProcessInstances(stateIn, variablesFilter) } ) } diff --git a/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/ProcessResolver.kt b/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/ProcessResolver.kt index 1a28c8e..c57a7eb 100644 --- a/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/ProcessResolver.kt +++ b/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/ProcessResolver.kt @@ -30,7 +30,7 @@ class ProcessResolver( @Argument perPage: Int, @Argument page: Int, @Argument stateIn: List, - @Argument variables: List? + @Argument variablesFilter: VariableFilterGroup? ): ProcessInstanceConnection { return ProcessInstanceConnection( getItems = { @@ -39,14 +39,14 @@ class ProcessResolver( page, stateIn, process.key, - variables + variablesFilter ).toList() }, getCount = { processInstanceService.countProcessInstances( stateIn, process.key, - variables + variablesFilter ) } ) diff --git a/graphql-api/src/main/resources/graphql/Process.graphqls b/graphql-api/src/main/resources/graphql/Process.graphqls index 78c65ba..0a9071e 100644 --- a/graphql-api/src/main/resources/graphql/Process.graphqls +++ b/graphql-api/src/main/resources/graphql/Process.graphqls @@ -14,7 +14,7 @@ type Process { perPage: Int = 10, page: Int = 0, stateIn: [ProcessInstanceState!] = [ACTIVATED, COMPLETED, TERMINATED] - variables: [VariableFilter] = null): ProcessInstanceConnection! + variablesFilter: VariableFilterGroup = null): ProcessInstanceConnection! # the scheduled timers of the timer start events of the process timers: [Timer!] # the opened message subscriptions of the message start events of the process diff --git a/graphql-api/src/main/resources/graphql/ProcessInstance.graphqls b/graphql-api/src/main/resources/graphql/ProcessInstance.graphqls index 470fede..de27d42 100644 --- a/graphql-api/src/main/resources/graphql/ProcessInstance.graphqls +++ b/graphql-api/src/main/resources/graphql/ProcessInstance.graphqls @@ -74,7 +74,7 @@ type Query { perPage: Int = 10, page: Int = 0, stateIn: [ProcessInstanceState!] = [ACTIVATED, COMPLETED, TERMINATED], - variables: [VariableFilter] = null + variablesFilter: VariableFilterGroup = null ): ProcessInstanceConnection! } diff --git a/graphql-api/src/main/resources/graphql/Variable.graphqls b/graphql-api/src/main/resources/graphql/Variable.graphqls index a6d467f..b2ff88a 100644 --- a/graphql-api/src/main/resources/graphql/Variable.graphqls +++ b/graphql-api/src/main/resources/graphql/Variable.graphqls @@ -18,11 +18,20 @@ type VariableUpdate { input VariableFilter { name: String!, value: String!, - equalityOperation: EqualityOperation = EQUALS + comparisonOperation: ComparisonOperation! } -# The type of a variable value filter -enum EqualityOperation { +input VariableFilterGroup { + variables: [VariableFilter!] + filterOperation: FilterOperation = OR +} + +enum ComparisonOperation { EQUALS, CONTAINS } + +enum FilterOperation { + AND, + OR +} \ No newline at end of file