Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get user tasks forms as metadata #314

Merged
merged 2 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions data/src/main/kotlin/io/zeebe/zeeqs/data/entity/UserTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ data class UserTask(
val elementInstanceKey: Long,
val assignee: String?,
val candidateGroups: String?,
val formKey: String?,
val isCamundaForm: Boolean
val formKey: String?
) {
@Enumerated(EnumType.STRING)
var state: UserTaskState = UserTaskState.CREATED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ data class BpmnElementMetadata(
val errorCode: String? = null,
val calledProcessId: String? = null,
val messageSubscriptionDefinition: MessageSubscriptionDefinition? = null,
val userTaskAssignmentDefinition: UserTaskAssignmentDefinition? = null
val userTaskAssignmentDefinition: UserTaskAssignmentDefinition? = null,
val userTaskForm: UserTaskForm? = null
)
25 changes: 23 additions & 2 deletions data/src/main/kotlin/io/zeebe/zeeqs/data/service/ProcessService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import io.camunda.zeebe.model.bpmn.instance.*
import io.camunda.zeebe.model.bpmn.instance.zeebe.*
import io.zeebe.zeeqs.data.entity.BpmnElementType
import io.zeebe.zeeqs.data.repository.ProcessRepository
import org.camunda.bpm.model.xml.ModelInstance
import org.springframework.cache.annotation.Cacheable
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Component

private const val CAMUNDA_FORM_KEY_PREFIX = "camunda-forms:bpmn:"

@Component
class ProcessService(val processRepository: ProcessRepository) {

Expand Down Expand Up @@ -126,15 +129,33 @@ class ProcessService(val processRepository: ProcessRepository) {
assignee = it.assignee,
candidateGroups = it.candidateGroups
)
},
userTaskForm = element
.getSingleExtensionElement(ZeebeFormDefinition::class.java)
?.formKey
?.let { formKey ->
UserTaskForm(
key = formKey,
resource = getForm(
model = element.modelInstance,
formKey = formKey
)
)
}
)
}

@Cacheable(cacheNames = ["userTaskForm"])
fun getForm(processDefinitionKey: Long, formKey: String): String? {
return getBpmnModel(processDefinitionKey)
?.getModelElementsByType(ZeebeUserTaskForm::class.java)
?.firstOrNull { it.id == formKey }
?.let { getForm(model = it, formKey = formKey) }
}

private fun getForm(model: ModelInstance, formKey: String): String? {
val normalizedFormKey = formKey.replace(CAMUNDA_FORM_KEY_PREFIX, "")

return model.getModelElementsByType(ZeebeUserTaskForm::class.java)
?.firstOrNull { it.id == normalizedFormKey }
?.textContent
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.zeebe.zeeqs.graphql.resolvers.type
package io.zeebe.zeeqs.data.service

data class UserTaskForm(
val key: String,
val resource: String?
)
)
110 changes: 69 additions & 41 deletions data/src/test/kotlin/io/zeebe/zeeqs/ProcessServiceTest.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package io.zeebe.zeeqs

import io.camunda.zeebe.model.bpmn.Bpmn
import io.camunda.zeebe.model.bpmn.BpmnModelInstance
import io.zeebe.zeeqs.data.entity.BpmnElementType
import io.zeebe.zeeqs.data.entity.Process
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.UserTaskAssignmentDefinition
import io.zeebe.zeeqs.data.service.*
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.entry
import org.junit.jupiter.api.BeforeEach
Expand Down Expand Up @@ -36,25 +34,16 @@ class ProcessServiceTest(
// given
val processDefinitionKey = 1L

val bpmn = Bpmn.createExecutableProcess("process")
.startEvent("s").name("start")
.serviceTask("t").name("task")
.zeebeJobType("test")
.userTask("u").name("userTask")
.zeebeAssignee("user1").zeebeCandidateGroups("group1")
.endEvent("e").name("")
.done()

processRepository.save(
Process(
key = processDefinitionKey,
bpmnProcessId = "process",
version = 1,
bpmnXML = Bpmn.convertToString(bpmn),
deployTime = Instant.now().toEpochMilli(),
resourceName = "process.bpmn",
checksum = "checksum"
)
createProcess(
processDefinitionKey = processDefinitionKey,
bpmn = Bpmn.createExecutableProcess("process")
.startEvent("s").name("start")
.serviceTask("t").name("task")
.zeebeJobType("test")
.userTask("u").name("userTask")
.zeebeAssignee("user1").zeebeCandidateGroups("group1")
.endEvent("e").name("")
.done()
)

// when
Expand All @@ -71,6 +60,41 @@ class ProcessServiceTest(
.contains(entry("e", BpmnElementInfo("e", null, BpmnElementType.END_EVENT, BpmnElementMetadata())))
}

@Test
fun `should return user task form`() {
// given
val processDefinitionKey = 1L

createProcess(
processDefinitionKey = processDefinitionKey,
bpmn = Bpmn.createExecutableProcess("process")
.startEvent()
.userTask("user_task_A").name("A")
.zeebeUserTaskForm("form_A", """{"x":1}""")
.done()
)

// when
val info = processService.getBpmnElementInfo(processDefinitionKey)!!

// then
assertThat(info["user_task_A"])
.isNotNull()
.isEqualTo(
BpmnElementInfo(
elementId = "user_task_A",
elementName = "A",
elementType = BpmnElementType.USER_TASK,
metadata = BpmnElementMetadata(
userTaskForm = UserTaskForm(
key = "camunda-forms:bpmn:form_A",
resource = """{"x":1}"""
)
)
)
)
}

@Test
fun `should return nothing if process does not exist`() {
// given
Expand All @@ -94,24 +118,14 @@ class ProcessServiceTest(

@BeforeEach
fun `store process`() {
val bpmn = Bpmn.createExecutableProcess("process")
.startEvent()
.userTask("A")
.zeebeUserTaskForm(formKey, userForm)
.endEvent()
.done()

processRepository.save(
Process(
key = processDefinitionKey,
bpmnProcessId = "process",
version = 1,
bpmnXML = Bpmn.convertToString(bpmn),
deployTime = Instant.now().toEpochMilli(),
resourceName = "process.bpmn",
checksum = "checksum"
)
)
createProcess(
processDefinitionKey = 1L,
bpmn = Bpmn.createExecutableProcess("process")
.startEvent()
.userTask("A")
.zeebeUserTaskForm(formKey, userForm)
.endEvent()
.done())
}

@Test
Expand Down Expand Up @@ -150,4 +164,18 @@ class ProcessServiceTest(
}
}

private fun createProcess(processDefinitionKey: Long, bpmn: BpmnModelInstance?) {
processRepository.save(
Process(
key = processDefinitionKey,
bpmnProcessId = "process",
version = 1,
bpmnXML = Bpmn.convertToString(bpmn),
deployTime = Instant.now().toEpochMilli(),
resourceName = "process.bpmn",
checksum = "checksum"
)
)
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.zeebe.zeeqs.graphql.resolvers.type

import graphql.kickstart.tools.GraphQLResolver
import io.zeebe.zeeqs.data.entity.MessageSubscription
import io.zeebe.zeeqs.data.entity.Timer
import io.zeebe.zeeqs.data.entity.Process
import io.zeebe.zeeqs.data.entity.ProcessInstanceState
import io.zeebe.zeeqs.data.entity.*
import io.zeebe.zeeqs.data.repository.MessageSubscriptionRepository
import io.zeebe.zeeqs.data.repository.TimerRepository
import io.zeebe.zeeqs.data.repository.ProcessInstanceRepository
Expand Down Expand Up @@ -41,10 +38,11 @@ class ProcessResolver(
return messageSubscriptionRepository.findByProcessDefinitionKeyAndElementInstanceKeyIsNull(process.key)
}

fun elements(process: Process): List<BpmnElement> {
fun elements(process: Process, elementTypeIn: List<BpmnElementType>): List<BpmnElement> {
return processService
.getBpmnElementInfo(process.key)
?.values
?.filter { elementTypeIn.isEmpty() || elementTypeIn.contains(it.elementType) }
?.map { asBpmnElement(process, it) }
?: emptyList()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import graphql.kickstart.tools.GraphQLResolver
import io.zeebe.zeeqs.data.entity.ElementInstance
import io.zeebe.zeeqs.data.entity.ProcessInstance
import io.zeebe.zeeqs.data.entity.UserTask
import io.zeebe.zeeqs.data.service.UserTaskForm
import io.zeebe.zeeqs.data.repository.ElementInstanceRepository
import io.zeebe.zeeqs.data.repository.ProcessInstanceRepository
import io.zeebe.zeeqs.data.repository.UserTaskRepository
import io.zeebe.zeeqs.data.service.ProcessService
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Component
Expand Down Expand Up @@ -42,14 +42,10 @@ class UserTaskResolver(
return userTask.formKey?.let { formKey ->
UserTaskForm(
key = formKey,
resource = formKey
.takeIf { userTask.isCamundaForm }
?.let {
processService.getForm(
processDefinitionKey = userTask.processDefinitionKey,
formKey = formKey
)
}
resource = processService.getForm(
processDefinitionKey = userTask.processDefinitionKey,
formKey = formKey
)
)
}
}
Expand Down
4 changes: 3 additions & 1 deletion graphql-api/src/main/resources/graphql/Element.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ type BpmnElementMetadata {
calledProcessId: String
# the definition of the message subscription if the element is a message catch event
messageSubscriptionDefinition: MessageSubscriptionDefinition
# the assignment definition if the element is an user task
# the assignment definition if the element is a user task
userTaskAssignmentDefinition: UserTaskAssignmentDefinition
# the user form if the element is a user task
userTaskForm: UserTaskForm
}

# The definition of a message subscription from a BPMN element.
Expand Down
5 changes: 4 additions & 1 deletion graphql-api/src/main/resources/graphql/Process.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ type Process {
# the opened message subscriptions of the message start events of the process
messageSubscriptions: [MessageSubscription!]
# all BPMN elements of the process
elements: [BpmnElement!]
elements(
# Filter the BPMN elements by the given types. If empty, return all elements.
elementTypeIn: [BpmnElementType!] = []
): [BpmnElement!]
# BPMN element of the process by its id
element(elementId: String): BpmnElement
}
Expand Down
Loading