diff --git a/.env.properties.example b/.env.properties.example index 12bfda7..0b0fd15 100644 --- a/.env.properties.example +++ b/.env.properties.example @@ -1,6 +1,6 @@ -SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:54320/valtimo +SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:54320/gzac SPRING_DATASOURCE_NAME=valtimo -SPRING_DATASOURCE_USERNAME=valtimo +SPRING_DATASOURCE_USERNAME=gzac SPRING_DATASOURCE_PASSWORD=password SPRING-ACTUATOR_PASSWORD=password SPRING_PROFILES_ACTIVE=localhost @@ -11,3 +11,4 @@ KEYCLOAK_AUTH-SERVER-URL=http://localhost:8081/auth KEYCLOAK_RESOURCE=valtimo-user-m2m-client KEYCLOAK_CREDENTIALS_SECRET=6ef6ca16-6b86-482a-a3d9-0561704c1db9 VALTIMO_CONNECTORENCRYPTION_SECRET=valtimo-connector-encryption-default-secret +REPO=valtimo-platform/config-poc-maarten \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index defb7be..cfee6b4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,6 +51,8 @@ dependencies { implementation("com.ritense.valtimo:openzaak") implementation("com.ritense.valtimo:zaken-api") + implementation("org.kohsuke:github-api:1.324") + implementation("org.postgresql:postgresql:42.7.3") if (System.getProperty("os.arch") == "aarch64") { diff --git a/gradle.properties b/gradle.properties index ab1edc6..8671486 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,4 +9,4 @@ spotlessVersion=6.23.3 ideaExt=1.1.7 org.gradle.jvmargs=-Xms128m -Xmx1024m -Duser.timezone=UTC org.gradle.welcome=never -valtimoVersion=12.2.1.RELEASE +valtimoVersion=12.4.0.poc-form-events.2-SNAPSHOT diff --git a/src/main/kotlin/com/ritense/valtimo/ApplicationReadyEventEventListener.kt b/src/main/kotlin/com/ritense/valtimo/ApplicationReadyEventEventListener.kt new file mode 100644 index 0000000..284795a --- /dev/null +++ b/src/main/kotlin/com/ritense/valtimo/ApplicationReadyEventEventListener.kt @@ -0,0 +1,155 @@ +package com.ritense.valtimo + +import com.ritense.authorization.AuthorizationContext +import com.ritense.document.domain.event.DocumentDefinitionDeployedEvent +import com.ritense.document.service.impl.JsonSchemaDocumentDefinitionService +import com.ritense.form.autodeployment.FormDefinitionDeploymentService +import com.ritense.form.domain.event.FormCreatedEvent +import com.ritense.form.domain.event.FormUpdatedEvent +import com.ritense.processdocument.service.ProcessDocumentDeploymentService +import com.ritense.valtimo.contract.utils.SecurityUtils +import com.ritense.valtimo.service.CamundaProcessService +import mu.KotlinLogging +import org.kohsuke.github.GHFileNotFoundException +import org.kohsuke.github.GHRepository +import org.kohsuke.github.GitHub +import org.kohsuke.github.GitHubBuilder +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.context.event.ApplicationReadyEvent +import org.springframework.context.event.EventListener +import org.springframework.stereotype.Service +import java.io.ByteArrayInputStream + +@Service +class ApplicationReadyEventEventListener( + val formDefinitionDeploymentService: FormDefinitionDeploymentService, + val jsonSchemaDocumentDefinitionService: JsonSchemaDocumentDefinitionService, + val processDocumentDeploymentService: ProcessDocumentDeploymentService, + val camundaProcessService: CamundaProcessService, + @Value("\${REPO}") val repo: String, + @Value("\${OAUTHTOKEN}") val oAuthToken: String +) { + + private val gitHub: GitHub = GitHubBuilder().withOAuthToken(oAuthToken).build() + private val repository: GHRepository = gitHub.getRepository(repo) + + @EventListener(FormCreatedEvent::class) + fun handle(event: FormCreatedEvent) { + logger.info { "FormCreatedEvent. $event" } + if (SecurityUtils.getCurrentUserLogin() != null) { + logger.info { "User created a new form" } + val filename = "resources/config/form/${event.formDefinition.name}.json" + repository.createContent() + .path(filename) + .content(event.formDefinition.formDefinition.toPrettyString()) + .message("Creating new form file via API, triggered by UI change") + .commit() + logger.info { "File created successfully." } + } + } + + @EventListener(FormUpdatedEvent::class) + fun handle(event: FormUpdatedEvent) { + logger.info { "FormUpdatedEvent. $event" } + if (SecurityUtils.getCurrentUserLogin() != null) { + logger.info { "User updated a form" } + val filename = "resources/config/form/${event.formDefinition.name}.json" + val existingFile = repository.getFileContent(filename) + existingFile.update( + event.formDefinition.formDefinition.toPrettyString(), + "Updating form JSON file via API" + ) + logger.info { "File updated successfully." } + } + } + + @EventListener(DocumentDefinitionDeployedEvent::class) + fun handle(event: DocumentDefinitionDeployedEvent) { + logger.info { "DocumentDefinitionDeployedEvent. $event" } + if (SecurityUtils.getCurrentUserLogin() != null) { + logger.info { "User created a new document-definition" } + val filename = "resources/config/document/definition/${event.documentDefinition().id().name()}.json" + repository.createContent() + .path(filename) + .content(event.documentDefinition().schema().toPrettyString()) + .message("Creating new document-definition file via API, triggered by UI change") + .commit() + logger.info { "File created successfully." } + } + } + + @EventListener(ApplicationReadyEvent::class) + fun handle(event: ApplicationReadyEvent) { + + try { + val formDirectory = repository.getDirectoryContent("resources/config/form") + formDirectory.listIterator().forEach { + if (it.name != ".gitkeep") { + logger.info { "${it.name}" } + val form = repository.getFileContent(it.path) + logger.info { "File content ${form.content}" } + AuthorizationContext.runWithoutAuthorization { + formDefinitionDeploymentService.deploy(it.name.removeSuffix(".json"), form.content, false) + } + } + } + } catch (ex: GHFileNotFoundException) { + //ignore + } + + try { + val caseDefinitionDirectory = repository.getDirectoryContent("resources/config/document/definition") + caseDefinitionDirectory.listIterator().forEach { + if (it.name != ".gitkeep") { + val documentDefinition = repository.getFileContent(it.path) + logger.info { "${it.name}" } + logger.info { "File content ${documentDefinition.content}" } + AuthorizationContext.runWithoutAuthorization { + jsonSchemaDocumentDefinitionService.deploy(documentDefinition.content) + } + } + } + } catch (ex: GHFileNotFoundException) { + //ignore + } + + try { + val bpmnDirectory = repository.getDirectoryContent("resources/bpmn") + bpmnDirectory.listIterator().forEach { + if (it.name != ".gitkeep") { + val bpmn = repository.getFileContent(it.path) + logger.info { "${it.name}" } + logger.info { "File content ${bpmn.name}" } + AuthorizationContext.runWithoutAuthorization { + camundaProcessService.deploy(bpmn.name, ByteArrayInputStream(bpmn.content.encodeToByteArray())) + } + } + } + } catch (ex: GHFileNotFoundException) { + //ignore + } + + try { + val caseDefinitionLinkDirectory = repository.getDirectoryContent("resources/config/process-document-link") + caseDefinitionLinkDirectory.listIterator().forEach { + if (it.name != ".gitkeep") { + val caseDefinitionLink = repository.getFileContent(it.path) + logger.info { "${it.name}" } + logger.info { "File content ${caseDefinitionLink.content}" } + AuthorizationContext.runWithoutAuthorization { + processDocumentDeploymentService.deploy( + it.name.substringBefore("."), + caseDefinitionLink.content + ) + } + } + } + } catch (ex: GHFileNotFoundException) { + //ignore + } + } + + private companion object { + val logger = KotlinLogging.logger {} + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DigitaalKlantDossierPlugin.kt b/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DigitaalKlantDossierPlugin.kt deleted file mode 100644 index ad52a76..0000000 --- a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DigitaalKlantDossierPlugin.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.ritense.valtimo.digitaalklantdossierauthenticatie - -import com.ritense.plugin.annotation.Plugin -import com.ritense.plugin.annotation.PluginProperty -import java.net.URI - -@Plugin( - key = "digitaalklantdossier", - title = "Digitaal Klant Dossier", - description = "Connects to DKD via OpenTunnel", -) -class DigitaalKlantDossierPlugin { - @PluginProperty(key = "url", secret = false) - lateinit var url: URI - - @PluginProperty(key = "username", secret = false) - lateinit var username: String - - @PluginProperty(key = "password", secret = true) - lateinit var password: String -} \ No newline at end of file diff --git a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DigitaalKlantDossierPluginFactory.kt b/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DigitaalKlantDossierPluginFactory.kt deleted file mode 100644 index f7c6071..0000000 --- a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DigitaalKlantDossierPluginFactory.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.ritense.valtimo.digitaalklantdossierauthenticatie - -import com.ritense.plugin.PluginFactory -import com.ritense.plugin.service.PluginService - -class DigitaalKlantDossierPluginFactory( - pluginService: PluginService, -) : PluginFactory(pluginService) { - override fun create(): DigitaalKlantDossierPlugin = DigitaalKlantDossierPlugin() -} \ No newline at end of file diff --git a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DkdAuthenticationPluginDto.kt b/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DkdAuthenticationPluginDto.kt deleted file mode 100644 index 4a9426d..0000000 --- a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/DkdAuthenticationPluginDto.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.ritense.valtimo.digitaalklantdossierauthenticatie - -data class DkdAuthenticationPluginDto( - val url: String, - val username: String, - val password: String, -) \ No newline at end of file diff --git a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/autoconfigure/DigitaalKlantDossierAutoConfiguration.kt b/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/autoconfigure/DigitaalKlantDossierAutoConfiguration.kt deleted file mode 100644 index 27d2665..0000000 --- a/src/main/kotlin/com/ritense/valtimo/digitaalklantdossierauthenticatie/autoconfigure/DigitaalKlantDossierAutoConfiguration.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.ritense.valtimo.digitaalklantdossierauthenticatie.autoconfigure - -import com.ritense.plugin.service.PluginService -import com.ritense.valtimo.digitaalklantdossierauthenticatie.DigitaalKlantDossierPluginFactory -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -internal class DigitaalKlantDossierAutoConfiguration { - @Bean - fun digitaalKlantDossierPluginFactory(pluginService: PluginService): DigitaalKlantDossierPluginFactory = - DigitaalKlantDossierPluginFactory( - pluginService = pluginService, - ) -} \ No newline at end of file