Skip to content

Commit

Permalink
Merge branch 'release/0.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
jangalinski committed Sep 14, 2022
2 parents 4caf009 + 8cbf997 commit ee5459d
Show file tree
Hide file tree
Showing 20 changed files with 377 additions and 71 deletions.
Binary file added .docs/admin-process-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .docs/admin-process-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .docs/admin-process-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 38 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,58 @@
# camunda-admin-process-registry

Template repository for usage in organizations: toolisticon, holunda-io, holixon...
Run administration tasks directly from the camunda 7 cockpit using generated mini-processes.

[![incubating](https://img.shields.io/badge/lifecycle-INCUBATING-orange.svg)](https://github.com/holisticon#open-source-lifecycle)
[![Build Status](https://github.com/holunda-io/camunda-admin-process-registry/workflows/Development%20branches/badge.svg)](https://github.com/holunda-io/camunda-admin-process-registry/actions)
[![sponsored](https://img.shields.io/badge/sponsoredBy-Holisticon-RED.svg)](https://holisticon.de/)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.holunda/camunda-admin-process-registry/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.holunda/camunda-admin-process-registry)
![Compatible with: Camunda Platform 7](https://img.shields.io/badge/Compatible%20with-Camunda%20Platform%207-26d07c)

This repository is a **template repository** designed to be a template for the next project.
This lib/spring-boot-auto-config allows you to easily and fast generate and deploy single-service-task processes that can e started from the camunda-webapp/tasklist.

## How to use
Doing so enables you to implement administration/house-keeping jobs as a process, use camundas form/ui and run tasks controlled with the full power of the engine cockpit, including error handling and analysis.

* create a new repo on github (can be in any organization). Choose this project as template repository. Copy all branches, so the `master`exists in your repo (for the github actions)
* on the command line: clone your new repo locally
* in the `setup.sh` script: set your organization, repository and base package
* run the `setup.sh` script, all placeholders are filled with your information
* delete the setup-script
* Update the `README.md`
* in the `developers` section of the `pom.xml`: mention yourself ... it is your project.
## How does it work

## Things to change after usage of template
Once you included the lib in your camunda spring boot application, create an [AdminProcess](src/main/kotlin/io/holunda/camunda/platform/adminprocess/AdminProcess.kt) bean like this:

To change the following values, modify the placeholders in `setup.sh` and run it.
This is a one-time operation, you can safely delete the `setup.sh` file afterwards.
```kotlin

Of course, you can also edit manually .... and do not forget to change this `README.md` with YOUR project specific information :-).
@Bean
fun helloWorldAdminProcess(): AdminProcess {
val foo = StringField("foo", "Foo - enter your name")
val date = DateField("date", "Date - select some magic")

### Maven pom.xml
return adminProcess(
activityId = "helloWorld",
label = "Hello World 2",
formFields = listOf(foo, date)
) {
val variables = CamundaBpmData.reader(it)

* Maven coordinates: `groupId`, `artifactId` and `version`
* Main description: `name`, `url`, `description`
* SCM: `connection`, `url`, `developerConnection`
logger.info { """ Hi, I am the process running with:
* foo: ${variables.get(foo)}
* date: ${variables.get(date)}
""".trimIndent()
}
}
}

```

### Issue Template
And you are done!

* correct the URL to repo
---

### Issue Labels
The generated model looks like this:

* Check the release-notes.yml for details, but create the following labels: Type: dependencies, Type: bug, Type: documentation, Type: question, Type: enhancement
![generated model](.docs/admin-process-3.png)

You can run the process in the webapp:

![start process](.docs/admin-process-1.png)

And fill out the form:

![fill out form](.docs/admin-process-2.png)

94 changes: 77 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>io.holunda</groupId>
<artifactId>camunda-admin-process-registry</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.1.0</version>
<name>${project.artifactId}</name>
<description>camunda-admin-process-registry</description>
<description>Register and run utility processes</description>
<url>https://github.com/holunda-io/camunda-admin-process-registry/</url>

<properties>
<project.encoding>UTF-8</project.encoding>
<project.build.sourceEncoding>${project.encoding}</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.encoding}</project.reporting.outputEncoding>

<kotlin.version>1.7.10</kotlin.version>
<java.version>11</java.version>
<kotlin-logging.version>2.1.23</kotlin-logging.version>

<spring-boot.version>2.7.3</spring-boot.version>
<camunda.version>7.17.0</camunda.version>
<camunda-data.version>1.2.7</camunda-data.version>

<!-- required for camunda with jdk >= 9 -->
<jaxb-impl.version>4.0.0</jaxb-impl.version>

<!-- TEST -->
<kotlin-logging.version>2.1.23</kotlin-logging.version>
<junit5.version>5.9.0</junit5.version>
<mockito.version>4.0.0</mockito.version>
<assertj.version>3.23.1</assertj.version>

<!-- MAVEN -->
<project.encoding>UTF-8</project.encoding>
<project.build.sourceEncoding>${project.encoding}</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.encoding}</project.reporting.outputEncoding>
</properties>

<dependencyManagement>
Expand All @@ -33,6 +41,22 @@
<scope>import</scope>
<type>pom</type>
</dependency>
<!-- CAMUNDA OFFICIAL -->
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-bom</artifactId>
<version>${camunda.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!-- SPRING -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
Expand All @@ -59,6 +83,18 @@
<version>${kotlin-logging.version}</version>
</dependency>

<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.holunda.data</groupId>
<artifactId>camunda-bpm-data</artifactId>
<version>${camunda-data.version}</version>
</dependency>

<!-- TEST -->
<dependency>
<groupId>org.mockito.kotlin</groupId>
Expand Down Expand Up @@ -87,6 +123,35 @@
<artifactId>kotlin-test-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.holunda</groupId>
<artifactId>camunda-platform-7-autologin</artifactId>
<version>0.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<scope>test</scope>
</dependency>

<!-- prior to jdk9 we have to include jaxb for camunda to work -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb-impl.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -204,16 +269,12 @@
<version>${kotlin.version}</version>
<configuration>
<jvmTarget>${java.version}</jvmTarget>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<!--<plugin>spring</plugin>-->
<!--plugin>jpa</plugin-->
<plugin>no-arg</plugin>
<plugin>all-open</plugin>
<plugin>spring</plugin>
</compilerPlugins>
<pluginOptions>
<!-- Each annotation is placed on its own line -->
<!-- <option>all-open:annotation=com.tngtech.jgiven.integration.spring.JGivenStage</option> -->
</pluginOptions>
</configuration>

<executions>
Expand All @@ -236,7 +297,6 @@
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
Expand Down
8 changes: 0 additions & 8 deletions src/main/kotlin/KotlinLibTemplate.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.holunda.camunda.platform.adminprocess

import org.camunda.bpm.engine.delegate.JavaDelegate
import org.camunda.bpm.model.bpmn.Bpmn
import org.camunda.bpm.model.bpmn.BpmnModelInstance
import org.camunda.bpm.model.bpmn.builder.StartEventBuilder


abstract class AdminProcess(
val activityId: String,
private val label: String = activityId,
private val formFields: List<FormField<*>>,
private val historyTimeToLive: Int = 0,
private val versionTag: String = "1"
) : JavaDelegate {

val processDefinitionKey = "admin_$activityId"
val processName = "[admin] $label"

val modelInstance: BpmnModelInstance by lazy {
Bpmn.createExecutableProcess(processDefinitionKey)
.name(processName)
.camundaHistoryTimeToLive(historyTimeToLive)
.camundaVersionTag(versionTag)
.camundaStartableInTasklist(true)
.startEvent()
.camundaFormFields(formFields)
.serviceTask(activityId)
.camundaAsyncBefore()
.name(label)
.camundaDelegateExpression("#{${AdminProcessRegistry.NAME}}")
.endEvent()
.done()
}

override fun toString(): String {
return "${this::class.simpleName ?: AdminProcess::class.simpleName}(activityName='$activityId', label='$label', processDefinitionKey='$processDefinitionKey', processName='$processName')"
}
}


fun StartEventBuilder.camundaFormFields(formFields: List<FormField<*>>): StartEventBuilder = formFields.fold(this) { builder, formField ->
builder.camundaFormField()
.camundaLabel(formField.label)
.camundaType(formField.type)
.camundaId(formField.id)
.camundaDefaultValue(formField.defaultValue?.toString())
.camundaFormFieldDone()
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.holunda.camunda.platform.adminprocess

import mu.KLogging
import org.camunda.bpm.engine.RepositoryService
import org.camunda.bpm.engine.delegate.DelegateExecution
import org.camunda.bpm.engine.delegate.JavaDelegate
import org.camunda.bpm.engine.repository.Deployment
import org.camunda.bpm.spring.boot.starter.event.PostDeployEvent
import org.springframework.context.event.EventListener


class AdminProcessRegistry(
private val processes: Map<ActivityId, AdminProcess>
) : JavaDelegate {
companion object : KLogging() {

const val NAME = "adminProcessRegistry"

/**
* Implementation of [AdminProcess] that does not get deployed and is only used as a fallback, when
* the engine tries to run an activity that is not registered.
*/
val WARN = CamundaAdminProcessRegistryLib.adminProcess("WARN") {
logger.warn { "no adminProcess registered with processDefinitionKey=${it.currentActivityId}" }
}

}

@EventListener
fun deploy(evt: PostDeployEvent) {
if (processes.isNotEmpty()) {
logger.info { "deploying admin processes: ${processes.values}" }
createDeployment(evt.processEngine.repositoryService)
} else
logger.info { "no admin processes registered - skip deployment." }
}

fun createDeployment(repositoryService: RepositoryService, tenantId: String? = NAME): Deployment =
processes.values.fold(repositoryService.createDeployment()) { builder, process ->
builder.addModelInstance(
"${process.processDefinitionKey}.bpmn",
process.modelInstance
)
}.tenantId(tenantId)
.enableDuplicateFiltering(true)
.deploy()

/**
* Delegates the execution to a registered admin process.
*/
override fun execute(execution: DelegateExecution): Unit = processes.getOrDefault(execution.currentActivityId, WARN).execute(execution)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.holunda.camunda.platform.adminprocess

import mu.KLogging
import org.camunda.bpm.engine.delegate.DelegateExecution
import org.camunda.bpm.engine.delegate.JavaDelegate
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import javax.annotation.PostConstruct

object CamundaAdminProcessRegistryLib {
fun adminProcess(
activityId: String,
label: String = activityId,
formFields: List<FormField<*>> = emptyList(),
historyTimeToLive: Int = 0,
versionTag: String = "1",
delegate: JavaDelegate
): AdminProcess = object : AdminProcess(activityId, label, formFields, historyTimeToLive, versionTag) {
override fun execute(execution: DelegateExecution) {
delegate.execute(execution)
}
}
}

@Configuration
class CamundaAdminProcessAutoConfiguration {
companion object : KLogging()

/**
* Collects all beans of type [AdminProcess] in context and registers them in a map.
*/
@Bean(AdminProcessRegistry.NAME)
fun adminProcessRegistry(
processes: List<AdminProcess>?
) = AdminProcessRegistry((processes?: emptyList()).associateBy { it.activityId })

}
Loading

0 comments on commit ee5459d

Please sign in to comment.