diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/BpmnElementType.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/BpmnElementType.kt index 570be2e6..08ba6586 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/BpmnElementType.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/BpmnElementType.kt @@ -25,5 +25,6 @@ enum class BpmnElementType { BUSINESS_RULE_TASK, SCRIPT_TASK, SEND_TASK, - INCLUSIVE_GATEWAY + INCLUSIVE_GATEWAY, + GROUP } 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 new file mode 100644 index 00000000..4cfee606 --- /dev/null +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/entity/VariableFilter.kt @@ -0,0 +1,22 @@ +package io.zeebe.zeeqs.data.entity + +enum class ComparisonOperation { + EQUALS, + CONTAINS +} + +enum class FilterOperation { + AND, + OR +} + +class VariableFilter ( + val name: String, + val value: String, + 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/repository/ProcessInstanceRepository.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/ProcessInstanceRepository.kt index f9bcff71..95959bbc 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/ProcessInstanceRepository.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/ProcessInstanceRepository.kt @@ -6,17 +6,26 @@ import org.springframework.data.domain.Pageable import org.springframework.data.repository.PagingAndSortingRepository import org.springframework.stereotype.Repository +interface ProcessInstanceKeyOnly { + fun getKey(): Long +} + @Repository interface ProcessInstanceRepository : PagingAndSortingRepository { fun findByParentProcessInstanceKey(parentProcessInstanceKey: Long): List + fun findByProcessDefinitionKeyAndStateIn(processDefinitionKey: Long, stateIn: List): List + fun findByProcessDefinitionKeyAndStateIn(processDefinitionKey: Long, stateIn: List, pageable: Pageable): List fun countByProcessDefinitionKeyAndStateIn(processDefinitionKey: Long, stateIn: List): Long fun findByStateIn(stateIn: List, pageable: Pageable): List + fun findByStateIn(stateIn: List): List + fun countByStateIn(stateIn: List): Long + fun findByStateInAndKeyIn(stateIn: List, key: List, pageable: Pageable): List } \ No newline at end of file diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/VariableRepository.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/VariableRepository.kt index 5f9a315e..54107210 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/VariableRepository.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/repository/VariableRepository.kt @@ -13,4 +13,12 @@ interface VariableRepository : PagingAndSortingRepository { @Transactional(readOnly = true) fun findByScopeKey(scopeKey: Long): List + + @Transactional(readOnly = true) + fun findByProcessInstanceKeyInAndName(processInstanceKey: List, name: String): List + + + @Transactional(readOnly = true) + fun findByProcessInstanceKeyInAndNameIn(processInstanceKey: List, name: List): List + } \ No newline at end of file diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnElementInfo.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnElementInfo.kt index f3d786ea..1271be1f 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnElementInfo.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnElementInfo.kt @@ -6,5 +6,7 @@ data class BpmnElementInfo( val elementId: String, val elementName: String?, val elementType: BpmnElementType, - val metadata: BpmnElementMetadata + val metadata: BpmnElementMetadata, + val extensionElements: BpmnExtensionElements?, + val documentation: String? ) \ No newline at end of file diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnExtensionElements.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnExtensionElements.kt new file mode 100644 index 00000000..e216551a --- /dev/null +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/BpmnExtensionElements.kt @@ -0,0 +1,20 @@ +package io.zeebe.zeeqs.data.service + +data class BpmnExtensionProperty( + val name: String?, + val value: String? +) + +data class IoMapping ( + val source: String?, + val target: String? +) +data class ExtensionIoMapping( + val inputs: List? = emptyList(), + val outputs: List? = emptyList(), +) +data class BpmnExtensionElements( + val properties: List? = emptyList(), + val ioMapping: ExtensionIoMapping? = ExtensionIoMapping(), +) + 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 new file mode 100644 index 00000000..a8d24311 --- /dev/null +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessInstanceService.kt @@ -0,0 +1,93 @@ +package io.zeebe.zeeqs.data.service + +import io.zeebe.zeeqs.data.entity.* +import io.zeebe.zeeqs.data.repository.ProcessInstanceKeyOnly +import io.zeebe.zeeqs.data.repository.ProcessInstanceRepository +import io.zeebe.zeeqs.data.repository.VariableRepository +import org.springframework.data.domain.PageRequest +import org.springframework.stereotype.Component + +@Component +class ProcessInstanceService( + private val processInstancesRepository: ProcessInstanceRepository, + private val variableRepository: VariableRepository) { + + private fun getVariables(stateIn: List, variableFilterGroup: VariableFilterGroup): List { + val processInstances = processInstancesRepository.findByStateIn(stateIn).toList(); + return getVariablesByProcessInstanceKeys(processInstances, variableFilterGroup); + } + + private fun getVariables(stateIn: List, processDefinitionKey: Long, variableFilterGroup: VariableFilterGroup): List { + val processInstances = processInstancesRepository.findByProcessDefinitionKeyAndStateIn(processDefinitionKey, stateIn).toList(); + return getVariablesByProcessInstanceKeys(processInstances, variableFilterGroup); + + } + + 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 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) } + } + } + } + + + 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; + } + else { + return processInstancesRepository.findByStateIn(stateIn, PageRequest.of(page, perPage)).toList(); + } + } + + fun countProcessInstances(stateIn: List, variableFilterGroup: VariableFilterGroup?): Long { + if (variableFilterGroup?.variables?.isNotEmpty() == true) { + val filteredVariables = getVariables(stateIn, variableFilterGroup); + return filteredVariables.count().toLong(); + } + + else { + return processInstancesRepository.countByStateIn(stateIn); + } + } + + + 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; + } + else { + return processInstancesRepository.findByProcessDefinitionKeyAndStateIn(processDefinitionKey, stateIn, PageRequest.of(page, perPage)).toList(); + } + } + + fun countProcessInstances(stateIn: List, processDefinitionKey: Long, variableFilterGroup: VariableFilterGroup?): Long { + if (variableFilterGroup?.variables?.isNotEmpty() == true) { + val filteredVariables = getVariables(stateIn, processDefinitionKey, variableFilterGroup); + return filteredVariables.count().toLong(); + } + + else { + return processInstancesRepository.countByProcessDefinitionKeyAndStateIn(processDefinitionKey, stateIn); + } + } + +} \ No newline at end of file diff --git a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessService.kt b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessService.kt index 794a692f..49a2272c 100644 --- a/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessService.kt +++ b/data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessService.kt @@ -20,18 +20,28 @@ class ProcessService(val processRepository: ProcessRepository) { @Cacheable(cacheNames = ["bpmnElementInfo"]) fun getBpmnElementInfo(processDefinitionKey: Long): Map? { return getBpmnModel(processDefinitionKey) - ?.let { it.getModelElementsByType(FlowElement::class.java) } - ?.map { flowElement -> - Pair( - flowElement.id, BpmnElementInfo( - elementId = flowElement.id, - elementName = flowElement.name, - elementType = getBpmnElementType(flowElement), - metadata = getMetadata(flowElement) - ) - ) - } - ?.toMap() + ?.let { model -> + (model.getModelElementsByType(FlowElement::class.java)?.associate { flowElement -> + flowElement.id to BpmnElementInfo( + elementId = flowElement.id, + elementName = flowElement.name, + elementType = getBpmnElementType(flowElement), + metadata = getMetadata(flowElement), + extensionElements = getExtensionElements(flowElement), + documentation = getDocumentation(flowElement) + ) + }.orEmpty() + + model.getModelElementsByType(Group::class.java)?.associate { groupElement -> + groupElement.id to BpmnElementInfo( + elementId = groupElement.id, + elementName = groupElement.category?.value ?: "", + elementType = getBpmnElementType(groupElement), + metadata = getMetadata(groupElement), + extensionElements = getExtensionElements(groupElement), + documentation = getDocumentation(groupElement) + ) + }.orEmpty()) + } } private fun getBpmnModel(processDefinitionKey: Long): BpmnModelInstance? { @@ -41,7 +51,7 @@ class ProcessService(val processRepository: ProcessRepository) { ?.let { Bpmn.readModelFromStream(it) } } - private fun getBpmnElementType(element: FlowElement): BpmnElementType { + private fun getBpmnElementType(element: BaseElement): BpmnElementType { return when (element.elementType.typeName) { BpmnModelConstants.BPMN_ELEMENT_PROCESS -> BpmnElementType.PROCESS BpmnModelConstants.BPMN_ELEMENT_SUB_PROCESS -> getBpmnSubprocessType(element) @@ -63,11 +73,12 @@ class ProcessService(val processRepository: ProcessRepository) { BpmnModelConstants.BPMN_ELEMENT_BUSINESS_RULE_TASK -> BpmnElementType.BUSINESS_RULE_TASK BpmnModelConstants.BPMN_ELEMENT_SCRIPT_TASK -> BpmnElementType.SCRIPT_TASK BpmnModelConstants.BPMN_ELEMENT_INCLUSIVE_GATEWAY -> BpmnElementType.INCLUSIVE_GATEWAY + BpmnModelConstants.BPMN_ELEMENT_GROUP -> BpmnElementType.GROUP else -> BpmnElementType.UNKNOWN } } - private fun getBpmnSubprocessType(element: FlowElement) = + private fun getBpmnSubprocessType(element: BaseElement) = if (element is SubProcess) { if (element.triggeredByEvent()) { BpmnElementType.EVENT_SUB_PROCESS @@ -78,7 +89,7 @@ class ProcessService(val processRepository: ProcessRepository) { BpmnElementType.UNKNOWN } - private fun getMetadata(element: FlowElement): BpmnElementMetadata { + private fun getMetadata(element: BaseElement): BpmnElementMetadata { return BpmnElementMetadata( jobType = element .getSingleExtensionElement(ZeebeTaskDefinition::class.java) @@ -156,6 +167,41 @@ class ProcessService(val processRepository: ProcessRepository) { ) } + private fun getExtensionElements(element: BaseElement): BpmnExtensionElements { + + val properties = element.extensionElements?.elementsQuery + ?.filterByType(ZeebeProperties::class.java) + ?.findSingleResult() + ?.map { properties -> + properties.properties?.map { property -> + BpmnExtensionProperty(name = property.name, value = property.value) + } + } + ?.orElse(emptyList()) ?: emptyList() + + val ioMapping = element.extensionElements?.elementsQuery + ?.filterByType(ZeebeIoMapping::class.java) + ?.findSingleResult() + ?.map { mapping -> + ExtensionIoMapping( + inputs = mapping.inputs?.map { input -> + IoMapping(source = input.source, target = input.target) + } ?: emptyList(), + outputs = mapping.outputs?.map { output -> + IoMapping(source = output.source, target = output.target) + } ?: emptyList() + ) + } + ?.orElse(ExtensionIoMapping(inputs = emptyList(), outputs = emptyList())) ?: ExtensionIoMapping(inputs = emptyList(), outputs = emptyList()) + + return BpmnExtensionElements(properties = properties, ioMapping = ioMapping) + } + + + private fun getDocumentation(element: BaseElement): String { + return element.documentations.joinToString(separator = "") { it.textContent } + } + @Cacheable(cacheNames = ["userTaskForm"]) fun getForm(processDefinitionKey: Long, formKey: String): String? { return getBpmnModel(processDefinitionKey) diff --git a/data/src/test/kotlin/io/zeebe/zeeqs/ProcessServiceTest.kt b/data/src/test/kotlin/io/zeebe/zeeqs/ProcessServiceTest.kt index 337243b1..c6e0d7ee 100644 --- a/data/src/test/kotlin/io/zeebe/zeeqs/ProcessServiceTest.kt +++ b/data/src/test/kotlin/io/zeebe/zeeqs/ProcessServiceTest.kt @@ -12,7 +12,6 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.TestConfiguration import java.time.Instant @@ -52,12 +51,12 @@ class ProcessServiceTest( // then assertThat(info) .isNotNull() - .contains(entry("s", BpmnElementInfo("s", "start", BpmnElementType.START_EVENT, BpmnElementMetadata()))) - .contains(entry("t", BpmnElementInfo("t", "task", BpmnElementType.SERVICE_TASK, BpmnElementMetadata(jobType = "test")))) + .contains(entry("s", BpmnElementInfo("s", "start", BpmnElementType.START_EVENT, BpmnElementMetadata(), BpmnExtensionElements(properties = emptyList(), ioMapping = ExtensionIoMapping()), ""))) + .contains(entry("t", BpmnElementInfo("t", "task", BpmnElementType.SERVICE_TASK, BpmnElementMetadata(jobType = "test"), BpmnExtensionElements(properties = emptyList(), ioMapping = ExtensionIoMapping()), ""))) .contains(entry("u", BpmnElementInfo("u", "userTask", BpmnElementType.USER_TASK, BpmnElementMetadata( - userTaskAssignmentDefinition = UserTaskAssignmentDefinition(assignee = "user1", candidateGroups = "group1")))) + userTaskAssignmentDefinition = UserTaskAssignmentDefinition(assignee = "user1", candidateGroups = "group1")), BpmnExtensionElements(properties = emptyList(), ioMapping = ExtensionIoMapping()), "")) ) - .contains(entry("e", BpmnElementInfo("e", null, BpmnElementType.END_EVENT, BpmnElementMetadata()))) + .contains(entry("e", BpmnElementInfo("e", null, BpmnElementType.END_EVENT, BpmnElementMetadata(), BpmnExtensionElements(properties = emptyList(), ioMapping = ExtensionIoMapping()), ""))) } @Test @@ -90,7 +89,9 @@ class ProcessServiceTest( key = "camunda-forms:bpmn:form_A", resource = """{"x":1}""" ) - ) + ), + BpmnExtensionElements(properties = emptyList(), ioMapping = ExtensionIoMapping()), + "" ) ) } 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 7943c905..10679efc 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,9 @@ 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.VariableFilterGroup import io.zeebe.zeeqs.data.repository.ProcessInstanceRepository +import io.zeebe.zeeqs.data.service.ProcessInstanceService import io.zeebe.zeeqs.graphql.resolvers.connection.ProcessInstanceConnection import org.springframework.data.domain.PageRequest import org.springframework.data.repository.findByIdOrNull @@ -12,18 +14,20 @@ import org.springframework.stereotype.Controller @Controller class ProcessInstanceQueryResolver( - val processInstanceRepository: ProcessInstanceRepository + val processInstanceRepository: ProcessInstanceRepository, + val processInstanceService: ProcessInstanceService ) { @QueryMapping fun processInstances( @Argument perPage: Int, @Argument page: Int, - @Argument stateIn: List + @Argument stateIn: List, + @Argument variablesFilter: VariableFilterGroup? ): ProcessInstanceConnection { return ProcessInstanceConnection( - getItems = { processInstanceRepository.findByStateIn(stateIn, PageRequest.of(page, perPage)).toList() }, - getCount = { processInstanceRepository.countByStateIn(stateIn) } + 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/BpmnElementResolver.kt b/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/BpmnElementResolver.kt index b867d74b..ae445c1b 100644 --- a/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/BpmnElementResolver.kt +++ b/graphql-api/src/main/kotlin/io/zeebe/zeeqs/graphql/resolvers/type/BpmnElementResolver.kt @@ -5,9 +5,7 @@ import io.zeebe.zeeqs.data.entity.ElementInstanceState import io.zeebe.zeeqs.data.entity.Process import io.zeebe.zeeqs.data.repository.ElementInstanceRepository import io.zeebe.zeeqs.data.repository.ProcessRepository -import io.zeebe.zeeqs.data.service.BpmnElementInfo -import io.zeebe.zeeqs.data.service.BpmnElementMetadata -import io.zeebe.zeeqs.data.service.ProcessService +import io.zeebe.zeeqs.data.service.* import io.zeebe.zeeqs.graphql.resolvers.connection.ElementInstanceConnection import org.springframework.data.domain.PageRequest import org.springframework.data.repository.findByIdOrNull @@ -41,6 +39,21 @@ class BpmnElementResolver( ?: BpmnElementMetadata() } + + @SchemaMapping(typeName = "BpmnElement", field = "extensionElements") + fun extensionElements(element: BpmnElement): BpmnExtensionElements? { + return findElementInfo(element) + ?.extensionElements + } + + + @SchemaMapping(typeName = "BpmnElement", field = "documentation") + fun documentation(element: BpmnElement): String? { + return findElementInfo(element) + ?.documentation + + } + @SchemaMapping(typeName = "BpmnElement", field = "process") fun process(element: BpmnElement): Process? { return processRepository.findByIdOrNull(element.processDefinitionKey) 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 2a10a279..c57a7eba 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 @@ -6,6 +6,7 @@ import io.zeebe.zeeqs.data.repository.ProcessInstanceRepository import io.zeebe.zeeqs.data.repository.SignalSubscriptionRepository import io.zeebe.zeeqs.data.repository.TimerRepository import io.zeebe.zeeqs.data.service.BpmnElementInfo +import io.zeebe.zeeqs.data.service.ProcessInstanceService import io.zeebe.zeeqs.data.service.ProcessService import io.zeebe.zeeqs.graphql.resolvers.connection.ProcessInstanceConnection import org.springframework.data.domain.PageRequest @@ -19,6 +20,7 @@ class ProcessResolver( val timerRepository: TimerRepository, val messageSubscriptionRepository: MessageSubscriptionRepository, val processService: ProcessService, + val processInstanceService: ProcessInstanceService, private val signalSubscriptionRepository: SignalSubscriptionRepository ) { @@ -27,20 +29,24 @@ class ProcessResolver( process: Process, @Argument perPage: Int, @Argument page: Int, - @Argument stateIn: List + @Argument stateIn: List, + @Argument variablesFilter: VariableFilterGroup? ): ProcessInstanceConnection { return ProcessInstanceConnection( getItems = { - processInstanceRepository.findByProcessDefinitionKeyAndStateIn( - process.key, - stateIn, - PageRequest.of(page, perPage) + processInstanceService.getProcessInstances( + perPage, + page, + stateIn, + process.key, + variablesFilter ).toList() }, getCount = { - processInstanceRepository.countByProcessDefinitionKeyAndStateIn( - process.key, - stateIn + processInstanceService.countProcessInstances( + stateIn, + process.key, + variablesFilter ) } ) diff --git a/graphql-api/src/main/resources/graphql/Element.graphqls b/graphql-api/src/main/resources/graphql/Element.graphqls index 4e84b9e2..d6bb264f 100644 --- a/graphql-api/src/main/resources/graphql/Element.graphqls +++ b/graphql-api/src/main/resources/graphql/Element.graphqls @@ -10,6 +10,12 @@ type BpmnElement { # the metadata of the BPMN element metadata: BpmnElementMetadata! + # extension properties of the BPMN element + extensionElements: BpmnExtensionElements + + # documentation of the BPMN element + documentation: String + # the process that contains the BPMN element process: Process # the instances of the BPMN element @@ -46,6 +52,7 @@ enum BpmnElementType { SCRIPT_TASK SEND_TASK INCLUSIVE_GATEWAY + GROUP } # Additional metadata that are defined statically on the BPMN element. @@ -84,4 +91,24 @@ type UserTaskAssignmentDefinition { assignee: String # the candidate groups candidateGroups: String -} \ No newline at end of file +} + +type BpmnExtensionProperty { + name: String + value: String +} + +type IoMapping { + source: String + target: String +} + +type ExtensionIoMapping { + inputs: [IoMapping] + outputs: [IoMapping] +} + +type BpmnExtensionElements { + properties: [BpmnExtensionProperty] + ioMapping: ExtensionIoMapping +} diff --git a/graphql-api/src/main/resources/graphql/Process.graphqls b/graphql-api/src/main/resources/graphql/Process.graphqls index 24dd7c93..0a9071eb 100644 --- a/graphql-api/src/main/resources/graphql/Process.graphqls +++ b/graphql-api/src/main/resources/graphql/Process.graphqls @@ -13,7 +13,8 @@ type Process { processInstances( perPage: Int = 10, page: Int = 0, - stateIn: [ProcessInstanceState!] = [ACTIVATED, COMPLETED, TERMINATED]): ProcessInstanceConnection! + stateIn: [ProcessInstanceState!] = [ACTIVATED, COMPLETED, TERMINATED] + 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 acafefd8..de27d421 100644 --- a/graphql-api/src/main/resources/graphql/ProcessInstance.graphqls +++ b/graphql-api/src/main/resources/graphql/ProcessInstance.graphqls @@ -73,7 +73,8 @@ type Query { processInstances( perPage: Int = 10, page: Int = 0, - stateIn: [ProcessInstanceState!] = [ACTIVATED, COMPLETED, TERMINATED] + stateIn: [ProcessInstanceState!] = [ACTIVATED, COMPLETED, TERMINATED], + 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 29e38f97..b2ff88a1 100644 --- a/graphql-api/src/main/resources/graphql/Variable.graphqls +++ b/graphql-api/src/main/resources/graphql/Variable.graphqls @@ -14,3 +14,24 @@ type VariableUpdate { value: String! timestamp(zoneId: String = "Z"): String! } + +input VariableFilter { + name: String!, + value: String!, + comparisonOperation: ComparisonOperation! +} + +input VariableFilterGroup { + variables: [VariableFilter!] + filterOperation: FilterOperation = OR +} + +enum ComparisonOperation { + EQUALS, + CONTAINS +} + +enum FilterOperation { + AND, + OR +} \ No newline at end of file