diff --git a/data-audit/.gitignore b/data-audit/.gitignore new file mode 100644 index 0000000000..a3191deafb --- /dev/null +++ b/data-audit/.gitignore @@ -0,0 +1,167 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + + +ObjectStore/ +PutObjectStoreDirHere/ + +# Created by https://www.gitignore.io/api/git,java,maven,eclipse,windows + +### Eclipse ### + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core +.project + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Annotation Processing +.apt_generated + +.sts4-cache/ + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + + +# End of https://www.gitignore.io/api/git,java,maven,eclipse,windows diff --git a/data-audit/README.md b/data-audit/README.md new file mode 100644 index 0000000000..e567bba444 --- /dev/null +++ b/data-audit/README.md @@ -0,0 +1,84 @@ +### Data Audit subsystem + +This is the implementation of the Kogito Audit subystem. The subsystem allows to store events from issued by +- process engine +- user task +- job service + +Main features are: + +- runs as colocated services with quarkus and springboot +- module to write your own subsystem +- graphql modules to query data +- extension points to develop new storage easily +- extension points to develop new queries extending graphql definitions + +## Design of the Data Audit + +The system contains several modules and common modules to redistribute responsabilities. + +![Data Audit Architecture](img/design.png "Data Audit Architecture") + +Data Audit Common: Provides the common framework to create implementations. +Data Audit «Quarkus»: Provides the wiring to use Data Audit with Quarkus as colocated service (deployment) +Data Audit «SpringBoot»: Provides the wiring to use Data Audit with SpringBoot as colocated service (deployment) + +Now we have and implementation examples + + +Data Audit JPA Common: Provides the common exension not depending on the runtime +Data Audit JPA «Quarkus»: Provides the wiring between the specific implementation and Quarkus System +Data Audit JPA «SpringBoot»: Provides the wiring between the specific implementation and Springboot colocated system + + +## Queries + +The way to retrieve information from the data audit is using GraphQL. This way we can abstract how the information is retrieved and allow different needs depending on the user. + +## JPA implementation + +The jpa implementation allows you to store those events to be stored in a database. + +## Extension Points + +There are two different extensions. Those who belong to the runtime to wire things and those which does not depends on the runtime + +Extension points depending on the runtime is: +org.kie.kogito.app.audit.spi.DataAuditContextFactory: this allows creating the context needed by a particular implementation. + +Extension points not depending on the runtime: +org.kie.kogito.app.audit.spi.DataAuditStore: This is responsible to store the data in certain way +org.kie.kogito.app.audit.spi.GraphQLSchemaQuery: This is responsible to execute a GraphQL query +org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider: this allow the subsystem to identify additional queries provided by the end user + + +## How to use in with Quarkus/Springboot + +You need to add two different dependencies to your project. + + + org.kie.kogito + kogito-addons-data-audit- + ${version} + + + org.kie.kogito + kogito-addons-data-audit-jpa- + ${version} + + + + + +The first dependency is related how to you want to deploy it. In this case as collocated/embedded service +The second dependency is which implementation you want to use. + +Each implementation might require additional dependencies. In our case for using JPA implementation we might require driver + + + io.quarkus + quarkus-jdbc-h2 + + +No additional configuration is requires besides the default datasource use by the application already. + diff --git a/data-audit/data-audit-common-service/pom.xml b/data-audit/data-audit-common-service/pom.xml new file mode 100644 index 0000000000..07d8bfbb9f --- /dev/null +++ b/data-audit/data-audit-common-service/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + data-audit + org.kie.kogito + 999-SNAPSHOT + + + data-audit-common-service + + Kogito Apps :: Data Audit :: Service Common + + + UTF-8 + + + + + org.kie.kogito + kogito-events-core + + + org.kie.kogito + jobs-service-api + + + org.slf4j + slf4j-api + + + org.apache.kafka + kafka-clients + + + + + diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonJobDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonJobDataEventDeserializer.java new file mode 100644 index 0000000000..fde7cbc498 --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonJobDataEventDeserializer.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.json; + +import java.io.IOException; +import java.time.OffsetDateTime; + +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class JsonJobDataEventDeserializer extends StdDeserializer { + + private static final Logger LOGGER = LoggerFactory.getLogger(JsonJobDataEventDeserializer.class); + + private static final long serialVersionUID = 6152014726577574241L; + + public JsonJobDataEventDeserializer() { + this(null); + } + + public JsonJobDataEventDeserializer(Class vc) { + super(vc); + } + + @Override + public JobInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + LOGGER.debug("Deserialize process instance data event: {}", node); + + JobInstanceDataEvent event = new JobInstanceDataEvent( + node.has("type") ? node.get("type").asText() : null, + node.has("source") ? node.get("source").asText() : null, + node.has("data") ? node.get("data").binaryValue() : null, + node.has("kogitoprocinstanceid") ? node.get("kogitoprocinstanceid").asText() : null, + node.has("kogitorootprociid") ? node.get("kogitorootprociid").asText() : null, + node.has("kogitoprocid") ? node.get("kogitoprocid").asText() : null, + node.has("kogitorootprocid") ? node.get("kogitorootprocid").asText() : null, + node.has("kogitoidentity") ? node.get("kogitoidentity").asText() : null); + + event.setId(node.has("id") ? node.get("id").asText() : null); + event.setKogitoIdentity(node.has("kogitoidentity") ? node.get("kogitoidentity").asText() : null); + event.setTime(node.has("time") ? jp.getCodec().treeToValue(node.get("time"), OffsetDateTime.class) : null); + + return event; + } +} \ No newline at end of file diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java new file mode 100644 index 0000000000..a5801a763c --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.json; + +import java.io.IOException; + +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class JsonProcessInstanceDataEventDeserializer extends StdDeserializer> { + + private static final Logger LOGGER = LoggerFactory.getLogger(JsonProcessInstanceDataEventDeserializer.class); + + private static final long serialVersionUID = 6152014726577574241L; + + public JsonProcessInstanceDataEventDeserializer() { + this(null); + } + + public JsonProcessInstanceDataEventDeserializer(Class vc) { + super(vc); + } + + @Override + public ProcessInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + LOGGER.debug("Deserialize process instance data event: {}", node); + String type = node.get("type").asText(); + + switch (type) { + case "ProcessInstanceErrorDataEvent": + return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceErrorDataEvent.class); + case "ProcessInstanceNodeDataEvent": + return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceNodeDataEvent.class); + case "ProcessInstanceSLADataEvent": + return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceSLADataEvent.class); + case "ProcessInstanceStateDataEvent": + return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceStateDataEvent.class); + case "ProcessInstanceVariableDataEvent": + return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceVariableDataEvent.class); + default: + LOGGER.warn("Unknown type {} in json data {}", type, node); + return (ProcessInstanceDataEvent) jp.getCodec().treeToValue(node, ProcessInstanceDataEvent.class); + + } + } +} \ No newline at end of file diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java new file mode 100644 index 0000000000..e9d57f86c0 --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.json; + +import java.io.IOException; + +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class JsonUserTaskInstanceDataEventDeserializer extends StdDeserializer> { + + private static final Logger LOGGER = LoggerFactory.getLogger(JsonUserTaskInstanceDataEventDeserializer.class); + + private static final long serialVersionUID = -6626663191296012306L; + + public JsonUserTaskInstanceDataEventDeserializer() { + this(null); + } + + public JsonUserTaskInstanceDataEventDeserializer(Class vc) { + super(vc); + } + + @Override + public UserTaskInstanceDataEvent deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + LOGGER.debug("Deserialize user task instance data event: {}", node); + String type = node.get("type").asText(); + + switch (type) { + case "UserTaskInstanceAssignmentDataEvent": + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceAssignmentDataEvent.class); + case "UserTaskInstanceAttachmentDataEvent": + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceAttachmentDataEvent.class); + case "UserTaskInstanceCommentDataEvent": + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceCommentDataEvent.class); + case "UserTaskInstanceDeadlineDataEvent": + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceDeadlineDataEvent.class); + case "UserTaskInstanceStateDataEvent": + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceStateDataEvent.class); + case "UserTaskInstanceVariableDataEvent": + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceVariableDataEvent.class); + default: + LOGGER.warn("Unknown type {} in json data {}", type, node); + return (UserTaskInstanceDataEvent) jp.getCodec().treeToValue(node, UserTaskInstanceDataEvent.class); + + } + } +} \ No newline at end of file diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java new file mode 100644 index 0000000000..52ece97fd5 --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.json; + +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import io.cloudevents.jackson.JsonFormat; + +public final class JsonUtils { + + private static final ObjectMapper MAPPER = configure(new ObjectMapper()); + + private JsonUtils() { + } + + public static ObjectMapper getObjectMapper() { + return MAPPER; + } + + public static ObjectMapper configure(ObjectMapper objectMapper) { + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.registerModule(JsonFormat.getCloudEventJacksonModule()); + objectMapper.registerModule(new JavaTimeModule()); + + SimpleModule module = new SimpleModule("Kogito Cloud Events"); + module.addDeserializer(ProcessInstanceDataEvent.class, new JsonProcessInstanceDataEventDeserializer()); + module.addDeserializer(UserTaskInstanceDataEvent.class, new JsonUserTaskInstanceDataEventDeserializer()); + module.addDeserializer(JobInstanceDataEvent.class, new JsonJobDataEventDeserializer()); + objectMapper.registerModule(module); + return objectMapper; + } +} diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/JobDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/JobDataEventDeserializer.java new file mode 100644 index 0000000000..a9199851fc --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/JobDataEventDeserializer.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.kafka; + +import org.apache.kafka.common.serialization.Deserializer; +import org.kie.kogito.app.audit.json.JsonUtils; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class JobDataEventDeserializer implements Deserializer { + private static final Logger LOGGER = LoggerFactory.getLogger(JobDataEventDeserializer.class); + + @Override + public JobInstanceDataEvent deserialize(String topic, byte[] data) { + try { + return JsonUtils.getObjectMapper().readValue(new String(data), JobInstanceDataEvent.class); + } catch (JsonProcessingException e) { + LOGGER.error("not possible to deserialize JobInstanceDataEvent data {}", new String(data), e); + throw new IllegalArgumentException("not possible to deserialize data"); + } + + } + +} diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/ProcessInstanceDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/ProcessInstanceDataEventDeserializer.java new file mode 100644 index 0000000000..01116805cf --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/ProcessInstanceDataEventDeserializer.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.kafka; + +import org.apache.kafka.common.serialization.Deserializer; +import org.kie.kogito.app.audit.json.JsonUtils; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class ProcessInstanceDataEventDeserializer implements Deserializer> { + private static final Logger LOGGER = LoggerFactory.getLogger(ProcessInstanceDataEventDeserializer.class); + + @Override + public ProcessInstanceDataEvent deserialize(String topic, byte[] data) { + try { + return JsonUtils.getObjectMapper().readValue(new String(data), ProcessInstanceDataEvent.class); + } catch (JsonProcessingException e) { + LOGGER.error("not possible to deserialize ProcessInstanceDataEvent data {}", new String(data), e); + throw new IllegalArgumentException("not possible to deserialize data"); + } + + } + +} diff --git a/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/UserTaskInstanceDataEventDeserializer.java b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/UserTaskInstanceDataEventDeserializer.java new file mode 100644 index 0000000000..394316ca83 --- /dev/null +++ b/data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/UserTaskInstanceDataEventDeserializer.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.kafka; + +import org.apache.kafka.common.serialization.Deserializer; +import org.kie.kogito.app.audit.json.JsonUtils; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class UserTaskInstanceDataEventDeserializer implements Deserializer> { + private static final Logger LOGGER = LoggerFactory.getLogger(UserTaskInstanceDataEventDeserializer.class); + + @Override + public UserTaskInstanceDataEvent deserialize(String topic, byte[] data) { + try { + return JsonUtils.getObjectMapper().readValue(new String(data), UserTaskInstanceDataEvent.class); + } catch (JsonProcessingException e) { + LOGGER.error("not possible to deserialize UserTaskInstanceDataEvent data {}", new String(data), e); + throw new IllegalArgumentException("not possible to deserialize data"); + } + + } + +} diff --git a/data-audit/data-audit-common/.gitignore b/data-audit/data-audit-common/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/data-audit/data-audit-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/data-audit/data-audit-common/pom.xml b/data-audit/data-audit-common/pom.xml new file mode 100644 index 0000000000..8a247b02eb --- /dev/null +++ b/data-audit/data-audit-common/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + org.kie.kogito + data-audit + 999-SNAPSHOT + + data-audit-common + Kogito Apps :: Data Audit :: Common + + 1.18 + + + + com.graphql-java + graphql-java-extended-scalars + + + com.graphql-java + graphql-java + + + org.kie.kogito + kogito-events-core + + + org.kie.kogito + jobs-service-api + + + org.kie.kogito + jobs-service-internal-api + + + org.slf4j + slf4j-api + + + diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditContext.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditContext.java new file mode 100644 index 0000000000..e98723782c --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditContext.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.api; + +public class DataAuditContext { + + private Object context; + + public DataAuditContext(Object context) { + this.context = context; + } + + public static DataAuditContext newDataAuditContext(Object context) { + return new DataAuditContext(context); + } + + @SuppressWarnings("unchecked") + public T getContext() { + return (T) context; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditQueryService.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditQueryService.java new file mode 100644 index 0000000000..fdcf3eaa66 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditQueryService.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.api; + +import java.util.Map; + +import org.kie.kogito.app.audit.graphql.GraphQLSchemaManager; + +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.schema.GraphQLSchema; + +import static java.util.Collections.emptyMap; +import static org.kie.kogito.app.audit.graphql.GraphQLSchemaManager.graphQLSchemaManagerInstance; + +public class DataAuditQueryService { + + private GraphQLSchemaManager graphQLManager; + private GraphQL graphQL; + + private DataAuditQueryService(GraphQLSchemaManager graphQLManager) { + this.graphQLManager = graphQLManager; + this.graphQL = GraphQL.newGraphQL(graphQLManager.getGraphQLSchema()).build(); + } + + public GraphQLSchema getGraphQLSchema() { + return this.graphQLManager.getGraphQLSchema(); + } + + public ExecutionResult executeQuery(DataAuditContext context, String query) { + return executeQuery(context, query, emptyMap()); + } + + public ExecutionResult executeQuery(String query) { + return executeQuery(null, query, emptyMap()); + } + + public ExecutionResult executeQuery(DataAuditContext context, String query, Map variables) { + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .localContext(context) + .query(query) + .variables(variables) + .build(); + + return graphQL.execute(executionInput); + } + + public static DataAuditQueryService newAuditQuerySerice() { + return new DataAuditQueryService(graphQLSchemaManagerInstance()); + } +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditStoreProxyService.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditStoreProxyService.java new file mode 100644 index 0000000000..6ab14c52d8 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditStoreProxyService.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.api; + +import java.util.ServiceLoader; + +import org.kie.kogito.app.audit.spi.DataAuditStore; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.kie.kogito.app.audit.api.TypeCheck.typeCheckOf; + +public class DataAuditStoreProxyService { + + private static final Logger LOGGER = LoggerFactory.getLogger(DataAuditStoreProxyService.class); + + private DataAuditStore auditStoreService; + + private DataAuditStoreProxyService(DataAuditStore auditStoreService) { + this.auditStoreService = auditStoreService; + } + + public void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceDataEvent event) { + + typeCheckOf(ProcessInstanceErrorDataEvent.class).ifType(context, event, auditStoreService::storeProcessInstanceDataEvent); + typeCheckOf(ProcessInstanceNodeDataEvent.class).ifType(context, event, auditStoreService::storeProcessInstanceDataEvent); + typeCheckOf(ProcessInstanceSLADataEvent.class).ifType(context, event, auditStoreService::storeProcessInstanceDataEvent); + typeCheckOf(ProcessInstanceStateDataEvent.class).ifType(context, event, auditStoreService::storeProcessInstanceDataEvent); + typeCheckOf(ProcessInstanceVariableDataEvent.class).ifType(context, event, auditStoreService::storeProcessInstanceDataEvent); + + } + + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceDataEvent event) { + + typeCheckOf(UserTaskInstanceAssignmentDataEvent.class).ifType(context, event, auditStoreService::storeUserTaskInstanceDataEvent); + typeCheckOf(UserTaskInstanceAttachmentDataEvent.class).ifType(context, event, auditStoreService::storeUserTaskInstanceDataEvent); + typeCheckOf(UserTaskInstanceCommentDataEvent.class).ifType(context, event, auditStoreService::storeUserTaskInstanceDataEvent); + typeCheckOf(UserTaskInstanceDeadlineDataEvent.class).ifType(context, event, auditStoreService::storeUserTaskInstanceDataEvent); + typeCheckOf(UserTaskInstanceStateDataEvent.class).ifType(context, event, auditStoreService::storeUserTaskInstanceDataEvent); + typeCheckOf(UserTaskInstanceVariableDataEvent.class).ifType(context, event, auditStoreService::storeUserTaskInstanceDataEvent); + + } + + public void storeJobDataEvent(DataAuditContext context, JobInstanceDataEvent event) { + auditStoreService.storeJobDataEvent(context, event); + + } + + public static DataAuditStoreProxyService newAuditStoreService() { + DataAuditStore service = ServiceLoader.load(DataAuditStore.class).findFirst().orElseThrow(() -> new RuntimeException("DataAuditStore implementation not found")); + LOGGER.debug("Creating new Data Audit Store proxy service with {}", service); + return new DataAuditStoreProxyService(service); + } +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/SubsystemConstants.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/SubsystemConstants.java new file mode 100644 index 0000000000..1f56dd2944 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/SubsystemConstants.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.api; + +public final class SubsystemConstants { + + private SubsystemConstants() { + // do nothing + } + + public static final String DATA_AUDIT_PATH = "/data-audit"; + + public static final String KOGITO_PROCESSINSTANCES_EVENTS = "kogito-processinstances-events"; + public static final String KOGITO_USERTASKINSTANCES_EVENTS = "kogito-usertaskinstances-events"; + public static final String KOGITO_JOBS_EVENTS = "kogito-jobs-events"; +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/TypeCheck.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/TypeCheck.java new file mode 100644 index 0000000000..6b85880ac9 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/TypeCheck.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.api; + +import java.util.function.BiConsumer; + +class TypeCheck { + + private Class clazz; + + public TypeCheck(Class clazz) { + this.clazz = clazz; + } + + public static TypeCheck typeCheckOf(Class clazz) { + return new TypeCheck(clazz); + } + + public void ifType(DataAuditContext context, Object event, BiConsumer executor) { + if (event != null && clazz.isInstance(event)) { + executor.accept(context, clazz.cast(event)); + } + } +} \ No newline at end of file diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/GraphQLSchemaManager.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/GraphQLSchemaManager.java new file mode 100644 index 0000000000..48b31dfef6 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/GraphQLSchemaManager.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.ServiceLoader; + +import org.kie.kogito.app.audit.spi.GraphQLSchemaQuery; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import graphql.language.FieldDefinition; +import graphql.language.ObjectTypeDefinition; +import graphql.scalars.ExtendedScalars; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring; + +public class GraphQLSchemaManager { + + private static final GraphQLSchemaManager INSTANCE = new GraphQLSchemaManager(); + + private static final Logger LOGGER = LoggerFactory.getLogger(GraphQLSchemaManager.class); + + private GraphQLSchema graphQLSchema; + + public static GraphQLSchemaManager graphQLSchemaManagerInstance() { + return INSTANCE; + } + + private GraphQLSchemaManager() { + + RuntimeWiring.Builder runtimeWiringBuilder = newRuntimeWiring(); + + runtimeWiringBuilder.scalar(ExtendedScalars.GraphQLBigInteger); + runtimeWiringBuilder.scalar(ExtendedScalars.GraphQLLong); + runtimeWiringBuilder.scalar(ExtendedScalars.Date); + runtimeWiringBuilder.scalar(ExtendedScalars.DateTime); + runtimeWiringBuilder.scalar(ExtendedScalars.Json); + + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + classLoader = (classLoader != null) ? classLoader : this.getClass().getClassLoader(); + + TypeDefinitionRegistry typeDefinitionRegistry = new TypeDefinitionRegistry(); + + List graphqlSchemas = new ArrayList<>(); + graphqlSchemas.addAll( + List.of("META-INF/data-audit-types.graphqls", + "META-INF/data-audit-job-query.graphqls", + "META-INF/data-audit-process-query.graphqls", + "META-INF/data-audit-usertask-query.graphqls")); + + ServiceLoader.load(GraphQLSchemaQueryProvider.class, classLoader).forEach(queryProvider -> { + graphqlSchemas.addAll(List.of(queryProvider.graphQLQueryExtension())); + for (GraphQLSchemaQuery query : queryProvider.queries()) { + runtimeWiringBuilder.type("Query", builder -> builder.dataFetcher(query.name(), query::fetch)); + } + }); + + // now we have all of definitions + List queryDefinitions = new ArrayList<>(); + for (String graphQLSchema : graphqlSchemas) { + TypeDefinitionRegistry newTypes = readDefintionRegistry(graphQLSchema); + + // for allowing extension of the schema we need to merge this object manually + // we remove it from the new Types and aggregate in temporal list so we can add this at the end + // of extension processing + Optional newDefinitions = newTypes.getType("Query", ObjectTypeDefinition.class); + if (newDefinitions.isPresent()) { + queryDefinitions.addAll(newDefinitions.get().getFieldDefinitions()); + newTypes.remove(newDefinitions.get()); + } + typeDefinitionRegistry.merge(newTypes); + } + + RuntimeWiring runtimeWiring = runtimeWiringBuilder.build(); + + SchemaGenerator schemaGenerator = new SchemaGenerator(); + // we merge the query object + typeDefinitionRegistry.add(ObjectTypeDefinition.newObjectTypeDefinition().name("Query").fieldDefinitions(queryDefinitions).build()); + graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); + + } + + private TypeDefinitionRegistry readDefintionRegistry(String graphQLSchema) { + try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(graphQLSchema)) { + SchemaParser schemaParser = new SchemaParser(); + return schemaParser.parse(is); + } catch (IOException e) { + LOGGER.error("could not find or process {}", graphQLSchema, e); + return new TypeDefinitionRegistry(); + } + } + + public GraphQLSchema getGraphQLSchema() { + return graphQLSchema; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JobExecutionTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JobExecutionTO.java new file mode 100644 index 0000000000..c8e649d73e --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JobExecutionTO.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class JobExecutionTO { + + private String jobId; + + private OffsetDateTime expirationTime; + + private Integer priority; + + private String processInstanceId; + + private String nodeInstanceId; + + private Long repeatInterval; + + private Integer repeatLimit; + + private String scheduledId; + + private Integer retries; + + private String status; + + private Integer executionCounter; + + private OffsetDateTime eventDate; + + public JobExecutionTO() { + + } + + public JobExecutionTO(String jobId, Date expirationtime, Integer priority, String processInstanceId, String nodeInstanceId, + Long repeatInterval, Integer repeatLimit, String scheduledId, Integer retries, String status, Integer executionCounter, Date eventDate) { + this.jobId = jobId; + this.expirationTime = OffsetDateTime.ofInstant(expirationtime.toInstant(), ZoneId.of("UTC")); + this.priority = priority; + this.processInstanceId = processInstanceId; + this.nodeInstanceId = nodeInstanceId; + this.repeatInterval = repeatInterval; + this.repeatLimit = repeatLimit; + this.scheduledId = scheduledId; + this.retries = retries; + this.status = status; + this.executionCounter = executionCounter; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + } + + public String getJobId() { + return jobId; + } + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + public OffsetDateTime getExpirationTime() { + return expirationTime; + } + + public void setExpirationTime(OffsetDateTime expirationTime) { + this.expirationTime = expirationTime; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getNodeInstanceId() { + return nodeInstanceId; + } + + public void setNodeInstanceId(String nodeInstanceId) { + this.nodeInstanceId = nodeInstanceId; + } + + public Long getRepeatInterval() { + return repeatInterval; + } + + public void setRepeatInterval(Long repeatInterval) { + this.repeatInterval = repeatInterval; + } + + public Integer getRepeatLimit() { + return repeatLimit; + } + + public void setRepeatLimit(Integer repeatLimit) { + this.repeatLimit = repeatLimit; + } + + public String getScheduledId() { + return scheduledId; + } + + public void setScheduledId(String scheduledId) { + this.scheduledId = scheduledId; + } + + public Integer getRetries() { + return retries; + } + + public void setRetries(Integer retries) { + this.retries = retries; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Integer getExecutionCounter() { + return executionCounter; + } + + public void setExecutionCounter(Integer executionCounter) { + this.executionCounter = executionCounter; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JsonUtil.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JsonUtil.java new file mode 100644 index 0000000000..5b07e6c708 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JsonUtil.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.NullNode; + +public class JsonUtil { + + public static JsonNode toJsonNode(String jsonString) { + try { + ObjectMapper mapper = new ObjectMapper(); + JsonFactory factory = mapper.getFactory(); + JsonParser parser = factory.createParser(jsonString); + return mapper.readTree(parser); + } catch (Exception e) { + return NullNode.getInstance(); + } + } +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceErrorTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceErrorTO.java new file mode 100644 index 0000000000..2f5fbe9110 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceErrorTO.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class ProcessInstanceErrorTO { + private String eventId; + + private OffsetDateTime eventDate; + + private String processType; + + private String processId; + + private String processVersion; + + private String parentProcessInstanceId; + + private String rootProcessId; + + private String rootProcessInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String errorMessage; + + private String nodeDefinitionId; + + private String nodeInstanceId; + + public ProcessInstanceErrorTO(String eventId, Date eventDate, String processType, String processId, + String processVersion, String parentProcessInstanceId, String rootProcessId, String rootProcessInstanceId, String processInstanceId, + String businessKey, String errorMessage, String nodeDefinitionId, String nodeInstanceId) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.processType = processType; + this.processId = processId; + this.processVersion = processVersion; + this.parentProcessInstanceId = parentProcessInstanceId; + this.rootProcessId = rootProcessId; + this.rootProcessInstanceId = rootProcessInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.errorMessage = errorMessage; + this.nodeDefinitionId = nodeDefinitionId; + this.nodeInstanceId = nodeInstanceId; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getProcessType() { + return processType; + } + + public void setProcessType(String processType) { + this.processType = processType; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getProcessVersion() { + return processVersion; + } + + public void setProcessVersion(String processVersion) { + this.processVersion = processVersion; + } + + public String getParentProcessInstanceId() { + return parentProcessInstanceId; + } + + public void setParentProcessInstanceId(String parentProcessInstanceId) { + this.parentProcessInstanceId = parentProcessInstanceId; + } + + public String getRootProcessId() { + return rootProcessId; + } + + public void setRootProcessId(String rootProcessId) { + this.rootProcessId = rootProcessId; + } + + public String getRootProcessInstanceId() { + return rootProcessInstanceId; + } + + public void setRootProcessInstanceId(String rootProcessInstanceId) { + this.rootProcessInstanceId = rootProcessInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getNodeDefinitionId() { + return nodeDefinitionId; + } + + public void setNodeDefinitionId(String nodeDefinitionId) { + this.nodeDefinitionId = nodeDefinitionId; + } + + public String getNodeInstanceId() { + return nodeInstanceId; + } + + public void setNodeInstanceId(String nodeInstanceId) { + this.nodeInstanceId = nodeInstanceId; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceNodeTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceNodeTO.java new file mode 100644 index 0000000000..85498672a9 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceNodeTO.java @@ -0,0 +1,232 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class ProcessInstanceNodeTO { + private String eventId; + + private OffsetDateTime eventDate; + + private String processType; + + private String processId; + + private String processVersion; + + private String parentProcessInstanceId; + + private String rootProcessId; + + private String rootProcessInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String eventType; + + private String nodeType; + + private String nodeName; + + private String nodeInstanceId; + + private String connection; + + private String workItemId; + + private OffsetDateTime slaDueDate; + + private Object eventData; + + public ProcessInstanceNodeTO(String eventId, Date eventDate, String processType, String processId, + String processVersion, String parentProcessInstanceId, String rootProcessId, String rootProcessInstanceId, String processInstanceId, + String businessKey, String eventType, String nodeType, + String nodeName, String nodeInstanceId, String connection, String workItemId, Date slaDueDate, String eventData) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.processType = processType; + this.processId = processId; + this.processVersion = processVersion; + this.parentProcessInstanceId = parentProcessInstanceId; + this.rootProcessId = rootProcessId; + this.rootProcessInstanceId = rootProcessInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.eventType = eventType; + this.nodeType = nodeType; + this.nodeName = nodeName; + this.nodeInstanceId = nodeInstanceId; + this.connection = connection; + this.workItemId = workItemId; + if (slaDueDate != null) { + this.slaDueDate = OffsetDateTime.ofInstant(slaDueDate.toInstant(), ZoneId.of("UTC")); + } + this.eventData = JsonUtil.toJsonNode(eventData); + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getProcessType() { + return processType; + } + + public void setProcessType(String processType) { + this.processType = processType; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getProcessVersion() { + return processVersion; + } + + public void setProcessVersion(String processVersion) { + this.processVersion = processVersion; + } + + public String getParentProcessInstanceId() { + return parentProcessInstanceId; + } + + public void setParentProcessInstanceId(String parentProcessInstanceId) { + this.parentProcessInstanceId = parentProcessInstanceId; + } + + public String getRootProcessId() { + return rootProcessId; + } + + public void setRootProcessId(String rootProcessId) { + this.rootProcessId = rootProcessId; + } + + public String getRootProcessInstanceId() { + return rootProcessInstanceId; + } + + public void setRootProcessInstanceId(String rootProcessInstanceId) { + this.rootProcessInstanceId = rootProcessInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getNodeInstanceId() { + return nodeInstanceId; + } + + public void setNodeInstanceId(String nodeInstanceId) { + this.nodeInstanceId = nodeInstanceId; + } + + public String getConnection() { + return connection; + } + + public void setConnection(String connection) { + this.connection = connection; + } + + public String getWorkItemId() { + return workItemId; + } + + public void setWorkItemId(String workItemId) { + this.workItemId = workItemId; + } + + public OffsetDateTime getSlaDueDate() { + return slaDueDate; + } + + public void setSlaDueDate(OffsetDateTime slaDueDate) { + this.slaDueDate = slaDueDate; + } + + public Object getEventData() { + return eventData; + } + + public void setEventData(Object eventData) { + this.eventData = eventData; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceStateTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceStateTO.java new file mode 100644 index 0000000000..c4fbbda6dd --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceStateTO.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +public class ProcessInstanceStateTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String processType; + + private String processId; + + private String processVersion; + + private String parentProcessInstanceId; + + private String rootProcessId; + + private String rootProcessInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String eventType; + + private String outcome; + + private String state; + + private OffsetDateTime slaDueDate; + + private Set roles; + + public ProcessInstanceStateTO() { + roles = new HashSet<>(); + } + + public ProcessInstanceStateTO(String eventId, Date eventDate, String processType, String processId, + String processVersion, String parentProcessInstanceId, String rootProcessId, String rootProcessInstanceId, String processInstanceId, + String businessKey, String eventType, String outcome, String state, Date slaDueDate) { + this(); + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.processType = processType; + this.processId = processId; + this.processVersion = processVersion; + this.parentProcessInstanceId = parentProcessInstanceId; + this.rootProcessId = rootProcessId; + this.rootProcessInstanceId = rootProcessInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.eventType = eventType; + this.outcome = outcome; + this.state = state; + if (slaDueDate != null) { + this.slaDueDate = OffsetDateTime.ofInstant(slaDueDate.toInstant(), ZoneId.of("UTC")); + } + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getProcessType() { + return processType; + } + + public void setProcessType(String processType) { + this.processType = processType; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getProcessVersion() { + return processVersion; + } + + public void setProcessVersion(String processVersion) { + this.processVersion = processVersion; + } + + public String getParentProcessInstanceId() { + return parentProcessInstanceId; + } + + public void setParentProcessInstanceId(String parentProcessInstanceId) { + this.parentProcessInstanceId = parentProcessInstanceId; + } + + public String getRootProcessId() { + return rootProcessId; + } + + public void setRootProcessId(String rootProcessId) { + this.rootProcessId = rootProcessId; + } + + public String getRootProcessInstanceId() { + return rootProcessInstanceId; + } + + public void setRootProcessInstanceId(String rootProcessInstanceId) { + this.rootProcessInstanceId = rootProcessInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getOutcome() { + return outcome; + } + + public void setOutcome(String outcome) { + this.outcome = outcome; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public OffsetDateTime getSlaDueDate() { + return slaDueDate; + } + + public void setSlaDueDate(OffsetDateTime slaDueDate) { + this.slaDueDate = slaDueDate; + } + + public void addRole(String role) { + this.roles.add(role); + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableHistoryTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableHistoryTO.java new file mode 100644 index 0000000000..b7470fccf8 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableHistoryTO.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import java.util.ArrayList; +import java.util.List; + +public class ProcessInstanceVariableHistoryTO { + + private String variableId; + + private String variableName; + + private List logs; + + public ProcessInstanceVariableHistoryTO() { + logs = new ArrayList<>(); + } + + public String getVariableId() { + return variableId; + } + + public void setVariableId(String variableId) { + this.variableId = variableId; + } + + public String getVariableName() { + return variableName; + } + + public void setVariableName(String variableName) { + this.variableName = variableName; + } + + public List getLogs() { + return logs; + } + + public void setLogs(List logs) { + this.logs = logs; + } + + public void addLog(ProcessInstanceVariableTO log) { + logs.add(log); + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableTO.java new file mode 100644 index 0000000000..4df0991a42 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableTO.java @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +import com.fasterxml.jackson.databind.JsonNode; + +public class ProcessInstanceVariableTO { + private String eventId; + + private OffsetDateTime eventDate; + + private String processType; + + private String processId; + + private String processVersion; + + private String parentProcessInstanceId; + + private String rootProcessId; + + private String rootProcessInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String variableId; + + private String variableName; + + private JsonNode variableValue; + + public ProcessInstanceVariableTO(String eventId, Date eventDate, String processType, String processId, + String processVersion, String parentProcessInstanceId, String rootProcessId, String rootProcessInstanceId, String processInstanceId, + String businessKey, String variableId, String variableName, String variableValue) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.processType = processType; + this.processId = processId; + this.processVersion = processVersion; + this.parentProcessInstanceId = parentProcessInstanceId; + this.rootProcessId = rootProcessId; + this.rootProcessInstanceId = rootProcessInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.variableId = variableId; + this.variableName = variableName; + this.variableValue = JsonUtil.toJsonNode(variableValue); + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getProcessType() { + return processType; + } + + public void setProcessType(String processType) { + this.processType = processType; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getProcessVersion() { + return processVersion; + } + + public void setProcessVersion(String processVersion) { + this.processVersion = processVersion; + } + + public String getParentProcessInstanceId() { + return parentProcessInstanceId; + } + + public void setParentProcessInstanceId(String parentProcessInstanceId) { + this.parentProcessInstanceId = parentProcessInstanceId; + } + + public String getRootProcessId() { + return rootProcessId; + } + + public void setRootProcessId(String rootProcessId) { + this.rootProcessId = rootProcessId; + } + + public String getRootProcessInstanceId() { + return rootProcessInstanceId; + } + + public void setRootProcessInstanceId(String rootProcessInstanceId) { + this.rootProcessInstanceId = rootProcessInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getVariableId() { + return variableId; + } + + public void setVariableId(String variableId) { + this.variableId = variableId; + } + + public String getVariableName() { + return variableName; + } + + public void setVariableName(String variableName) { + this.variableName = variableName; + } + + public JsonNode getVariableValue() { + return variableValue; + } + + public void setVariableValue(JsonNode variableValue) { + this.variableValue = variableValue; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAssignmentTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAssignmentTO.java new file mode 100644 index 0000000000..a9aaac5962 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAssignmentTO.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +public class UserTaskInstanceAssignmentTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String eventUser; + + private String userTaskDefinitionId; + + private String userTaskInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String userTaskName; + + private String assignmentType; + + private Set users; + + public UserTaskInstanceAssignmentTO() { + users = new HashSet<>(); + } + + public UserTaskInstanceAssignmentTO(String eventId, Date eventDate, String eventUser, String userTaskDefinitionId, String userTaskInstanceId, String processInstanceId, String businessKey, + String userTaskName, String assignmentType) { + this(); + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.eventUser = eventUser; + this.userTaskDefinitionId = userTaskDefinitionId; + this.userTaskInstanceId = userTaskInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.userTaskName = userTaskName; + this.assignmentType = assignmentType; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getEventUser() { + return eventUser; + } + + public void setEventUser(String eventUser) { + this.eventUser = eventUser; + } + + public String getUserTaskName() { + return userTaskName; + } + + public void setUserTaskName(String userTaskName) { + this.userTaskName = userTaskName; + } + + public String getAssignmentType() { + return assignmentType; + } + + public void setAssignmentType(String assignmentType) { + this.assignmentType = assignmentType; + } + + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public void addUser(String user) { + this.users.add(user); + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAttachmentTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAttachmentTO.java new file mode 100644 index 0000000000..a5dd338c0e --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAttachmentTO.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.graphql.type; + +import java.net.URI; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class UserTaskInstanceAttachmentTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String eventUser; + + private String userTaskDefinitionId; + + private String userTaskInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String attachmentId; + + private String attachmentName; + + private URI attachmentURI; + + private int eventType; + + public UserTaskInstanceAttachmentTO(String eventId, Date eventDate, String eventUser, String userTaskDefinitionId, String userTaskInstanceId, String processInstanceId, String businessKey, + String attachmentId, String attachmentName, String attachmentURI, Integer eventType) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.eventUser = eventUser; + this.userTaskDefinitionId = userTaskDefinitionId; + this.userTaskInstanceId = userTaskInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.attachmentId = attachmentId; + this.attachmentName = attachmentName; + if (attachmentURI != null) { + this.attachmentURI = URI.create(new String(attachmentURI)); + } + this.eventType = eventType; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getAttachmentId() { + return attachmentId; + } + + public void setAttachmentId(String attachmentId) { + this.attachmentId = attachmentId; + } + + public String getAttachmentName() { + return attachmentName; + } + + public void setAttachmentName(String attachmentName) { + this.attachmentName = attachmentName; + } + + public URI getAttachmentURI() { + return attachmentURI; + } + + public void setAttachmentURI(URI attachmentURI) { + this.attachmentURI = attachmentURI; + } + + public int getEventType() { + return eventType; + } + + public void setEventType(int eventType) { + this.eventType = eventType; + } + + public String getEventUser() { + return eventUser; + } + + public void setEventUser(String eventUser) { + this.eventUser = eventUser; + } +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceCommentTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceCommentTO.java new file mode 100644 index 0000000000..062880c506 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceCommentTO.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class UserTaskInstanceCommentTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String userTaskDefinitionId; + + private String userTaskInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String commentId; + + private String commentContent; + + private int eventType; + + public UserTaskInstanceCommentTO(String eventId, Date eventDate, String userTaskDefinitionId, String userTaskInstanceId, String processInstanceId, String businessKey, + String commentId, String commentContent, Integer eventType) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.userTaskDefinitionId = userTaskDefinitionId; + this.userTaskInstanceId = userTaskInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.commentId = commentId; + this.commentContent = commentContent; + this.eventType = eventType; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getCommentId() { + return commentId; + } + + public void setCommentId(String commentId) { + this.commentId = commentId; + } + + public String getCommentContent() { + return commentContent; + } + + public void setCommentContent(String commentContent) { + this.commentContent = commentContent; + } + + public int getEventType() { + return eventType; + } + + public void setEventType(int eventType) { + this.eventType = eventType; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceDeadlineTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceDeadlineTO.java new file mode 100644 index 0000000000..67281d8e01 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceDeadlineTO.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class UserTaskInstanceDeadlineTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String userTaskDefinitionId; + + private String userTaskInstanceId; + + private String processInstanceId; + + private String businessKey; + + private Map notification; + + private String eventType; + + public UserTaskInstanceDeadlineTO(String eventId, Date eventDate, String userTaskDefinitionId, String userTaskInstanceId, String processInstanceId, String businessKey, String eventType) { + this(); + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.userTaskDefinitionId = userTaskDefinitionId; + this.userTaskInstanceId = userTaskInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.eventType = eventType; + } + + public UserTaskInstanceDeadlineTO() { + this.notification = new HashMap<>(); + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public Map getNotification() { + return notification; + } + + public void setNotification(Map notification) { + this.notification = notification; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public void addNotification(String key, String value) { + notification.put(key, value); + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceStateTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceStateTO.java new file mode 100644 index 0000000000..67e88d46f2 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceStateTO.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class UserTaskInstanceStateTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String userTaskDefinitionId; + + private String userTaskInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String name; + + private String description; + + private String actualUser; + + private String state; + + private String eventType; + + public UserTaskInstanceStateTO(String eventId, Date eventDate, String userTaskDefinitionId, String userTaskInstanceId, String processInstanceId, String businessKey, + String name, String description, String actualUser, String state, String eventType) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.userTaskDefinitionId = userTaskDefinitionId; + this.userTaskInstanceId = userTaskInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.name = name; + this.description = description; + this.actualUser = actualUser; + this.state = state; + this.eventType = eventType; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getActualUser() { + return actualUser; + } + + public void setActualUser(String actualUser) { + this.actualUser = actualUser; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceVariableTO.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceVariableTO.java new file mode 100644 index 0000000000..b5f3e83e74 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceVariableTO.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.graphql.type; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; + +import com.fasterxml.jackson.databind.JsonNode; + +public class UserTaskInstanceVariableTO { + + private String eventId; + + private OffsetDateTime eventDate; + + private String userTaskDefinitionId; + + private String userTaskInstanceId; + + private String processInstanceId; + + private String businessKey; + + private String variableId; + + private String variableName; + + private JsonNode variableValue; + + private String variableType; + + public UserTaskInstanceVariableTO(String eventId, Date eventDate, String eventUser, String userTaskDefinitionId, String userTaskInstanceId, String processInstanceId, String businessKey, + String variableId, String variableName, String variableValue, String variableType) { + this.eventId = eventId; + this.eventDate = OffsetDateTime.ofInstant(eventDate.toInstant(), ZoneId.of("UTC")); + this.userTaskDefinitionId = userTaskDefinitionId; + this.userTaskInstanceId = userTaskInstanceId; + this.processInstanceId = processInstanceId; + this.businessKey = businessKey; + this.variableId = variableId; + this.variableName = variableName; + this.variableType = variableType; + this.variableValue = JsonUtil.toJsonNode(variableValue); + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public OffsetDateTime getEventDate() { + return eventDate; + } + + public void setEventDate(OffsetDateTime eventDate) { + this.eventDate = eventDate; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getVariableId() { + return variableId; + } + + public void setVariableId(String variableId) { + this.variableId = variableId; + } + + public String getVariableName() { + return variableName; + } + + public void setVariableName(String variableName) { + this.variableName = variableName; + } + + public JsonNode getVariableValue() { + return variableValue; + } + + public void setVariableValue(JsonNode variableValue) { + this.variableValue = variableValue; + } + + public String getVariableType() { + return variableType; + } + + public void setVariableType(String variableType) { + this.variableType = variableType; + } + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditContextFactory.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditContextFactory.java new file mode 100644 index 0000000000..256741ce38 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditContextFactory.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.spi; + +import org.kie.kogito.app.audit.api.DataAuditContext; + +public interface DataAuditContextFactory { + + DataAuditContext newDataAuditContext(); + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditStore.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditStore.java new file mode 100644 index 0000000000..46944cad86 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditStore.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.spi; + +import org.kie.kogito.app.audit.api.DataAuditContext; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; + +public interface DataAuditStore { + + void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceErrorDataEvent event); + + void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceNodeDataEvent event); + + void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceSLADataEvent event); + + void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceStateDataEvent event); + + void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceVariableDataEvent event); + + void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceAssignmentDataEvent event); + + void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceAttachmentDataEvent event); + + void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceCommentDataEvent event); + + void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceDeadlineDataEvent event); + + void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceStateDataEvent event); + + void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceVariableDataEvent event); + + void storeJobDataEvent(DataAuditContext context, JobInstanceDataEvent event); + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQuery.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQuery.java new file mode 100644 index 0000000000..c004a250af --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQuery.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.spi; + +import graphql.schema.DataFetchingEnvironment; + +public interface GraphQLSchemaQuery { + + String name(); + + Object fetch(DataFetchingEnvironment datafetchingenvironment); + +} diff --git a/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQueryProvider.java b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQueryProvider.java new file mode 100644 index 0000000000..7f04dcd6c4 --- /dev/null +++ b/data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQueryProvider.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.spi; + +import java.util.List; + +public interface GraphQLSchemaQueryProvider { + + default String[] graphQLQueryExtension() { + return new String[0]; + } + + List> queries(); + +} diff --git a/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-job-query.graphqls b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-job-query.graphqls new file mode 100644 index 0000000000..7251d7a01c --- /dev/null +++ b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-job-query.graphqls @@ -0,0 +1,21 @@ + +type Query { + GetAllScheduledJobs (pagination: Pagination): [JobExecutionLog] + + GetJobById (jobId : String!) : [JobExecutionLog] + GetJobByProcessInstanceId (processInstanceId : String!) : [JobExecutionLog] + + GetJobHistoryById (jobId : String!) : [JobExecutionLog] + GetJobHistoryByProcessInstanceId (processInstanceId : String!) : [JobExecutionLog] + + GetAllPendingJobs (pagination: Pagination): [JobExecutionLog] + GetAllEligibleJobsForExecution (pagination: Pagination) : [JobExecutionLog] + GetAllEligibleJobsForRetry (pagination: Pagination) : [JobExecutionLog] + GetAllJobs (pagination: Pagination) : [JobExecutionLog] + GetAllCompletedJobs (pagination: Pagination) : [JobExecutionLog] + GetAllInErrorJobs (pagination: Pagination) : [JobExecutionLog] + GetAllCancelledJobs (pagination: Pagination) : [JobExecutionLog] + GetAllJobsByStatus (status : [String]!, pagination: Pagination) : [JobExecutionLog] + +} + diff --git a/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-process-query.graphqls b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-process-query.graphqls new file mode 100644 index 0000000000..fd53c71668 --- /dev/null +++ b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-process-query.graphqls @@ -0,0 +1,15 @@ + +type Query { + + GetAllProcessInstancesState (pagination: Pagination): [ProcessInstanceStateLog] + GetAllProcessInstancesStateByStatus (status : String!, pagination: Pagination): [ProcessInstanceStateLog] + GetAllProcessInstancesStateByProcessId (processId : String!, pagination: Pagination): [ProcessInstanceStateLog] + GetProcessInstancesStateHistory (processInstanceId : String!, pagination: Pagination): [ProcessInstanceStateLog] + GetProcessInstancesStateHistoryByBusinessKey (businessKey : String!, pagination: Pagination): [ProcessInstanceStateLog] + + GetAllProcessInstancesNodeByProcessInstanceId (processInstanceId : String!, pagination: Pagination) : [ProcessInstanceNodeLog] + GetAllProcessInstancesErrorByProcessInstanceId (processInstanceId : String!, pagination: Pagination) : [ProcessInstanceErrorLog] + + GetAllProcessInstancesVariableByProcessInstanceId (processInstanceId : String!, pagination: Pagination) : [ProcessInstanceVariableLog] + GetAllProcessInstancesVariableHistoryByProcessInstanceId (processInstanceId : String!, pagination: Pagination) : [ProcessInstanceVariableHistoryLog] +} diff --git a/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-types.graphqls b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-types.graphqls new file mode 100644 index 0000000000..44220f21c6 --- /dev/null +++ b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-types.graphqls @@ -0,0 +1,183 @@ +scalar Long +scalar Int +scalar JSON +scalar DateTime +scalar Date + +type JobExecutionLog { + jobId : String! + expirationTime : DateTime + priority: Int + processInstanceId : String + nodeInstanceId : String + repeatInterval : Long + repeatLimit : Int + scheduledId : String + retries : Int + status : String + executionCounter : Int + eventDate : DateTime +} + +type ProcessInstanceStateLog { + eventId : String! + eventDate : DateTime + processType : String + processId : String + processVersion : String + parentProcessInstanceId : String + rootProcessId : String + rootProcessInstanceId : String + processInstanceId : String + businessKey : String + eventType : String + outcome : String + state : String + slaDueDate : DateTime + roles : [String] +} + +type ProcessInstanceNodeLog { + eventId : String! + eventDate : DateTime + processType : String + processId : String + processVersion : String + parentProcessInstanceId : String + rootProcessId : String + rootProcessInstanceId : String + processInstanceId : String + businessKey : String + eventType : String + nodeType : String + nodeName : String + nodeInstanceId : String + connection : String + workItemId : String + slaDueDate : DateTime + eventData : JSON +} + +type ProcessInstanceErrorLog { + eventId : String! + eventDate : DateTime + processType : String + processId : String + processVersion : String + parentProcessInstanceId : String + rootProcessId : String + rootProcessInstanceId : String + processInstanceId : String + businessKey : String + errorMessage : String + nodeDefinitionId : String + nodeInstanceId : String +} + +type ProcessInstanceVariableLog { + eventId : String + eventDate : DateTime + processType : String + processId : String + processVersion : String + parentProcessInstanceId : String + rootProcessId : String + rootProcessInstanceId : String + processInstanceId : String + businessKey : String + variableId : String + variableName : String + variableValue : JSON +} + +type ProcessInstanceVariableHistoryLog { + variableId : String! + variableName : String! + logs : [ProcessInstanceVariableLog] +} + +type UserTaskInstanceStateLog { + eventId : String! + eventDate : DateTime + userTaskDefinitionId : String + userTaskInstanceId : String + processInstanceId : String + businessKey : String + name : String + description : String + actualUser : String + state : String + slaDueDate : DateTime + eventType : String +} + +type UserTaskInstanceAssignmentLog { + eventId : String! + eventDate : DateTime + userTaskDefinitionId : String + userTaskInstanceId : String + processInstanceId : String + businessKey : String + userTaskName : String + assignmentType : String + users : [String] +} + +type UserTaskInstanceAttachmentLog { + eventId : String! + eventDate : DateTime + userTaskDefinitionId : String + userTaskInstanceId : String + processInstanceId : String + businessKey : String + attachmentId : String + attachmentName : String + attachmentURI : String + eventType : Int +} + +type UserTaskInstanceCommentLog { + eventId : String! + eventDate : DateTime + userTaskDefinitionId : String + userTaskInstanceId : String + processInstanceId : String + businessKey : String + commentId : String + commentContent : String + eventType : Int +} + +type UserTaskInstanceDeadlineLog { + eventId : String! + eventDate : DateTime + userTaskDefinitionId : String + userTaskInstanceId : String + processInstanceId : String + businessKey : String + eventType : String + notification : JSON +} + +type UserTaskInstanceVariableLog { + eventId : String! + eventDate : DateTime + userTaskDefinitionId : String + userTaskInstanceId : String + processInstanceId : String + businessKey : String + variableId : String + variableName : String + variableValue : JSON + variableType : String +} + +input Pagination { + limit: Int + offset: Int +} + + +schema { + query: Query +} diff --git a/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-usertask-query.graphqls b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-usertask-query.graphqls new file mode 100644 index 0000000000..98ac378344 --- /dev/null +++ b/data-audit/data-audit-common/src/main/resources/META-INF/data-audit-usertask-query.graphqls @@ -0,0 +1,8 @@ +type Query { + GetAllUserTaskInstanceState (pagination: Pagination) : [UserTaskInstanceStateLog] + GetAllUserTaskInstanceAssignments (userTaskInstanceId : String!, pagination: Pagination) : [UserTaskInstanceAssignmentLog] + GetAllUserTaskInstanceAttachments (userTaskInstanceId : String!, pagination: Pagination) : [UserTaskInstanceAttachmentLog] + GetAllUserTaskInstanceComments (userTaskInstanceId : String!, pagination: Pagination) : [UserTaskInstanceCommentLog] + GetAllUserTaskInstanceDeadlines (userTaskInstanceId : String!, pagination: Pagination) : [UserTaskInstanceDeadlineLog] + GetAllUserTaskInstanceVariables (userTaskInstanceId : String!, pagination: Pagination) : [UserTaskInstanceVariableLog] +} \ No newline at end of file diff --git a/data-audit/data-audit-quarkus-service/pom.xml b/data-audit/data-audit-quarkus-service/pom.xml new file mode 100644 index 0000000000..e8c773fe87 --- /dev/null +++ b/data-audit/data-audit-quarkus-service/pom.xml @@ -0,0 +1,110 @@ + + + 4.0.0 + + data-audit + org.kie.kogito + 999-SNAPSHOT + + + + data-audit-quarkus-service + + Kogito Apps :: Data Audit :: Quarkus :: Service + + + + UTF-8 + + + + + + org.kie.kogito + data-audit-common-service + + + org.kie.kogito + kogito-addons-data-audit-quarkus + + + org.kie.kogito + data-audit-common + + + org.kie.kogito + kogito-events-core + + + org.kie.kogito + jobs-service-api + + + org.slf4j + slf4j-api + + + + + + io.quarkus + quarkus-core + + + io.quarkus + quarkus-arc + + + + io.smallrye.reactive + smallrye-reactive-messaging-api + + + io.smallrye.reactive + smallrye-reactive-messaging-kafka + + + io.quarkus + quarkus-smallrye-metrics + + + org.apache.kafka + kafka-clients + + + + io.quarkus + quarkus-reactive-routes + + + io.quarkiverse.reactivemessaging.http + quarkus-reactive-messaging-http + + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + org.assertj + assertj-core + test + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + diff --git a/data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMain.java b/data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMain.java new file mode 100644 index 0000000000..aea424e516 --- /dev/null +++ b/data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMain.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import io.quarkus.runtime.Quarkus; +import io.quarkus.runtime.annotations.QuarkusMain; + +@QuarkusMain +public class QuarkusDataAuditMain { + + public static void main(String... args) { + Quarkus.run(args); + } +} \ No newline at end of file diff --git a/data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMessagingEventConsumer.java b/data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMessagingEventConsumer.java new file mode 100644 index 0000000000..38eddbd8d5 --- /dev/null +++ b/data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMessagingEventConsumer.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import org.eclipse.microprofile.reactive.messaging.Incoming; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.smallrye.common.annotation.Blocking; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; + +import static org.kie.kogito.app.audit.api.SubsystemConstants.KOGITO_JOBS_EVENTS; +import static org.kie.kogito.app.audit.api.SubsystemConstants.KOGITO_PROCESSINSTANCES_EVENTS; +import static org.kie.kogito.app.audit.api.SubsystemConstants.KOGITO_USERTASKINSTANCES_EVENTS; + +@ApplicationScoped +public class QuarkusDataAuditMessagingEventConsumer { + + private static final Logger LOGGER = LoggerFactory.getLogger(QuarkusDataAuditMessagingEventConsumer.class); + + @Inject + EventPublisher eventPublisher; + + @Incoming(KOGITO_PROCESSINSTANCES_EVENTS) + @Blocking + @Transactional + public void onProcessInstanceEvent(ProcessInstanceDataEvent event) { + LOGGER.debug("Process instance consumer received ProcessInstanceDataEvent: \n{}", event); + eventPublisher.publish(event); + } + + @Incoming(KOGITO_USERTASKINSTANCES_EVENTS) + @Blocking + @Transactional + public void onUserTaskInstanceEvent(UserTaskInstanceDataEvent event) { + LOGGER.debug("Task instance received UserTaskInstanceDataEvent \n{}", event); + eventPublisher.publish(event); + } + + @Incoming(KOGITO_JOBS_EVENTS) + @Blocking + @Transactional + public void onJobEvent(JobInstanceDataEvent event) { + LOGGER.debug("Job received KogitoJobCloudEvent \n{}", event); + eventPublisher.publish(event); + } + +} diff --git a/data-audit/data-audit-quarkus-service/src/main/resources/META-INF/beans.xml b/data-audit/data-audit-quarkus-service/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data-audit/data-audit-quarkus-service/src/main/resources/META-INF/microprofile-config.properties b/data-audit/data-audit-quarkus-service/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 0000000000..48bd13b8da --- /dev/null +++ b/data-audit/data-audit-quarkus-service/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Quarkus + +mp.messaging.incoming.kogito-processinstances-events.topic=kogito-processinstances-events +mp.messaging.incoming.kogito-processinstances-events.group.id=kogito-data-audit-processinstances +mp.messaging.incoming.kogito-processinstances-events.enable.auto.commit=false +mp.messaging.incoming.kogito-processinstances-events.auto.offset.reset=earliest +mp.messaging.incoming.kogito-processinstances-events.isolation.level=read_committed +mp.messaging.incoming.kogito-processinstances-events.connector=smallrye-kafka +mp.messaging.incoming.kogito-processinstances-events.value.deserializer=org.kie.kogito.app.audit.kafka.ProcessInstanceDataEventDeserializer + +mp.messaging.incoming.kogito-usertaskinstances-events.topic=kogito-usertaskinstances-events +mp.messaging.incoming.kogito-usertaskinstances-events.group.id=kogito-data-audit-usertaskinstances +mp.messaging.incoming.kogito-usertaskinstances-events.enable.auto.commit=false +mp.messaging.incoming.kogito-usertaskinstances-events.auto.offset.reset=earliest +mp.messaging.incoming.kogito-usertaskinstances-events.isolation.level=read_committed +mp.messaging.incoming.kogito-usertaskinstances-events.connector=smallrye-kafka +mp.messaging.incoming.kogito-usertaskinstances-events.value.deserializer=org.kie.kogito.app.audit.kafka.UserTaskInstanceDataEventDeserializer + +mp.messaging.incoming.kogito-jobs-events.topic=kogito-jobs-events +mp.messaging.incoming.kogito-jobs-events.group.id=kogito-data-audit-jobs +mp.messaging.incoming.kogito-jobs-events.enable.auto.commit=false +mp.messaging.incoming.kogito-jobs-events.auto.offset.reset=earliest +mp.messaging.incoming.kogito-jobs-events.isolation.level=read_committed +mp.messaging.incoming.kogito-jobs-events.connector=smallrye-kafka +mp.messaging.incoming.kogito-jobs-events.value.deserializer=org.kie.kogito.app.audit.kafka.JobDataEventDeserializer + diff --git a/data-audit/data-audit-quarkus-service/src/main/resources/application.properties b/data-audit/data-audit-quarkus-service/src/main/resources/application.properties new file mode 100644 index 0000000000..c674b7830a --- /dev/null +++ b/data-audit/data-audit-quarkus-service/src/main/resources/application.properties @@ -0,0 +1 @@ +kafka.bootstrap.servers=${QUARKUS_KAFKA_URL:localhost:9092} \ No newline at end of file diff --git a/data-audit/img/design.png b/data-audit/img/design.png new file mode 100644 index 0000000000..f12aafeac0 Binary files /dev/null and b/data-audit/img/design.png differ diff --git a/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/pom.xml b/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/pom.xml new file mode 100644 index 0000000000..0f7f031ef4 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + kogito-addons-data-audit-jpa + org.kie.kogito + 999-SNAPSHOT + + + data-audit-quarkus-jpa-service + + Kogito Apps :: Data Audit :: JPA :: Service + + + UTF-8 + + + + + org.kie.kogito + data-audit-quarkus-service + + + + org.kie.kogito + kogito-addons-data-audit-jpa-quarkus + + + + io.quarkus + quarkus-container-image-jib + + + + + + + io.quarkus + quarkus-maven-plugin + + true + + + + + build + + + + + + + diff --git a/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/META-INF/beans.xml b/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/application.properties b/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/application.properties new file mode 100644 index 0000000000..be277ecd5c --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/application.properties @@ -0,0 +1,13 @@ +#default values + +quarkus.datasource.db-kind=${QUARKUS_DATASOURCE_DB:h2} +quarkus.datasource.username=${QUARKUS_DATASOURCE_USER:kogito-user} +quarkus.datasource.password=${QUARKUS_DATASOURCE_PASS:kogito-pass} +quarkus.datasource.jdbc.url=${QUARKUS_DATASOURCE_JDBC_URL:jdbc:h2:mem:data-audit} + +quarkus.hibernate-orm.database.generation=update + +quarkus.container-image.build=${quarkus.build.image:true} +quarkus.container-image.group=org.kie.kogito +quarkus.jib.jvm-arguments=-Dquarkus.http.port=8080 +quarkus.container-image.name=data-audit-jpa-service \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/.gitignore b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/pom.xml b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/pom.xml new file mode 100644 index 0000000000..9c734aeac8 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + org.kie.kogito + kogito-addons-data-audit-jpa + 999-SNAPSHOT + + kogito-addons-data-audit-jpa-common + Kogito Apps :: Data Audit :: JPA :: Common + + + org.kie.kogito + kogito-events-core + + + org.kie.kogito + jobs-service-api + + + org.kie.kogito + data-audit-common + + + com.fasterxml.jackson.core + jackson-core + + + jakarta.persistence + jakarta.persistence-api + + + org.slf4j + slf4j-api + + + io.smallrye + jandex + + + + org.assertj + assertj-core + test + + + org.jboss.logmanager + jboss-logmanager + 3.0.2.Final + test + + + org.slf4j + slf4j-simple + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.junit.platform + junit-platform-suite + test + + + org.hibernate + hibernate-entitymanager + 5.6.12.Final + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + ${project.build.directory}/ObjectStore + + + + org.kie.kogito.app.audit:data-audit-service-tck + + + + + + diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/JPADataAuditStore.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/JPADataAuditStore.java new file mode 100644 index 0000000000..8d51e98583 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/JPADataAuditStore.java @@ -0,0 +1,400 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +import org.kie.kogito.app.audit.api.DataAuditContext; +import org.kie.kogito.app.audit.jpa.model.AbstractProcessInstanceLog; +import org.kie.kogito.app.audit.jpa.model.AbstractUserTaskInstanceLog; +import org.kie.kogito.app.audit.jpa.model.JobExecutionLog; +import org.kie.kogito.app.audit.jpa.model.ProcessInstanceErrorLog; +import org.kie.kogito.app.audit.jpa.model.ProcessInstanceNodeLog; +import org.kie.kogito.app.audit.jpa.model.ProcessInstanceNodeLog.NodeLogType; +import org.kie.kogito.app.audit.jpa.model.ProcessInstanceStateLog; +import org.kie.kogito.app.audit.jpa.model.ProcessInstanceStateLog.ProcessStateLogType; +import org.kie.kogito.app.audit.jpa.model.ProcessInstanceVariableLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceAssignmentLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceAttachmentLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceCommentLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceDeadlineLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceStateLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceVariableLog; +import org.kie.kogito.app.audit.jpa.model.UserTaskInstanceVariableLog.VariableType; +import org.kie.kogito.app.audit.spi.DataAuditStore; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; +import org.kie.kogito.event.process.ProcessInstanceSLADataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; +import org.kie.kogito.internal.process.runtime.KogitoProcessInstance; +import org.kie.kogito.jobs.service.model.ScheduledJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import jakarta.persistence.EntityManager; + +public class JPADataAuditStore implements DataAuditStore { + + private static final Logger LOGGER = LoggerFactory.getLogger(JPADataAuditStore.class); + + private ObjectMapper mapper; + + public JPADataAuditStore() { + mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + } + + @Override + public void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceStateDataEvent event) { + ProcessInstanceStateLog log = new ProcessInstanceStateLog(); + + setProcessCommonAttributes(log, event); + log.setState(String.valueOf(event.getData().getState())); + log.setRoles(event.getData().getRoles()); + + EntityManager entityManager = context.getContext(); + switch (event.getData().getState()) { + case KogitoProcessInstance.STATE_ACTIVE: + log.setEventType(ProcessStateLogType.ACTIVE); + entityManager.persist(log); + break; + case KogitoProcessInstance.STATE_ABORTED: + log.setEventType(ProcessStateLogType.ABORTED); + entityManager.persist(log); + break; + case KogitoProcessInstance.STATE_COMPLETED: + log.setEventType(ProcessStateLogType.COMPLETED); + entityManager.persist(log); + break; + case KogitoProcessInstance.STATE_PENDING: + log.setEventType(ProcessStateLogType.PENDING); + entityManager.persist(log); + break; + case KogitoProcessInstance.STATE_SUSPENDED: + log.setEventType(ProcessStateLogType.SUSPENDING); + entityManager.persist(log); + break; + case KogitoProcessInstance.STATE_ERROR: + log.setEventType(ProcessStateLogType.ERROR); + entityManager.persist(log); + break; + } + + } + + @Override + public void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceErrorDataEvent event) { + ProcessInstanceErrorLog log = new ProcessInstanceErrorLog(); + + setProcessCommonAttributes(log, event); + + log.setErrorMessage(event.getData().getErrorMessage()); + log.setNodeDefinitionId(event.getData().getNodeDefinitionId()); + log.setNodeInstanceId(event.getData().getNodeInstanceId()); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + } + + @Override + public void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceNodeDataEvent event) { + ProcessInstanceNodeLog log = new ProcessInstanceNodeLog(); + + setProcessCommonAttributes(log, event); + + log.setConnection(event.getData().getConnectionNodeDefinitionId()); + log.setNodeDefinitionId(event.getData().getNodeDefinitionId()); + log.setNodeType(event.getData().getNodeType()); + + log.setNodeInstanceId(event.getData().getNodeInstanceId()); + log.setNodeName(event.getData().getNodeName()); + + switch (event.getData().getEventType()) { + case ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER: + log.setEventType(NodeLogType.ENTER); + break; + case ProcessInstanceNodeEventBody.EVENT_TYPE_EXIT: + log.setEventType(NodeLogType.EXIT); + break; + case ProcessInstanceNodeEventBody.EVENT_TYPE_ABORTED: + log.setEventType(NodeLogType.ABORTED); + break; + case ProcessInstanceNodeEventBody.EVENT_TYPE_SKIPPED: + log.setEventType(NodeLogType.SKIPPED); + break; + case ProcessInstanceNodeEventBody.EVENT_TYPE_OBSOLETE: + log.setEventType(NodeLogType.OBSOLETE); + break; + case ProcessInstanceNodeEventBody.EVENT_TYPE_ERROR: + log.setEventType(NodeLogType.ERROR); + break; + + } + + log.setWorkItemId(event.getData().getWorkItemId()); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + } + + @Override + public void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceSLADataEvent event) { + EntityManager entityManager = context.getContext(); + + if (event.getData().getNodeDefinitionId() == null) { + ProcessInstanceStateLog log = new ProcessInstanceStateLog(); + setProcessCommonAttributes(log, event); + log.setEventType(ProcessStateLogType.SLA_VIOLATION); + log.setSlaDueDate(event.getData().getSlaDueDate()); + entityManager.persist(log); + } else { + ProcessInstanceNodeLog log = new ProcessInstanceNodeLog(); + setProcessCommonAttributes(log, event); + log.setNodeDefinitionId(event.getData().getNodeDefinitionId()); + log.setNodeInstanceId(event.getData().getNodeInstanceId()); + log.setNodeName(event.getData().getNodeName()); + log.setNodeType(event.getData().getNodeType()); + log.setEventType(NodeLogType.SLA_VIOLATION); + log.setSlaDueDate(event.getData().getSlaDueDate()); + entityManager.persist(log); + } + } + + @Override + public void storeProcessInstanceDataEvent(DataAuditContext context, ProcessInstanceVariableDataEvent event) { + + ProcessInstanceVariableLog log = new ProcessInstanceVariableLog(); + + setProcessCommonAttributes(log, event); + + log.setVariableId(event.getData().getVariableId()); + log.setVariableName(event.getData().getVariableName()); + log.setVariableValue(toJsonString(event.getData().getVariableValue())); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + + } + + private void setProcessCommonAttributes(AbstractProcessInstanceLog log, ProcessInstanceDataEvent event) { + log.setEventId(event.getId()); + log.setEventDate(new Date(event.getTime().toInstant().toEpochMilli())); + log.setProcessType(event.getKogitoProcessType()); + log.setProcessId(event.getKogitoProcessId()); + log.setProcessVersion(event.getKogitoProcessInstanceVersion()); + log.setProcessInstanceId(event.getKogitoProcessInstanceId()); + log.setParentProcessInstanceId(getOnlyIfFilled(event::getKogitoParentProcessInstanceId)); + log.setRootProcessId(getOnlyIfFilled(event::getKogitoRootProcessId)); + log.setRootProcessInstanceId(getOnlyIfFilled(event::getKogitoRootProcessInstanceId)); + log.setBusinessKey(event.getKogitoBusinessKey()); + } + + private String getOnlyIfFilled(Supplier producer) { + String data = producer.get(); + return data != null && !data.isBlank() ? data : null; + } + + @Override + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceAssignmentDataEvent event) { + UserTaskInstanceAssignmentLog log = new UserTaskInstanceAssignmentLog(); + + setUserTaskCommonAttributes(log, event); + log.setUserTaskDefinitionId(event.getData().getUserTaskDefinitionId()); + log.setEventUser(event.getData().getEventUser()); + log.setUsers(event.getData().getUsers()); + log.setAssignmentType(event.getData().getAssignmentType()); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + + } + + @Override + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceAttachmentDataEvent event) { + UserTaskInstanceAttachmentLog log = new UserTaskInstanceAttachmentLog(); + + setUserTaskCommonAttributes(log, event); + log.setUserTaskDefinitionId(event.getData().getUserTaskDefinitionId()); + log.setEventUser(event.getData().getEventUser()); + log.setAttachmentId(event.getData().getAttachmentId()); + log.setAttachmentName(event.getData().getAttachmentName()); + + if (event.getData().getAttachmentURI() != null) { + try { + log.setAttachmentURI(event.getData().getAttachmentURI().toURL()); + } catch (MalformedURLException e) { + LOGGER.error("Could not serialize url {}", e); + } + } + + log.setEventType(event.getData().getEventType()); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + + } + + @Override + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceCommentDataEvent event) { + UserTaskInstanceCommentLog log = new UserTaskInstanceCommentLog(); + + setUserTaskCommonAttributes(log, event); + log.setUserTaskDefinitionId(event.getData().getUserTaskDefinitionId()); + log.setEventUser(event.getData().getEventUser()); + log.setCommentId(event.getData().getCommentId()); + log.setCommentContent(event.getData().getCommentContent()); + log.setEventType(event.getData().getEventType()); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + + } + + @Override + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceDeadlineDataEvent event) { + UserTaskInstanceDeadlineLog log = new UserTaskInstanceDeadlineLog(); + + setUserTaskCommonAttributes(log, event); + log.setUserTaskDefinitionId(event.getData().getUserTaskDefinitionId()); + log.setEventUser(event.getData().getEventUser()); + if (event.getData().getNotification() != null) { + Map data = new HashMap<>(); + for (Map.Entry entry : event.getData().getNotification().entrySet()) { + data.put(entry.getKey(), entry.getValue().toString()); + } + log.setNotification(data); + } + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + } + + @Override + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceStateDataEvent event) { + UserTaskInstanceStateLog log = new UserTaskInstanceStateLog(); + + setUserTaskCommonAttributes(log, event); + log.setUserTaskDefinitionId(event.getData().getUserTaskDefinitionId()); + log.setActualUser(event.getData().getActualOwner()); + log.setName(event.getData().getUserTaskName()); + log.setDescription(event.getData().getUserTaskDescription()); + log.setState(event.getData().getState()); + log.setEventType(event.getData().getEventType()); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + + } + + @Override + public void storeUserTaskInstanceDataEvent(DataAuditContext context, UserTaskInstanceVariableDataEvent event) { + UserTaskInstanceVariableLog log = new UserTaskInstanceVariableLog(); + + setUserTaskCommonAttributes(log, event); + + log.setEventUser(event.getData().getEventUser()); + log.setUserTaskDefinitionId(event.getData().getUserTaskDefinitionId()); + log.setVariableId(event.getData().getVariableId()); + log.setVariableName(event.getData().getVariableName()); + log.setVariableValue(toJsonString(event.getData().getVariableValue())); + + switch (event.getData().getVariableType()) { + case "INPUT": + log.setVariableType(VariableType.INPUT); + break; + case "OUTPUT": + log.setVariableType(VariableType.OUTPUT); + break; + } + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + } + + private void setUserTaskCommonAttributes(AbstractUserTaskInstanceLog log, UserTaskInstanceDataEvent event) { + log.setEventId(event.getId()); + log.setEventDate(event.getTime() != null ? Date.from(event.getTime().toInstant()) : Date.from(Instant.now())); + log.setProcessInstanceId(event.getKogitoProcessInstanceId()); + log.setBusinessKey(event.getKogitoBusinessKey()); + log.setUserTaskInstanceId(event.getKogitoUserTaskInstanceId()); + } + + @Override + public void storeJobDataEvent(DataAuditContext context, JobInstanceDataEvent jobDataEvent) { + + ScheduledJob job = toObject(ScheduledJob.class, jobDataEvent.getData()); + + JobExecutionLog log = new JobExecutionLog(); + log.setJobId(job.getId()); + if (job.getExpirationTime() != null) { + log.setExpirationTime(Timestamp.from(job.getExpirationTime().toInstant())); + } + log.setPriority(job.getPriority()); + log.setProcessInstanceId(job.getProcessInstanceId()); + log.setNodeInstanceId(job.getNodeInstanceId()); + log.setRepeatInterval(job.getRepeatInterval()); + log.setRepeatLimit(job.getRepeatLimit()); + log.setScheduledId(job.getScheduledId()); + + if (job.getStatus() != null) { + log.setStatus(job.getStatus().name()); + } + + log.setExecutionCounter(job.getExecutionCounter()); + log.setEventDate(Timestamp.from(Instant.now())); + EntityManager entityManager = context.getContext(); + entityManager.persist(log); + } + + private T toObject(Class clazz, byte[] bytes) { + try { + return clazz.cast(mapper.readValue(bytes, clazz)); + } catch (IOException e) { + LOGGER.error("could not convert to json string {}", new String(bytes), e); + return null; + } + } + + private String toJsonString(Object data) { + try { + if (data == null) { + return null; + } + + return mapper.writeValueAsString(data); + } catch (JsonProcessingException e) { + LOGGER.error("could not convert to json string {}", data, e); + return null; + } + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/AbstractProcessInstanceLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/AbstractProcessInstanceLog.java new file mode 100644 index 0000000000..bf3a7a300d --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/AbstractProcessInstanceLog.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.persistence.Column; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; +import jakarta.persistence.Transient; + +import static org.kie.kogito.app.audit.jpa.model.ModelConstants.BUSINESS_KEY_LOG_LENGTH; + +@MappedSuperclass +public abstract class AbstractProcessInstanceLog { + + @Transient + private static final Logger logger = LoggerFactory.getLogger(AbstractProcessInstanceLog.class); + + @Column(name = "event_id") + private String eventId; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "event_date") + private Date eventDate; + + @Column(name = "process_type") + private String processType; + + @Column(name = "process_id") + private String processId; + + @Column(name = "process_version") + private String processVersion; + + @Column(name = "parent_process_instance_id") + private String parentProcessInstanceId; + + @Column(name = "root_process_id") + private String rootProcessId; + + @Column(name = "root_process_instance_id") + private String rootProcessInstanceId; + + @Column(name = "process_instance_id") + private String processInstanceId; + + @Column(name = "business_key") + private String businessKey; + + public String getRootProcessId() { + return rootProcessId; + } + + public void setRootProcessId(String rootProcessId) { + this.rootProcessId = rootProcessId; + } + + public String getRootProcessInstanceId() { + return rootProcessInstanceId; + } + + public void setRootProcessInstanceId(String rootProcessInstanceId) { + this.rootProcessInstanceId = rootProcessInstanceId; + } + + public String getEventId() { + return eventId; + } + + public String getProcessType() { + return processType; + } + + public void setProcessType(String processType) { + this.processType = processType; + } + + public String getProcessVersion() { + return processVersion; + } + + public void setProcessVersion(String processVersion) { + this.processVersion = processVersion; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getParentProcessInstanceId() { + return parentProcessInstanceId; + } + + public void setParentProcessInstanceId(String parentProcessInstanceId) { + this.parentProcessInstanceId = parentProcessInstanceId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public void setBusinessKey(String businessKey) { + String trimmedBusinesskey = null; + if (businessKey != null && businessKey.length() > BUSINESS_KEY_LOG_LENGTH) { + trimmedBusinesskey = businessKey.substring(0, BUSINESS_KEY_LOG_LENGTH); + logger.warn("Business Key content was trimmed as it was too long (more than {} characters)", BUSINESS_KEY_LOG_LENGTH); + } else { + trimmedBusinesskey = businessKey; + } + this.businessKey = trimmedBusinesskey; + } + + public Date getEventDate() { + return eventDate; + } + + public void setEventDate(Date eventDate) { + this.eventDate = eventDate; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/AbstractUserTaskInstanceLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/AbstractUserTaskInstanceLog.java new file mode 100644 index 0000000000..ab4677fc37 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/AbstractUserTaskInstanceLog.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.model; + +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.persistence.Column; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; +import jakarta.persistence.Transient; + +@MappedSuperclass +public abstract class AbstractUserTaskInstanceLog { + + @Transient + private static final Logger logger = LoggerFactory.getLogger(ProcessInstanceStateLog.class); + + @Column(name = "event_id") + private String eventId; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "event_date") + private Date eventDate; + + @Column(name = "event_user") + private String eventUser; + + @Column(name = "user_task_definition_id") + private String userTaskDefinitionId; + + @Column(name = "user_task_instance_id") + private String userTaskInstanceId; + + @Column(name = "process_instance_id") + private String processInstanceId; + + @Column(name = "business_key") + private String businessKey; + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public void setBusinessKey(String businessKey) { + this.businessKey = businessKey; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getBusinessKey() { + return businessKey; + } + + public Date getEventDate() { + return eventDate; + } + + public void setEventDate(Date eventDate) { + this.eventDate = eventDate; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public String getEventId() { + return eventId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public String getEventUser() { + return eventUser; + } + + public void setEventUser(String eventUser) { + this.eventUser = eventUser; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/JobExecutionLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/JobExecutionLog.java new file mode 100644 index 0000000000..450b112a45 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/JobExecutionLog.java @@ -0,0 +1,181 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.model; + +import java.sql.Timestamp; +import java.util.Date; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; + +@Entity +@Table(name = "Job_Execution_Log") +@SequenceGenerator(name = "jobExecutionHistoryIdSeq", sequenceName = "JOB_EXECUTION_HISTORY_ID_SEQ") +public class JobExecutionLog { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "jobExecutionHistoryIdSeq") + private Long id; + + @Column(name = "job_id") + private String jobId; + + @Column(name = "expiration_time") + @Temporal(TemporalType.TIMESTAMP) + private Date expirationTime; + + private Integer priority; + + @Column(name = "process_instance_id") + private String processInstanceId; + + @Column(name = "node_instance_id") + private String nodeInstanceId; + + @Column(name = "repeat_interval") + private Long repeatInterval; + + @Column(name = "repeat_limit") + private Integer repeatLimit; + + @Column(name = "scheduled_id") + private String scheduledId; + + private Integer retries; + + private String status; + + @Column(name = "execution_counter") + private Integer executionCounter; + + @Column(name = "event_date") + @Temporal(TemporalType.TIMESTAMP) + private Date eventDate; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getJobId() { + return jobId; + } + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + public Date getExpirationTime() { + return expirationTime; + } + + public void setExpirationTime(Timestamp expirationTime) { + this.expirationTime = expirationTime; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getNodeInstanceId() { + return nodeInstanceId; + } + + public void setNodeInstanceId(String nodeInstanceId) { + this.nodeInstanceId = nodeInstanceId; + } + + public Long getRepeatInterval() { + return repeatInterval; + } + + public void setRepeatInterval(Long repeatInterval) { + this.repeatInterval = repeatInterval; + } + + public Integer getRepeatLimit() { + return repeatLimit; + } + + public void setRepeatLimit(Integer repeatLimit) { + this.repeatLimit = repeatLimit; + } + + public String getScheduledId() { + return scheduledId; + } + + public void setScheduledId(String scheduledId) { + this.scheduledId = scheduledId; + } + + public Integer getRetries() { + return retries; + } + + public void setRetries(Integer retries) { + this.retries = retries; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Integer getExecutionCounter() { + return executionCounter; + } + + public void setExecutionCounter(Integer executionCounter) { + this.executionCounter = executionCounter; + } + + public Date getEventDate() { + return eventDate; + } + + public void setEventDate(Timestamp eventDate) { + this.eventDate = eventDate; + } +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ModelConstants.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ModelConstants.java new file mode 100644 index 0000000000..bf74c833ab --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ModelConstants.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.model; + +public final class ModelConstants { + + public static final int VARIABLE_LOG_LENGTH = Integer.getInteger("org.jbpm.var.log.length", 255); + + public static final int BUSINESS_KEY_LOG_LENGTH = Integer.getInteger("org.jbpm.correlationkey.length", 255); + + public static final int ERROR_LOG_LENGTH = Integer.getInteger("org.kie.jbpm.error.log.length", 255); +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceErrorLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceErrorLog.java new file mode 100644 index 0000000000..532b55d653 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceErrorLog.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; + +import static org.kie.kogito.app.audit.jpa.model.ModelConstants.ERROR_LOG_LENGTH; + +@Entity +@Table(name = "Process_Instance_Error_Log") +@SequenceGenerator(name = "processInstanceErrorHistorySeq", sequenceName = "PROCESS_INSTANCE_ERROR_LOG_SEQ_ID") +public class ProcessInstanceErrorLog extends AbstractProcessInstanceLog { + + @Transient + private static final Logger logger = LoggerFactory.getLogger(ProcessInstanceErrorLog.class); + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "processInstanceErrorHistorySeq") + private Long id; + + @Column(name = "error_message") + private String errorMessage; + + @Column(name = "node_definition_id") + private String nodeDefinitionId; + + @Column(name = "node_instance_id") + private String nodeInstanceId; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + String trimmedErrorMessage = errorMessage; + if (trimmedErrorMessage != null && trimmedErrorMessage.length() > ERROR_LOG_LENGTH) { + trimmedErrorMessage = trimmedErrorMessage.substring(0, ERROR_LOG_LENGTH); + logger.warn("Error message content was trimmed as it was too long (more than {} characters)", ERROR_LOG_LENGTH); + } + this.errorMessage = trimmedErrorMessage; + } + + public String getNodeDefinitionId() { + return nodeDefinitionId; + } + + public void setNodeDefinitionId(String nodeDefinitionId) { + this.nodeDefinitionId = nodeDefinitionId; + } + + public String getNodeInstanceId() { + return nodeInstanceId; + } + + public void setNodeInstanceId(String nodeInstanceId) { + this.nodeInstanceId = nodeInstanceId; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceNodeLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceNodeLog.java new file mode 100644 index 0000000000..0aeaf06e7a --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceNodeLog.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import java.util.Date; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; + +@Entity +@Table(name = "Process_Instance_Node_Log") +@SequenceGenerator(name = "processInstanceNodeLogIdSeq", sequenceName = "PROCESS_INSTANCE_NODE_LOG_ID_SEQ") +public class ProcessInstanceNodeLog extends AbstractProcessInstanceLog { + + public enum NodeLogType { + ENTER, + EXIT, + ABORTED, + ASYNC_ENTER, + OBSOLETE, + SKIPPED, + ERROR, + SLA_VIOLATION + } + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "processInstanceNodeLogIdSeq") + private long id; + + @Column(name = "event_type") + @Enumerated(EnumType.STRING) + private NodeLogType eventType; + + @Column(name = "node_definition_id") + private String nodeDefinitionId; + + @Column(name = "node_type") + private String nodeType; + + @Column(name = "node_name") + private String nodeName; + + @Column(name = "node_instance_id") + private String nodeInstanceId; + + @Column(name = "connection") + private String connection; + + @Column(name = "work_item_id") + private String workItemId; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "sla_due_date") + private Date slaDueDate; + + @Column(name = "event_data") + private String eventData; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public NodeLogType getEventType() { + return eventType; + } + + public void setEventType(NodeLogType eventType) { + this.eventType = eventType; + } + + public String getNodeDefinitionId() { + return nodeDefinitionId; + } + + public void setNodeDefinitionId(String nodeDefinitionId) { + this.nodeDefinitionId = nodeDefinitionId; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getNodeInstanceId() { + return nodeInstanceId; + } + + public void setNodeInstanceId(String nodeInstanceId) { + this.nodeInstanceId = nodeInstanceId; + } + + public String getConnection() { + return connection; + } + + public void setConnection(String connection) { + this.connection = connection; + } + + public String getWorkItemId() { + return workItemId; + } + + public void setWorkItemId(String workItemId) { + this.workItemId = workItemId; + } + + public Date getSlaDueDate() { + return slaDueDate; + } + + public void setSlaDueDate(Date slaDueDate) { + this.slaDueDate = slaDueDate; + } + + public String getEventData() { + return eventData; + } + + public void setEventData(String eventData) { + this.eventData = eventData; + } + +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceStateLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceStateLog.java new file mode 100644 index 0000000000..96f47f6ef4 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceStateLog.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import java.util.Date; +import java.util.Set; + +import jakarta.persistence.CollectionTable; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.ForeignKey; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; + +@Entity +@Table(name = "Process_Instance_State_Log") +@SequenceGenerator(name = "processInstanceStateLogIdSeq", sequenceName = "PROCESS_INSTANCE_STATE_LOG_ID_SEQ") +public class ProcessInstanceStateLog extends AbstractProcessInstanceLog { + + public enum ProcessStateLogType { + ACTIVE, + STARTED, + COMPLETED, + ABORTED, + SLA_VIOLATION, + PENDING, + SUSPENDING, + ERROR + } + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "processInstanceStateLogIdSeq") + private long id; + + @Column(name = "event_type", nullable = false) + @Enumerated(EnumType.STRING) + private ProcessStateLogType eventType; + + @Column + private String outcome; + + @Column + private String state; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "sla_due_date") + private Date slaDueDate; + + @ElementCollection + @CollectionTable(name = "Process_Instance_State_Roles_Log", joinColumns = @JoinColumn(name = "process_instance_state_log_id", foreignKey = @ForeignKey(name = "fk_process_instance_state_pid"))) + @Column(name = "role") + private Set roles; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public ProcessStateLogType getEventType() { + return eventType; + } + + public void setEventType(ProcessStateLogType eventType) { + this.eventType = eventType; + } + + public String getOutcome() { + return outcome; + } + + public void setOutcome(String outcome) { + this.outcome = outcome; + } + + public Date getSlaDueDate() { + return slaDueDate; + } + + public void setSlaDueDate(Date slaDueDate) { + this.slaDueDate = slaDueDate; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public void setRoles(Set roles) { + this.roles = roles; + } + + public Set getRoles() { + return roles; + } + +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceVariableLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceVariableLog.java new file mode 100644 index 0000000000..76a528460b --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/ProcessInstanceVariableLog.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; + +@Entity +@Table(name = "Process_Instance_Variable_Log") +@SequenceGenerator(name = "processInstanceVariableLogIdSeq", sequenceName = "PROCESS_INSTANCE_VARIABLE_LOG_ID_SEQ") +public class ProcessInstanceVariableLog extends AbstractProcessInstanceLog { + + @Transient + private static final Logger logger = LoggerFactory.getLogger(ProcessInstanceVariableLog.class); + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "processInstanceVariableLogIdSeq") + private long id; + + @Column(name = "variable_id") + private String variableId; + + @Column(name = "variable_name") + private String variableName; + + @Column(name = "variable_value") + private String variableValue; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getVariableId() { + return variableId; + } + + public void setVariableId(String variableId) { + this.variableId = variableId; + } + + public String getVariableName() { + return variableName; + } + + public void setVariableName(String variableName) { + this.variableName = variableName; + } + + public String getVariableValue() { + return variableValue; + } + + public void setVariableValue(String variableValue) { + this.variableValue = variableValue; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceAssignmentLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceAssignmentLog.java new file mode 100644 index 0000000000..dd54c7415a --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceAssignmentLog.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import java.util.List; + +import jakarta.persistence.CollectionTable; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.ForeignKey; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Task_Instance_Assignment_Log") +@SequenceGenerator(name = "taskInstanceAssignmentLogIdSeq", sequenceName = "TASK_INSTANCE_ASSIGNMENT_LOG_ID_SEQ") +public class UserTaskInstanceAssignmentLog extends AbstractUserTaskInstanceLog { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "taskInstanceAssignmentLogIdSeq") + private Long id; + + @Column(name = "task_definition_id") + private String userTaskDefinitionId; + + @Column(name = "task_instance_id") + private String userTaskInstanceId; + + @Column(name = "task_name") + private String userTaskName; + + @Column(name = "assignment_type") + private String assignmentType; // POT OWNERS, ADMIN... + + @ElementCollection + @CollectionTable(name = "Task_Instance_Assignment_Users_Log", joinColumns = @JoinColumn(name = "task_instance_assignment_log_id"), + foreignKey = @ForeignKey(name = "fk_task_instance_assignment_log_tid")) + @Column(name = "user_id") + private List users; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserTaskDefinitionId() { + return userTaskDefinitionId; + } + + public void setUserTaskDefinitionId(String userTaskDefinitionId) { + this.userTaskDefinitionId = userTaskDefinitionId; + } + + public String getUserTaskInstanceId() { + return userTaskInstanceId; + } + + public void setUserTaskInstanceId(String userTaskInstanceId) { + this.userTaskInstanceId = userTaskInstanceId; + } + + public String getUserTaskName() { + return userTaskName; + } + + public void setUserTaskName(String userTaskName) { + this.userTaskName = userTaskName; + } + + public String getAssignmentType() { + return assignmentType; + } + + public void setAssignmentType(String assignmentType) { + this.assignmentType = assignmentType; + } + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceAttachmentLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceAttachmentLog.java new file mode 100644 index 0000000000..0794d471f3 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceAttachmentLog.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import java.net.URL; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Task_Instance_Attachment_Log") +@SequenceGenerator(name = "taskInstanceAttachmentLogIdSeq", sequenceName = "TASK_INSTANCE_ATTACHMENT_LOG_ID_SEQ") +public class UserTaskInstanceAttachmentLog extends AbstractUserTaskInstanceLog { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "taskInstanceAttachmentLogIdSeq") + private Long id; + + @Column(name = "attachment_id") + private String attachmentId; + + @Column(name = "attachment_name") + private String attachmentName; + + @Column(name = "attachment_uri") + private URL attachmentURI; + + @Column(name = "event_type") + private int eventType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAttachmentId() { + return attachmentId; + } + + public void setAttachmentId(String attachmentId) { + this.attachmentId = attachmentId; + } + + public String getAttachmentName() { + return attachmentName; + } + + public void setAttachmentName(String attachmentName) { + this.attachmentName = attachmentName; + } + + public URL getAttachmentURI() { + return attachmentURI; + } + + public void setAttachmentURI(URL attachmentURI) { + this.attachmentURI = attachmentURI; + } + + public int getEventType() { + return eventType; + } + + public void setEventType(int eventType) { + this.eventType = eventType; + } + +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceCommentLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceCommentLog.java new file mode 100644 index 0000000000..3992b2fd66 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceCommentLog.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Task_Instance_Comment_Log") +@SequenceGenerator(name = "taskInstanceCommentLogIdSeq", sequenceName = "TASK_INSTANCE_COMMENT_LOG_ID_SEQ") +public class UserTaskInstanceCommentLog extends AbstractUserTaskInstanceLog { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "taskInstanceCommentLogIdSeq") + private Long id; + + // custom data fields + @Column(name = "comment_id") + private String commentId; + + @Column(name = "comment_content") + private String commentContent; + + @Column(name = "event_type") + private int eventType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getCommentId() { + return commentId; + } + + public void setCommentId(String commentId) { + this.commentId = commentId; + } + + public String getCommentContent() { + return commentContent; + } + + public void setCommentContent(String commentContent) { + this.commentContent = commentContent; + } + + public int getEventType() { + return eventType; + } + + public void setEventType(int eventType) { + this.eventType = eventType; + } + +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceDeadlineLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceDeadlineLog.java new file mode 100644 index 0000000000..3fee819639 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceDeadlineLog.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import java.util.Map; + +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.ForeignKey; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.MapKeyColumn; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Task_Instance_Deadline_Log") +@SequenceGenerator(name = "taskInstanceDeadlineLogIdSeq", sequenceName = "TASK_INSTANCE_DEADLINE_LOG_ID_SEQ") +public class UserTaskInstanceDeadlineLog extends AbstractUserTaskInstanceLog { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "taskInstanceDeadlineLogIdSeq") + private Long id; + + @ElementCollection + @JoinTable(name = "TaskInstanceDeadlineNotificationLog", joinColumns = @JoinColumn(name = "task_instance_deadline_log_id"), foreignKey = @ForeignKey(name = "fk_task_instance_deadline_tid")) + @MapKeyColumn(name = "property_name") + @Column(name = "property_value") + private Map notification; + + @Column(name = "event_type") + private String eventType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Map getNotification() { + return notification; + } + + public void setNotification(Map notification) { + this.notification = notification; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceStateLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceStateLog.java new file mode 100644 index 0000000000..e7f0dca004 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceStateLog.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Task_Instance_State_Log") +@SequenceGenerator(name = "taskInstanceStateLogIdSeq", sequenceName = "TASK_INSTANCE_STATE_LOG_ID_SEQ") +public class UserTaskInstanceStateLog extends AbstractUserTaskInstanceLog { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "taskInstanceStateLogIdSeq") + private Long id; + + private String name; + + private String description; + + @Column(name = "actual_user") + private String actualUser; + + private String state; + + @Column(name = "event_type") + private String eventType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getActualUser() { + return actualUser; + } + + public void setActualUser(String actualUser) { + this.actualUser = actualUser; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceVariableLog.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceVariableLog.java new file mode 100644 index 0000000000..5435901375 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/model/UserTaskInstanceVariableLog.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.kie.kogito.app.audit.jpa.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Task_Instance_Variable_Log") +@SequenceGenerator(name = "taskInstanceVariableLogIdSeq", sequenceName = "TASK_INSTANCE_VARIABLE_LOG_ID_SEQ") +public class UserTaskInstanceVariableLog extends AbstractUserTaskInstanceLog { + + public enum VariableType { + INPUT, + OUTPUT; + } + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "taskInstanceVariableLogIdSeq") + private Long id; + + @Column(name = "variable_id") + private String variableId; + + @Column(name = "variable_name") + private String variableName; + + @Column(name = "variable_value") + private String variableValue; + + @Column(name = "variable_type") + @Enumerated(EnumType.STRING) + private VariableType variableType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getVariableId() { + return variableId; + } + + public void setVariableId(String variableId) { + this.variableId = variableId; + } + + public String getVariableName() { + return variableName; + } + + public void setVariableName(String variableName) { + this.variableName = variableName; + } + + public String getVariableValue() { + return variableValue; + } + + public void setVariableValue(String variableValue) { + this.variableValue = variableValue; + } + + public VariableType getVariableType() { + return variableType; + } + + public void setVariableType(VariableType type) { + this.variableType = type; + } + +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/DataMapper.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/DataMapper.java new file mode 100644 index 0000000000..27325d6066 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/DataMapper.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.util.List; + +public interface DataMapper { + List produce(List data); +} \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAAbstractQuery.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAAbstractQuery.java new file mode 100644 index 0000000000..b0dc015990 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAAbstractQuery.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.Query; + +public abstract class JPAAbstractQuery { + + protected List executeWithNamedQueryEntityManager(EntityManager entityManager, String queryName, Class clazz) { + return executeWithNamedQueryEntityManager("META-INF/data-audit-orm.xml", entityManager, queryName); + } + + protected List executeWithNamedQueryEntityManager(String file, EntityManager entityManager, String queryName) { + String query = MappingFile.findInFile(file, entityManager, queryName); + return entityManager.createNativeQuery(query).getResultList(); + } + + protected List executeWithNamedQueryEntityManager(EntityManager entityManager, String query) { + return executeWithNamedQueryEntityManagerAndArguments(entityManager, query, Collections.emptyMap()); + } + + protected List executeWithNamedQueryEntityManagerAndArguments(EntityManager entityManager, String query, Map arguments) { + return executeWithNamedQueryEntityManagerAndArguments("META-INF/data-audit-orm.xml", entityManager, query, arguments); + } + + protected List executeWithNamedQueryEntityManagerAndArguments(String file, EntityManager entityManager, String queryName, Map arguments) { + String query = MappingFile.findInFile(file, entityManager, queryName); + + Map parameters = new HashMap<>(arguments); + Query jpaQuery = entityManager.createNativeQuery(query); + @SuppressWarnings("unchecked") + Map pagination = (Map) parameters.remove("pagination"); + parameters.forEach(jpaQuery::setParameter); + if (pagination != null) { + if (pagination.get("limit") != null) { + jpaQuery.setMaxResults((Integer) pagination.get("limit")); + } + if (pagination.get("offset") != null) { + jpaQuery.setFirstResult((Integer) pagination.get("offset")); + } + } + + return jpaQuery.getResultList(); + + } +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAComplexNamedQuery.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAComplexNamedQuery.java new file mode 100644 index 0000000000..4efdc9629c --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAComplexNamedQuery.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.util.List; +import java.util.Map; + +import org.kie.kogito.app.audit.api.DataAuditContext; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQuery; + +import graphql.schema.DataFetchingEnvironment; +import jakarta.persistence.EntityManager; + +public class JPAComplexNamedQuery extends JPAAbstractQuery implements GraphQLSchemaQuery> { + + private String name; + private String namedQuery; + private DataMapper dataMapper; + + public JPAComplexNamedQuery(String name, DataMapper dataMapper) { + this(name, name, dataMapper); + } + + public JPAComplexNamedQuery(String name, String namedQuery, DataMapper dataMapper) { + this.name = name; + this.namedQuery = namedQuery; + this.dataMapper = dataMapper; + } + + @Override + public String name() { + return name; + } + + @Override + public List fetch(DataFetchingEnvironment dataFetchingEnvironment) { + Map arguments = dataFetchingEnvironment.getArguments(); + DataAuditContext context = dataFetchingEnvironment.getLocalContext(); + EntityManager entityManager = context.getContext(); + + if (arguments.isEmpty()) { + return dataMapper.produce(executeWithNamedQueryEntityManager(entityManager, namedQuery)); + } else { + return dataMapper.produce(executeWithNamedQueryEntityManagerAndArguments(entityManager, namedQuery, arguments)); + } + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaJobsQueryProvider.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaJobsQueryProvider.java new file mode 100644 index 0000000000..d01ab33acd --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaJobsQueryProvider.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.JobExecutionTO; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQuery; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider; + +public class JPAGraphQLSchemaJobsQueryProvider implements GraphQLSchemaQueryProvider { + + @Override + public List> queries() { + return List.of( + new JPASimpleNamedQuery("GetAllScheduledJobs", JobExecutionTO.class), + new JPASimpleNamedQuery("GetJobById", JobExecutionTO.class), + new JPASimpleNamedQuery("GetJobHistoryById", JobExecutionTO.class), + new JPASimpleNamedQuery("GetJobHistoryByProcessInstanceId", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllPendingJobs", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllEligibleJobsForExecution", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllEligibleJobsForRetry", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllJobs", "GetAllJobs", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllCompletedJobs", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllInErrorJobs", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllCancelledJobs", JobExecutionTO.class), + new JPASimpleNamedQuery("GetAllJobsByStatus", JobExecutionTO.class), + new JPASimpleNamedQuery("GetJobByProcessInstanceId", JobExecutionTO.class)); + + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaProcessInstancesQueryProvider.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaProcessInstancesQueryProvider.java new file mode 100644 index 0000000000..3dd41f105f --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaProcessInstancesQueryProvider.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceErrorTO; +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceNodeTO; +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceStateTO; +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceVariableHistoryTO; +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceVariableTO; +import org.kie.kogito.app.audit.jpa.queries.mapper.ProcessInstanceStateTOMapper; +import org.kie.kogito.app.audit.jpa.queries.mapper.ProcessInstanceVariableHistoryTOMapper; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQuery; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider; + +public class JPAGraphQLSchemaProcessInstancesQueryProvider implements GraphQLSchemaQueryProvider { + + @Override + public List> queries() { + return List.> of( + new JPAComplexNamedQuery("GetAllProcessInstancesState", new ProcessInstanceStateTOMapper()), + new JPAComplexNamedQuery("GetAllProcessInstancesStateByStatus", new ProcessInstanceStateTOMapper()), + new JPAComplexNamedQuery("GetAllProcessInstancesStateByProcessId", new ProcessInstanceStateTOMapper()), + new JPAComplexNamedQuery("GetProcessInstancesStateHistory", new ProcessInstanceStateTOMapper()), + new JPAComplexNamedQuery("GetProcessInstancesStateHistoryByBusinessKey", new ProcessInstanceStateTOMapper()), + new JPASimpleNamedQuery("GetAllProcessInstancesNodeByProcessInstanceId", ProcessInstanceNodeTO.class), + new JPASimpleNamedQuery("GetAllProcessInstancesErrorByProcessInstanceId", ProcessInstanceErrorTO.class), + new JPASimpleNamedQuery("GetAllProcessInstancesVariableByProcessInstanceId", ProcessInstanceVariableTO.class), + new JPAComplexNamedQuery("GetAllProcessInstancesVariableHistoryByProcessInstanceId", + new ProcessInstanceVariableHistoryTOMapper())); + + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaUserTaskInstancesQueryProvider.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaUserTaskInstancesQueryProvider.java new file mode 100644 index 0000000000..9fa5a6f114 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPAGraphQLSchemaUserTaskInstancesQueryProvider.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceAssignmentTO; +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceAttachmentTO; +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceCommentTO; +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceDeadlineTO; +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceStateTO; +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceVariableTO; +import org.kie.kogito.app.audit.jpa.queries.mapper.UserTaskInstanceAssignmentTOMapper; +import org.kie.kogito.app.audit.jpa.queries.mapper.UserTaskInstanceDeadlineTOMapper; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQuery; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider; + +public class JPAGraphQLSchemaUserTaskInstancesQueryProvider implements GraphQLSchemaQueryProvider { + + @Override + public List> queries() { + return List.of( + new JPASimpleNamedQuery("GetAllUserTaskInstanceState", UserTaskInstanceStateTO.class), + new JPASimpleNamedQuery("GetAllUserTaskInstanceAttachments", UserTaskInstanceAttachmentTO.class), + new JPASimpleNamedQuery("GetAllUserTaskInstanceComments", UserTaskInstanceCommentTO.class), + new JPASimpleNamedQuery("GetAllUserTaskInstanceVariables", UserTaskInstanceVariableTO.class), + new JPAComplexNamedQuery("GetAllUserTaskInstanceAssignments", new UserTaskInstanceAssignmentTOMapper()), + new JPAComplexNamedQuery("GetAllUserTaskInstanceDeadlines", new UserTaskInstanceDeadlineTOMapper())); + } + + public OffsetDateTime toDateTime(Date date) { + return (date != null) ? OffsetDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")) : null; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPASimpleNamedQuery.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPASimpleNamedQuery.java new file mode 100644 index 0000000000..0624fda4de --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/JPASimpleNamedQuery.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.util.List; +import java.util.Map; + +import org.kie.kogito.app.audit.api.DataAuditContext; +import org.kie.kogito.app.audit.jpa.queries.mapper.PojoMapper; +import org.kie.kogito.app.audit.spi.GraphQLSchemaQuery; + +import graphql.schema.DataFetchingEnvironment; +import jakarta.persistence.EntityManager; + +public class JPASimpleNamedQuery extends JPAAbstractQuery implements GraphQLSchemaQuery> { + + private String name; + private String namedQuery; + private Class clazz; + private PojoMapper mapper; + + public JPASimpleNamedQuery(String name, Class clazz) { + this(name, name, clazz); + } + + public JPASimpleNamedQuery(String name, String namedQuery, Class clazz) { + this.name = name; + this.namedQuery = namedQuery; + this.clazz = clazz; + this.mapper = new PojoMapper(this.clazz); + } + + @Override + public String name() { + return name; + } + + @Override + public List fetch(DataFetchingEnvironment dataFetchingEnvironment) { + Map arguments = dataFetchingEnvironment.getArguments(); + DataAuditContext context = dataFetchingEnvironment.getLocalContext(); + EntityManager entityManager = context.getContext(); + + if (arguments.isEmpty()) { + return mapper.produce(executeWithNamedQueryEntityManager(entityManager, namedQuery)); + } else { + return mapper.produce(executeWithNamedQueryEntityManagerAndArguments(entityManager, namedQuery, arguments)); + } + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/MappingFile.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/MappingFile.java new file mode 100644 index 0000000000..b41a4dd423 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/MappingFile.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries; + +import java.io.InputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import jakarta.persistence.EntityManager; + +public class MappingFile { + + public static String findInDefault(EntityManager entityManager, String queryName) { + return findInFile("META-INF/data-audit-orm.xml", entityManager, queryName); + } + + public static String findInFile(String file, EntityManager entityManager, String queryName) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + cl = (cl == null) ? MappingFile.class.getClassLoader() : cl; + try (InputStream is = cl.getResourceAsStream(file)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + // parse XML file + DocumentBuilder db = dbf.newDocumentBuilder(); + + Document doc = db.parse(is); + Node entityMappingsNode = doc.getFirstChild(); // entity-mappings + + NodeList nativeQueries = entityMappingsNode.getChildNodes(); + for (int i = 0; i < nativeQueries.getLength(); i++) { + Node nativeQuery = nativeQueries.item(i); + if ("named-native-query".equals(nativeQuery.getNodeName())) { + String name = nativeQuery.getAttributes().getNamedItem("name").getNodeValue(); + String sqlQuery = null; + NodeList children = nativeQuery.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + Node query = children.item(j); + if ("query".equals(query.getNodeName())) { + sqlQuery = query.getTextContent(); + } + } + + if (name.equals(queryName)) { + return sqlQuery; + } + } + } + } catch (Exception e) { + return null; + } + return null; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/PojoMapper.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/PojoMapper.java new file mode 100644 index 0000000000..60fb648ec4 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/PojoMapper.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries.mapper; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.kie.kogito.app.audit.jpa.queries.DataMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PojoMapper implements DataMapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(PojoMapper.class); + + private Class clazz; + private Constructor defaultConstructor; + + public PojoMapper(Class clazz) { + this.clazz = clazz; + for (Constructor constructor : clazz.getConstructors()) { + if (constructor.getParameterCount() > 0) { + defaultConstructor = (Constructor) constructor; + } + } + } + + @Override + public List produce(List data) { + List transformed = new ArrayList<>(); + for (Object[] row : data) { + try { + transformed.add(defaultConstructor.newInstance(row)); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + LOGGER.error("Could not transform data", e); + } + } + return transformed; + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/ProcessInstanceStateTOMapper.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/ProcessInstanceStateTOMapper.java new file mode 100644 index 0000000000..1c0dca4e0c --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/ProcessInstanceStateTOMapper.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries.mapper; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceStateTO; +import org.kie.kogito.app.audit.jpa.queries.DataMapper; + +import graphql.com.google.common.base.Objects; + +public class ProcessInstanceStateTOMapper implements DataMapper { + @Override + public List produce(List data) { + List transformedData = new ArrayList<>(); + ProcessInstanceStateTO current = null; + Object currentIndex = null; + for (int idx = 0; idx < data.size(); idx++) { + Object[] row = data.get(idx); + if (!Objects.equal(currentIndex, row[0])) { + current = new ProcessInstanceStateTO(); + currentIndex = row[0]; + transformedData.add(current); + } + current.setEventId((String) row[0]); + current.setEventDate(toDateTime((Date) row[1])); + current.setProcessType((String) row[2]); + current.setProcessId((String) row[3]); + current.setProcessVersion((String) row[4]); + current.setParentProcessInstanceId((String) row[5]); + current.setRootProcessId((String) row[6]); + current.setRootProcessInstanceId((String) row[7]); + current.setProcessInstanceId((String) row[8]); + current.setBusinessKey((String) row[9]); + current.setEventType((String) row[10]); + current.setOutcome((String) row[11]); + current.setState((String) row[12]); + current.setSlaDueDate(toDateTime((Date) row[13])); + current.addRole((String) data.get(idx)[14]); + + } + + return transformedData; + } + + public OffsetDateTime toDateTime(Date date) { + return (date != null) ? OffsetDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")) : null; + } +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/ProcessInstanceVariableHistoryTOMapper.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/ProcessInstanceVariableHistoryTOMapper.java new file mode 100644 index 0000000000..77e984f8b3 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/ProcessInstanceVariableHistoryTOMapper.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries.mapper; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceVariableHistoryTO; +import org.kie.kogito.app.audit.graphql.type.ProcessInstanceVariableTO; +import org.kie.kogito.app.audit.jpa.queries.DataMapper; + +import graphql.com.google.common.base.Objects; + +public class ProcessInstanceVariableHistoryTOMapper implements DataMapper { + + PojoMapper mapper; + + public ProcessInstanceVariableHistoryTOMapper() { + mapper = new PojoMapper<>(ProcessInstanceVariableTO.class); + } + + @Override + public List produce(List rows) { + List data = mapper.produce(rows); + List transformedData = new ArrayList<>(); + ProcessInstanceVariableHistoryTO current = null; + Object currentIndex = null; + for (int idx = 0; idx < data.size(); idx++) { + ProcessInstanceVariableTO row = data.get(idx); + if (!Objects.equal(currentIndex, row.getVariableId())) { + current = new ProcessInstanceVariableHistoryTO(); + current.setVariableId(row.getVariableId()); + current.setVariableName(row.getVariableName()); + currentIndex = row.getVariableId(); + transformedData.add(current); + } + current.addLog(row); + } + + return transformedData; + } + + public OffsetDateTime toDateTime(Date date) { + return (date != null) ? OffsetDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")) : null; + } +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/UserTaskInstanceAssignmentTOMapper.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/UserTaskInstanceAssignmentTOMapper.java new file mode 100644 index 0000000000..b740b494e2 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/UserTaskInstanceAssignmentTOMapper.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries.mapper; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceAssignmentTO; +import org.kie.kogito.app.audit.jpa.queries.DataMapper; + +import graphql.com.google.common.base.Objects; + +public class UserTaskInstanceAssignmentTOMapper implements DataMapper { + + @Override + public List produce(List data) { + List transformedData = new ArrayList<>(); + UserTaskInstanceAssignmentTO current = null; + Object currentIndex = null; + for (int idx = 0; idx < data.size(); idx++) { + Object[] row = data.get(idx); + if (!Objects.equal(currentIndex, row[0])) { + current = new UserTaskInstanceAssignmentTO(); + currentIndex = row[0]; + transformedData.add(current); + } + current.setEventId((String) row[0]); + current.setEventDate(toDateTime((Date) row[1])); + current.setEventUser((String) row[2]); + current.setUserTaskDefinitionId((String) row[3]); + current.setUserTaskInstanceId((String) row[4]); + current.setProcessInstanceId((String) row[5]); + current.setBusinessKey((String) row[6]); + current.setUserTaskName((String) row[7]); + current.setAssignmentType((String) row[8]); + current.addUser((String) data.get(idx)[9]); + + } + + return transformedData; + } + + public OffsetDateTime toDateTime(Date date) { + return (date != null) ? OffsetDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")) : null; + } +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/UserTaskInstanceDeadlineTOMapper.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/UserTaskInstanceDeadlineTOMapper.java new file mode 100644 index 0000000000..6974d0907d --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/queries/mapper/UserTaskInstanceDeadlineTOMapper.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.jpa.queries.mapper; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.kie.kogito.app.audit.graphql.type.UserTaskInstanceDeadlineTO; +import org.kie.kogito.app.audit.jpa.queries.DataMapper; + +import graphql.com.google.common.base.Objects; + +public class UserTaskInstanceDeadlineTOMapper implements DataMapper { + + @Override + public List produce(List data) { + List transformedData = new ArrayList<>(); + UserTaskInstanceDeadlineTO current = null; + Object currentIndex = null; + for (int idx = 0; idx < data.size(); idx++) { + Object[] row = data.get(idx); + if (!Objects.equal(currentIndex, row[0])) { + current = new UserTaskInstanceDeadlineTO(); + currentIndex = row[0]; + transformedData.add(current); + } + current.setEventId((String) row[0]); + current.setEventDate(toDateTime((Date) row[1])); + current.setUserTaskDefinitionId((String) row[2]); + current.setUserTaskInstanceId((String) row[3]); + current.setProcessInstanceId((String) row[4]); + current.setBusinessKey((String) row[5]); + current.setEventType((String) row[6]); + current.addNotification((String) row[7], (String) row[8]); + + } + + return transformedData; + } + + public OffsetDateTime toDateTime(Date date) { + return (date != null) ? OffsetDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")) : null; + } +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/beans.xml b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/data-audit-orm.xml b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/data-audit-orm.xml new file mode 100644 index 0000000000..8d384fe7af --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/data-audit-orm.xml @@ -0,0 +1,666 @@ + + + + + + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status = 'SCHEDULED' + + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.job_id = :jobId + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + WHERE o1.job_id = :jobId + ORDER BY o1.event_date DESC + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + WHERE o1.process_instance_id = :processInstanceId + ORDER BY o1.event_date DESC + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status IN ('SCHEDULED', 'RETRY') + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status IN ('SCHEDULED') + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status IN ('RETRY', 'ERROR') + + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL + ORDER BY o1.event_date DESC + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status = 'EXECUTED' + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status = 'ERROR' + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status = 'CANCELED' + + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.status IN (:status) + ORDER BY o1.event_date DESC + + + + + + SELECT + o1.job_id, + o1.expiration_time, + o1.priority, + o1.process_instance_id, + o1.node_instance_id, + o1.repeat_interval, + o1.repeat_limit, + o1.scheduled_id, + o1.retries, + o1.status, + o1.execution_counter, + o1.event_date + FROM Job_Execution_Log o1 + LEFT JOIN Job_Execution_Log o2 ON o1.job_id = o2.job_id AND o1.event_date < o2.event_date + WHERE o2.job_id IS NULL AND o1.process_instance_id = :processInstanceId + ORDER BY o1.event_date DESC + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.process_type as processType, + log.process_id as processId, + log.process_version as processVersion, + log.parent_process_instance_id as parentProcessInstanceId, + log.root_process_id as rootProcessId, + log.root_process_instance_id as rootProcessInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.event_type as eventType, + log.outcome as outcome, + log.state as state, + log.sla_due_date as slaDueDate, + roles.role as role + FROM Process_Instance_State_Log log + LEFT JOIN Process_Instance_State_Log log_newer ON log.event_date < log_newer.event_date AND log.process_instance_id = log_newer.process_instance_id + LEFT JOIN Process_Instance_State_Roles_Log roles ON log.id = roles.process_instance_state_log_id + WHERE log_newer.event_id IS NULL + ORDER BY log.event_date DESC + + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.process_type as processType, + log.process_id as processId, + log.process_version as processVersion, + log.parent_process_instance_id as parentProcessInstanceId, + log.root_process_id as rootProcessId, + log.root_process_instance_id as rootProcessInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.event_type as eventType, + log.outcome as outcome, + log.state as state, + log.sla_due_date as slaDueDate, + roles.role as role + FROM Process_Instance_State_Log log + LEFT JOIN Process_Instance_State_Log log_newer ON log.event_date < log_newer.event_date AND log.process_instance_id = log_newer.process_instance_id + LEFT JOIN Process_Instance_State_Roles_Log roles ON log.id = roles.process_instance_state_log_id + WHERE log_newer.event_id IS NULL AND log.state = :status + ORDER BY log.event_date DESC + + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.process_type as processType, + log.process_id as processId, + log.process_version as processVersion, + log.parent_process_instance_id as parentProcessInstanceId, + log.root_process_id as rootProcessId, + log.root_process_instance_id as rootProcessInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.event_type as eventType, + log.outcome as outcome, + log.state as state, + log.sla_due_date as slaDueDate, + roles.role as role + FROM Process_Instance_State_Log log + LEFT JOIN Process_Instance_State_Log log_newer ON log.event_date < log_newer.event_date AND log.process_instance_id = log_newer.process_instance_id + LEFT JOIN Process_Instance_State_Roles_Log roles ON log.id = roles.process_instance_state_log_id + WHERE log_newer.event_id IS NULL AND log.process_id = :processId + ORDER BY log.event_date DESC + + + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.process_type as processType, + log.process_id as processId, + log.process_version as processVersion, + log.parent_process_instance_id as parentProcessInstanceId, + log.root_process_id as rootProcessId, + log.root_process_instance_id as rootProcessInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.event_type as eventType, + log.outcome as outcome, + log.state as state, + log.sla_due_date as slaDueDate, + roles.role as role + FROM Process_Instance_State_Log log + LEFT JOIN Process_Instance_State_Roles_Log roles ON log.id = roles.process_instance_state_log_id + WHERE log.process_instance_id = :processInstanceId + ORDER BY log.event_date DESC + + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.process_type as processType, + log.process_id as processId, + log.process_version as processVersion, + log.parent_process_instance_id as parentProcessInstanceId, + log.root_process_id as rootProcessId, + log.root_process_instance_id as rootProcessInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.event_type as eventType, + log.outcome as outcome, + log.state as state, + log.sla_due_date as slaDueDate, + roles.role as role + FROM Process_Instance_State_Log log + LEFT JOIN Process_Instance_State_Roles_Log roles ON log.id = roles.process_instance_state_log_id + WHERE log.business_key = :businessKey + ORDER BY log.event_date DESC + + + + + + + SELECT + log.event_id, + log.event_date, + log.process_type, + log.process_id, + log.process_version, + log.parent_process_instance_id, + log.root_process_id, + log.root_process_instance_id, + log.process_instance_id, + log.business_key, + log.event_type, + log.node_type, + log.node_name, + log.node_instance_id, + log.connection, + log.work_item_id, + log.sla_due_date, + log.event_data + FROM Process_Instance_Node_Log log + LEFT JOIN Process_Instance_Node_Log log_newer ON log.event_date < log_newer.event_date AND log.process_instance_id = log_newer.process_instance_id AND log.node_instance_id = log_newer.node_instance_id + WHERE log_newer.event_id IS NULL AND log.process_instance_id = :processInstanceId + ORDER BY log.event_date DESC + + + + + + + SELECT + log.event_id, + log.event_date, + log.process_type, + log.process_id, + log.process_version, + log.parent_process_instance_id, + log.root_process_id, + log.root_process_instance_id, + log.process_instance_id, + log.business_key, + log.error_message, + log.node_definition_id, + log.node_instance_id + FROM Process_Instance_Error_Log log + WHERE log.process_instance_id = :processInstanceId + ORDER BY log.event_date DESC + + + + + + + SELECT + log.event_id, + log.event_date, + log.process_type, + log.process_id, + log.process_version, + log.parent_process_instance_id, + log.root_process_id, + log.root_process_instance_id, + log.process_instance_id, + log.business_key, + log.variable_id, + log.variable_name, + log.variable_value + FROM Process_Instance_Variable_Log log + LEFT JOIN Process_Instance_Variable_Log log_newer ON log.event_date < log_newer.event_date + AND log.process_instance_id = log_newer.process_instance_id + AND log.variable_id = log_newer.variable_id + WHERE log_newer.event_id IS NULL AND log.process_instance_id = :processInstanceId + ORDER BY log.event_date DESC + + + + + + + SELECT + log.event_id, + log.event_date, + log.process_type, + log.process_id, + log.process_version, + log.parent_process_instance_id, + log.root_process_id, + log.root_process_instance_id, + log.process_instance_id, + log.business_key, + log.variable_id, + log.variable_name, + log.variable_value + FROM Process_Instance_Variable_Log log + WHERE log.process_instance_id = :processInstanceId + ORDER BY log.variable_id ASC, log.event_date DESC + + + + + + + + + + + SELECT + log.event_id, + log.event_date, + log.user_task_definition_id, + log.user_task_instance_id, + log.process_instance_id, + log.business_key, + log.name, + log.description, + log.actual_user, + log.state, + log.event_type + FROM Task_Instance_State_Log log + LEFT JOIN Task_Instance_State_Log log_newer ON log.user_task_instance_id = log_newer.user_task_instance_id + AND log_newer.event_date < log_newer.event_date + WHERE log_newer.event_id IS NULL + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.event_user as eventUser, + log.user_task_definition_id as userTaskDefinitionId, + log.user_task_instance_id as userTaskInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.task_name as userTaskName, + log.assignment_type as assignmentType, + users.user_id + FROM Task_Instance_Assignment_Log log + LEFT JOIN Task_Instance_Assignment_Users_Log users ON users.task_instance_assignment_log_id = log.id + WHERE log.user_task_instance_id = :userTaskInstanceId + + + + + + + SELECT + log.event_id, + log.event_date, + log.event_user, + log.user_task_definition_id, + log.user_task_instance_id, + log.process_instance_id, + log.business_key, + log.attachment_id, + log.attachment_name, + log.attachment_uri, + log.event_type + FROM Task_Instance_Attachment_Log log + LEFT JOIN Task_Instance_Attachment_Log log_newer ON log.user_task_instance_id = log_newer.user_task_instance_id + AND log.attachment_id = log_newer.attachment_id + AND log_newer.event_date < log_newer.event_date + WHERE log_newer.event_id IS NULL AND log.user_task_instance_id = :userTaskInstanceId + + + + + + + SELECT + log.event_id, + log.event_date, + log.user_task_definition_id, + log.user_task_instance_id, + log.process_instance_id, + log.business_key, + log.comment_id, + log.comment_content, + log.event_type + FROM Task_Instance_Comment_Log log + LEFT JOIN Task_Instance_Comment_Log log_newer ON log.user_task_instance_id = log_newer.user_task_instance_id + AND log.comment_id = log_newer.comment_id + AND log_newer.event_date < log_newer.event_date + WHERE log_newer.event_id IS NULL AND log.user_task_instance_id = :userTaskInstanceId + + + + + + + SELECT log.event_id as eventId, + log.event_date as eventDate, + log.user_task_definition_id as userTaskDefinitionId, + log.user_task_instance_id as userTaskInstanceId, + log.process_instance_id as processInstanceId, + log.business_key as businessKey, + log.event_type as eventType, + notification.property_name as propertyName, + notification.property_value as propertyValue + FROM Task_Instance_Deadline_Log log + LEFT JOIN TaskInstanceDeadlineNotificationLog notification ON log.id = notification.task_instance_deadline_log_id + WHERE log.user_task_instance_id = :userTaskInstanceId + + + + + + + SELECT + log.event_id, + log.event_date, + log.event_user, + log.user_task_definition_id, + log.user_task_instance_id, + log.process_instance_id, + log.business_key, + log.variable_id, + log.variable_name, + log.variable_value, + log.variable_type + FROM Task_Instance_Variable_Log log + LEFT JOIN Task_Instance_Variable_Log log_newer ON log.user_task_instance_id = log_newer.user_task_instance_id + AND log.variable_id = log_newer.variable_id + AND log.variable_type = log_newer.variable_type + AND log.event_date < log_newer.event_date + WHERE log_newer.event_id IS NULL AND log.user_task_instance_id = :userTaskInstanceId + + + + + \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/services/org.kie.kogito.app.audit.spi.DataAuditStore b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/services/org.kie.kogito.app.audit.spi.DataAuditStore new file mode 100644 index 0000000000..3629c4c4f5 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/services/org.kie.kogito.app.audit.spi.DataAuditStore @@ -0,0 +1 @@ +org.kie.kogito.app.audit.jpa.JPADataAuditStore \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/services/org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/services/org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider new file mode 100644 index 0000000000..ac66f469b8 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/services/org.kie.kogito.app.audit.spi.GraphQLSchemaQueryProvider @@ -0,0 +1,3 @@ +org.kie.kogito.app.audit.jpa.queries.JPAGraphQLSchemaJobsQueryProvider +org.kie.kogito.app.audit.jpa.queries.JPAGraphQLSchemaProcessInstancesQueryProvider +org.kie.kogito.app.audit.jpa.queries.JPAGraphQLSchemaUserTaskInstancesQueryProvider \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/pom.xml b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/pom.xml new file mode 100644 index 0000000000..4f60023f3b --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + kogito-addons-data-audit-jpa + org.kie.kogito + 999-SNAPSHOT + + + kogito-addons-data-audit-jpa-quarkus + + Kogito Apps :: Data Audit :: JPA :: Quarkus + + + + UTF-8 + + + + + org.kie.kogito + kogito-addons-data-audit-jpa-common + + + org.kie.kogito + data-audit-common + + + org.kie.kogito + kogito-events-core + + + org.kie.kogito + jobs-service-api + + + org.slf4j + slf4j-api + + + io.quarkus + quarkus-core + + + io.quarkus + quarkus-arc + + + + io.quarkus + quarkus-reactive-routes + + + io.quarkiverse.reactivemessaging.http + quarkus-reactive-messaging-http + + + io.quarkus + quarkus-vertx-graphql + + + + + io.quarkus + quarkus-hibernate-orm + + + + io.quarkus + quarkus-jdbc-h2 + + + io.quarkus + quarkus-jdbc-postgresql + + + + diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditContextFactory.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditContextFactory.java new file mode 100644 index 0000000000..40e35c1a18 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditContextFactory.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import org.kie.kogito.app.audit.api.DataAuditContext; +import org.kie.kogito.app.audit.spi.DataAuditContextFactory; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +@ApplicationScoped +public class QuarkusJPADataAuditContextFactory implements DataAuditContextFactory { + + @PersistenceContext + EntityManager entityManager; + + @Override + public DataAuditContext newDataAuditContext() { + return DataAuditContext.newDataAuditContext(entityManager); + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/META-INF/beans.xml b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/application.properties b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/application.properties new file mode 100644 index 0000000000..b60de7d417 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/application.properties @@ -0,0 +1,3 @@ +#quarkus.hibernate-orm.DataAuditPU.packages=org.kie.kogito.app.audit.jpa.model +#quarkus.hibernate-orm.DataAuditPU.mapping-files=META-INF/entity-orm.xml,META-INF/job-orm.xml,META-INF/process-orm.xml,META-INF/usertask-orm.xml +#quarkus.hibernate-orm.DataAuditPU.datasource=data-audit \ No newline at end of file diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/pom.xml b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/pom.xml new file mode 100644 index 0000000000..072f923b95 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + kogito-addons-data-audit-jpa + org.kie.kogito + 999-SNAPSHOT + + + + kogito-addons-data-audit-jpa-springboot + Kogito Apps :: Data Audit :: JPA :: SpringBoot + + + + UTF-8 + + + + + org.kie.kogito + data-audit-common + + + org.kie.kogito + kogito-addons-data-audit-jpa-common + + + org.kie.kogito + kogito-events-core + + + org.slf4j + slf4j-api + + + + org.springframework.boot + spring-boot-starter + ${version.org.springframework.boot} + + + org.springframework.boot + spring-boot-starter-data-jpa + ${version.org.springframework.boot} + + + com.h2database + h2 + + + org.postgresql + postgresql + + + diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPAAuditDataConfiguration.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPAAuditDataConfiguration.java new file mode 100644 index 0000000000..98734d9c23 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPAAuditDataConfiguration.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.springboot; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration(proxyBeanMethods = false) +@EntityScan(basePackages = "org.kie.kogito.app.audit.jpa.model") +@EnableTransactionManagement +public class SpringbootJPAAuditDataConfiguration { + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditContextFactory.java b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditContextFactory.java new file mode 100644 index 0000000000..c7c0b09259 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditContextFactory.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.springboot; + +import org.kie.kogito.app.audit.api.DataAuditContext; +import org.kie.kogito.app.audit.spi.DataAuditContextFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import jakarta.persistence.EntityManager; + +@Component +public class SpringbootJPADataAuditContextFactory implements DataAuditContextFactory { + + @Autowired + EntityManager entityManager; + + @Override + public DataAuditContext newDataAuditContext() { + return DataAuditContext.newDataAuditContext(entityManager); + } + +} diff --git a/data-audit/kogito-addons-data-audit-jpa/pom.xml b/data-audit/kogito-addons-data-audit-jpa/pom.xml new file mode 100644 index 0000000000..1f7e867c75 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-jpa/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + data-audit + org.kie.kogito + 999-SNAPSHOT + + + pom + kogito-addons-data-audit-jpa + + Kogito Apps :: Data Audit :: JPA + + + UTF-8 + + + + kogito-addons-data-audit-jpa-common + kogito-addons-data-audit-jpa-quarkus + kogito-addons-data-audit-jpa-springboot + data-audit-quarkus-jpa-service + + diff --git a/data-audit/kogito-addons-data-audit-quarkus/pom.xml b/data-audit/kogito-addons-data-audit-quarkus/pom.xml new file mode 100644 index 0000000000..eca4a4b9bd --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/pom.xml @@ -0,0 +1,120 @@ + + + 4.0.0 + + org.kie.kogito + data-audit + 999-SNAPSHOT + + + kogito-addons-data-audit-quarkus + + + Kogito Apps :: Data Audit :: Quarkus + + + UTF-8 + + + + + org.kie.kogito + data-audit-common + + + org.kie.kogito + kogito-events-core + + + org.kie.kogito + jobs-service-api + + + org.slf4j + slf4j-api + + + + + + io.quarkus + quarkus-core + + + io.quarkus + quarkus-arc + + + + io.quarkus + quarkus-reactive-routes + + + io.quarkiverse.reactivemessaging.http + quarkus-reactive-messaging-http + + + io.quarkus + quarkus-vertx-graphql + + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + org.assertj + assertj-core + test + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + + + maven-surefire-plugin + + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + jpa + + true + + + + org.kie.kogito + kogito-addons-data-audit-jpa-quarkus + test + + + + + + + diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/GraphQLJPADataAuditRouter.java b/data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/GraphQLJPADataAuditRouter.java new file mode 100644 index 0000000000..28df810396 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/GraphQLJPADataAuditRouter.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import org.kie.kogito.app.audit.api.DataAuditQueryService; +import org.kie.kogito.app.audit.spi.DataAuditContextFactory; + +import io.quarkus.vertx.web.Route; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.graphql.ExecutionInputBuilderWithContext; +import io.vertx.ext.web.handler.graphql.GraphQLHandler; +import io.vertx.ext.web.handler.graphql.GraphQLHandlerOptions; + +import graphql.GraphQL; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import static io.quarkus.vertx.web.Route.HttpMethod.GET; +import static io.quarkus.vertx.web.Route.HttpMethod.POST; +import static org.kie.kogito.app.audit.api.SubsystemConstants.DATA_AUDIT_PATH; + +@ApplicationScoped +public class GraphQLJPADataAuditRouter { + + GraphQL graphQL; + + GraphQLHandler graphQLHandler; + + @Inject + DataAuditContextFactory dataAuditContextFactory; + + @PostConstruct + public void init() { + graphQL = GraphQL.newGraphQL(DataAuditQueryService.newAuditQuerySerice().getGraphQLSchema()).build(); + graphQLHandler = GraphQLHandler.create(graphQL, new GraphQLHandlerOptions()); + } + + @Route(path = DATA_AUDIT_PATH, type = Route.HandlerType.BLOCKING, order = 2, methods = { GET }) + public void blockingGraphQLHandlerGet(RoutingContext rc) { + graphQLHandler.beforeExecute(this::beforeExecuteHTTP).handle(rc); + } + + @Route(path = DATA_AUDIT_PATH, type = Route.HandlerType.BLOCKING, order = 2, methods = { POST }) + public void blockingGraphQLHandlerPost(RoutingContext rc) { + graphQLHandler.beforeExecute(this::beforeExecuteHTTP).handle(rc); + } + + private void beforeExecuteHTTP(ExecutionInputBuilderWithContext config) { + config.builder().localContext(dataAuditContextFactory.newDataAuditContext()); + } + +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditEventPublisher.java b/data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditEventPublisher.java new file mode 100644 index 0000000000..21261a5a1d --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditEventPublisher.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import java.util.Collection; + +import org.kie.kogito.app.audit.api.DataAuditStoreProxyService; +import org.kie.kogito.app.audit.spi.DataAuditContextFactory; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import jakarta.transaction.Transactional.TxType; + +@ApplicationScoped +public class QuarkusJPADataAuditEventPublisher implements EventPublisher { + + private static final Logger LOGGER = LoggerFactory.getLogger(QuarkusJPADataAuditEventPublisher.class); + + private DataAuditStoreProxyService proxy; + + @Inject + DataAuditContextFactory dataAuditContextFactory; + + public QuarkusJPADataAuditEventPublisher() { + proxy = DataAuditStoreProxyService.newAuditStoreService(); + } + + @Override + @Transactional(value = TxType.REQUIRED) + public void publish(Collection> events) { + events.forEach(this::publish); + } + + @Override + @Transactional(value = TxType.REQUIRED) + public void publish(DataEvent event) { + + if (event instanceof ProcessInstanceDataEvent) { + LOGGER.debug("Processing process instance event {}", event); + proxy.storeProcessInstanceDataEvent(dataAuditContextFactory.newDataAuditContext(), (ProcessInstanceDataEvent) event); + return; + } else if (event instanceof UserTaskInstanceDataEvent) { + LOGGER.debug("Processing user task instacne event {}", event); + proxy.storeUserTaskInstanceDataEvent(dataAuditContextFactory.newDataAuditContext(), (UserTaskInstanceDataEvent) event); + return; + } else if (event instanceof JobInstanceDataEvent) { + LOGGER.debug("Processing job instance event {}", event); + proxy.storeJobDataEvent(dataAuditContextFactory.newDataAuditContext(), (JobInstanceDataEvent) event); + return; + } + + LOGGER.info("Discard event {} as class {} is not supported by this", event, event.getClass().getName()); + } + +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/main/resources/META-INF/beans.xml b/data-audit/kogito-addons-data-audit-quarkus/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/DataAuditTestUtils.java b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/DataAuditTestUtils.java new file mode 100644 index 0000000000..b7f63c4305 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/DataAuditTestUtils.java @@ -0,0 +1,442 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import java.net.URI; +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceErrorEventBody; +import org.kie.kogito.event.process.ProcessInstanceEventMetadata; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.kie.kogito.event.process.ProcessInstanceVariableEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceEventMetadata; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableEventBody; +import org.kie.kogito.jobs.service.model.JobStatus; +import org.kie.kogito.jobs.service.model.ScheduledJob; +import org.kie.kogito.process.ProcessInstance; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +public class DataAuditTestUtils { + + public static final String ADDONS = "jobs-management,prometheus-monitoring,process-management"; + + private static String toURIEndpoint(String processId) { + return URI.create("http://localhost:8080/" + processId).toString(); + } + + public static String wrapQuery(String query) { + return "{ \"query\" : \"" + query + " \"}"; + } + + public static JobInstanceDataEvent newJobEvent(String jobId, String nodeInstanceId, Integer priority, + String processId, String procesInstanceId, Long repeatInterval, Integer repeatLimit, String rootProcessId, String rootProcessInstanceId, + JobStatus state, Integer executionCounter) throws Exception { + + ScheduledJob job = new ScheduledJob(); + job.setId(jobId); + job.setNodeInstanceId(nodeInstanceId); + job.setCallbackEndpoint("https://callback"); + job.setPriority(priority); + job.setProcessId(processId); + job.setProcessInstanceId(procesInstanceId); + job.setRepeatInterval(repeatInterval); + job.setRepeatLimit(repeatLimit); + job.setRootProcessId(rootProcessId); + job.setRootProcessInstanceId(rootProcessInstanceId); + + job = ScheduledJob.builder() + .job(job) + .status(state) + .executionCounter(executionCounter) + .scheduledId("my scheduler") + .expirationTime(ZonedDateTime.now()) + .build(); + + JobInstanceDataEvent dataEvent = + new JobInstanceDataEvent("JobEvent", toURIEndpoint(processId), new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsBytes(job), procesInstanceId, + rootProcessInstanceId, processId, rootProcessId, (String) "identity"); + return dataEvent; + } + + public static JobInstanceDataEvent deriveNewState(JobInstanceDataEvent jobEvent, Integer executionCounter, JobStatus state) throws Exception { + ScheduledJob job = new ObjectMapper().registerModule(new JavaTimeModule()).readValue(jobEvent.getData(), ScheduledJob.class); + job = ScheduledJob.builder() + .job(job) + .status(state) + .executionCounter(executionCounter) + .scheduledId("my scheduler") + .expirationTime(ZonedDateTime.now()) + .build(); + + JobInstanceDataEvent dataEvent = new JobInstanceDataEvent("JobEvent", jobEvent.getSource().toString(), new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsBytes(job), + jobEvent.getKogitoProcessInstanceId(), + jobEvent.getKogitoRootProcessInstanceId(), jobEvent.getKogitoProcessId(), jobEvent.getKogitoRootProcessId(), (String) "identity"); + return dataEvent; + } + + public static ProcessInstanceStateDataEvent newProcessInstanceStateEvent( + String processId, String processInstanceId, Integer status, String rootProcessInstanceId, String rootProcessId, + String parentProcessInstanceId, String identity, int eventType) { + + String processVersion = "1.0"; + String processType = "BPMN2"; + ProcessInstanceStateEventBody body = ProcessInstanceStateEventBody.create() + .processInstanceId(processInstanceId) + .parentInstanceId(parentProcessInstanceId) + .rootProcessInstanceId(rootProcessInstanceId) + .rootProcessId(rootProcessId) + .processId(processId) + .processType(processType) + .processVersion(processVersion) + .processName(UUID.randomUUID().toString()) + .eventDate(new Date()) + .state(status) + .businessKey("BusinessKey" + processInstanceId) + .roles("admin", "role2") + .eventUser(identity) + .eventType(eventType) + .build(); + + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, processInstanceId); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, processVersion); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, processId); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(status)); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, processType); + metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, parentProcessInstanceId); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, rootProcessId); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, rootProcessInstanceId); + + ProcessInstanceStateDataEvent event = + new ProcessInstanceStateDataEvent(toURIEndpoint(processId), ADDONS, (String) identity, metadata, body); + + event.setKogitoBusinessKey(body.getBusinessKey()); + return event; + } + + public static ProcessInstanceStateDataEvent deriveProcessInstanceStateEvent(ProcessInstanceStateDataEvent event, String identity, int status, int eventType) { + + ProcessInstanceStateEventBody body = ProcessInstanceStateEventBody.create() + .processInstanceId(event.getData().getProcessInstanceId()) + .parentInstanceId(event.getData().getParentInstanceId()) + .rootProcessInstanceId(event.getData().getRootProcessInstanceId()) + .rootProcessId(event.getData().getRootProcessId()) + .processId(event.getData().getProcessId()) + .processType(event.getData().getProcessType()) + .processVersion(event.getData().getProcessVersion()) + .processName(event.getData().getProcessName()) + .eventDate(new Date()) + .state(status) + .businessKey(event.getData().getBusinessKey()) + .roles("admin") + .eventUser(identity) + .eventType(eventType) + .build(); + + ProcessInstanceStateDataEvent newEvent = + new ProcessInstanceStateDataEvent(toURIEndpoint(body.getProcessId()), ADDONS, (String) identity, + extractProcessInstnaceEventMetadata(event), body); + newEvent.setKogitoBusinessKey(body.getBusinessKey()); + return newEvent; + } + + public static ProcessInstanceNodeDataEvent newProcessInstanceNodeEvent( + ProcessInstanceStateDataEvent pEvent, + String nodeType, String nodeDefintionId, String nodeInstanceId, String nodeName, String connection, String identity, int eventType) { + + ProcessInstanceNodeEventBody body = ProcessInstanceNodeEventBody.create() + .processInstanceId(pEvent.getData().getProcessInstanceId()) + .processId(pEvent.getData().getProcessId()) + .processVersion(pEvent.getData().getProcessVersion()) + .eventDate(new Date()) + .eventUser(identity) + .eventType(eventType) + .nodeName(nodeName) + .nodeType(nodeType) + .nodeDefinitionId(nodeDefintionId) + .nodeInstanceId(nodeInstanceId) + .connectionNodeDefinitionId(connection) + .build(); + + ProcessInstanceNodeDataEvent event = new ProcessInstanceNodeDataEvent(toURIEndpoint(body.getProcessId()), + ADDONS, (String) identity, + extractProcessInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + public static ProcessInstanceVariableDataEvent newProcessInstanceVariableEvent( + ProcessInstanceStateDataEvent pEvent, + String variableId, String variableName, Object variableValue, String identity) { + + ProcessInstanceVariableEventBody body = ProcessInstanceVariableEventBody.create() + .eventDate(new Date()) + .eventUser(identity) + .processId(pEvent.getData().getProcessId()) + .processVersion(pEvent.getData().getProcessVersion()) + .processInstanceId(pEvent.getData().getProcessInstanceId()) + .variableId(variableId) + .variableName(variableName) + .variableValue(variableValue) + .build(); + + ProcessInstanceVariableDataEvent event = new ProcessInstanceVariableDataEvent(toURIEndpoint(body.getProcessId()), + ADDONS, (String) identity, + extractProcessInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + public static ProcessInstanceErrorDataEvent newProcessInstanceErrorEvent( + ProcessInstanceStateDataEvent pEvent, + String nodeDefintionId, String nodeInstanceId, String errorMessage, String identity) { + + ProcessInstanceErrorEventBody body = ProcessInstanceErrorEventBody.create() + .eventDate(new Date()) + .eventUser(identity) + .processId(pEvent.getData().getProcessId()) + .processVersion(pEvent.getData().getProcessVersion()) + .processInstanceId(pEvent.getData().getProcessInstanceId()) + .nodeDefinitionId(nodeDefintionId) + .nodeInstanceId(nodeInstanceId) + .errorMessage(errorMessage) + .build(); + + ProcessInstanceErrorDataEvent event = new ProcessInstanceErrorDataEvent(toURIEndpoint(body.getProcessId()), + ADDONS, (String) identity, + extractProcessInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + private static Map extractProcessInstnaceEventMetadata(ProcessInstanceDataEvent pEvent) { + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, pEvent.getKogitoProcessInstanceId()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, pEvent.getKogitoProcessInstanceVersion()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, pEvent.getKogitoProcessId()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, pEvent.getKogitoProcessInstanceState()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, pEvent.getKogitoProcessType()); + metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, pEvent.getKogitoParentProcessInstanceId()); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, pEvent.getKogitoRootProcessId()); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, pEvent.getKogitoRootProcessInstanceId()); + return metadata; + } + + // user task instance stuff + public static UserTaskInstanceStateDataEvent newUserTaskInstanceStateEvent( + String eventUser, String userTaskDefinitionId, String userTaskInstanceId, String userTaskName, String eventType, + String userTaskDescription, String userTaskPriority, String userTaskReferenceName, String state, String actualOwner, String processInstanceId) { + + String processId = UUID.randomUUID().toString(); + String processVersion = "1.0"; + String processType = "BPMN2"; + + UserTaskInstanceStateEventBody body = UserTaskInstanceStateEventBody.create() + .eventUser(eventUser) + .eventDate(new Date()) + .userTaskDefinitionId(userTaskDefinitionId) + .userTaskInstanceId(userTaskInstanceId) + .userTaskName(userTaskName) + .eventType(eventType) + .userTaskDescription(userTaskDescription) + .userTaskDescription(userTaskPriority) + .userTaskReferenceName(userTaskReferenceName) + .state(state) + .actualOwner(actualOwner) + .processInstanceId(processInstanceId) + .build(); + + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, processInstanceId); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, processVersion); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, processId); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(ProcessInstance.STATE_ACTIVE)); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, processType); + metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, null); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, null); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, null); + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_ID_META_DATA, userTaskInstanceId); + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_STATE_META_DATA, state); + + UserTaskInstanceStateDataEvent event = + new UserTaskInstanceStateDataEvent(toURIEndpoint(processId), ADDONS, (String) eventUser, + metadata, body); + + event.setKogitoBusinessKey(UUID.randomUUID().toString()); + return event; + } + + public static UserTaskInstanceVariableDataEvent newUserTaskInstanceVariableEvent(UserTaskInstanceStateDataEvent pEvent, + String eventUser, String variableId, String variableName, String variableType, Object variableValue) { + + UserTaskInstanceVariableEventBody body = UserTaskInstanceVariableEventBody.create() + .eventUser(eventUser) + .eventDate(new Date()) + .userTaskDefinitionId(pEvent.getData().getUserTaskDefinitionId()) + .userTaskInstanceId(pEvent.getData().getUserTaskInstanceId()) + .userTaskName(pEvent.getData().getUserTaskName()) + .variableId(variableId) + .variableName(variableName) + .variableType(variableType) + .variableValue(variableValue) + .build(); + + UserTaskInstanceVariableDataEvent event = + new UserTaskInstanceVariableDataEvent(toURIEndpoint(pEvent.getKogitoProcessId()), ADDONS, + (String) eventUser, + extractUserTaskInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + public static UserTaskInstanceAssignmentDataEvent newUserTaskInstanceAssignmentEvent(UserTaskInstanceStateDataEvent pEvent, + String eventUser, String assigmentType, String... users) { + + UserTaskInstanceAssignmentEventBody body = UserTaskInstanceAssignmentEventBody.create() + .eventUser(eventUser) + .eventDate(new Date()) + .userTaskDefinitionId(pEvent.getData().getUserTaskDefinitionId()) + .userTaskInstanceId(pEvent.getData().getUserTaskInstanceId()) + .userTaskName(pEvent.getData().getUserTaskName()) + .assignmentType(assigmentType) + .users(users) + .build(); + + UserTaskInstanceAssignmentDataEvent event = + new UserTaskInstanceAssignmentDataEvent(toURIEndpoint(pEvent.getKogitoProcessId()), ADDONS, + (String) eventUser, + extractUserTaskInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + public static UserTaskInstanceAttachmentDataEvent newUserTaskInstanceAttachmentEvent(UserTaskInstanceStateDataEvent pEvent, + String eventUser, String attachmentId, String attachmentName, URI attachmentURI, Integer eventType) { + + UserTaskInstanceAttachmentEventBody body = UserTaskInstanceAttachmentEventBody.create() + .eventUser(eventUser) + .eventDate(new Date()) + .userTaskDefinitionId(pEvent.getData().getUserTaskDefinitionId()) + .userTaskInstanceId(pEvent.getData().getUserTaskInstanceId()) + .userTaskName(pEvent.getData().getUserTaskName()) + .attachmentId(attachmentId) + .attachmentName(attachmentName) + .attachmentURI(attachmentURI) + .eventType(eventType) + .build(); + + UserTaskInstanceAttachmentDataEvent event = + new UserTaskInstanceAttachmentDataEvent(toURIEndpoint(pEvent.getKogitoProcessId()), ADDONS, + (String) eventUser, + extractUserTaskInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + public static UserTaskInstanceDeadlineDataEvent newUserTaskInstanceDeadlineEvent(UserTaskInstanceStateDataEvent pEvent, + String eventUser, Map inputs, Map notifications) { + + UserTaskInstanceDeadlineEventBody body = UserTaskInstanceDeadlineEventBody.create() + .eventUser(eventUser) + .eventDate(new Date()) + .userTaskDefinitionId(pEvent.getData().getUserTaskDefinitionId()) + .userTaskInstanceId(pEvent.getData().getUserTaskInstanceId()) + .userTaskName(pEvent.getData().getUserTaskName()) + .inputs(inputs) + .notification(notifications) + .build(); + + UserTaskInstanceDeadlineDataEvent event = + new UserTaskInstanceDeadlineDataEvent(toURIEndpoint(pEvent.getKogitoProcessId()), ADDONS, + (String) eventUser, + extractUserTaskInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + public static UserTaskInstanceCommentDataEvent newUserTaskInstanceCommentEvent(UserTaskInstanceStateDataEvent pEvent, + String eventUser, String commentId, String commentContent, Integer eventType) { + + UserTaskInstanceCommentEventBody body = UserTaskInstanceCommentEventBody.create() + .eventUser(eventUser) + .eventDate(new Date()) + .userTaskDefinitionId(pEvent.getData().getUserTaskDefinitionId()) + .userTaskInstanceId(pEvent.getData().getUserTaskInstanceId()) + .userTaskName(pEvent.getData().getUserTaskName()) + .commentId(commentId) + .commentContent(commentContent) + .eventType(eventType) + .build(); + + UserTaskInstanceCommentDataEvent event = + new UserTaskInstanceCommentDataEvent(toURIEndpoint(pEvent.getKogitoProcessId()), ADDONS, + (String) eventUser, + extractUserTaskInstnaceEventMetadata(pEvent), body); + + event.setKogitoBusinessKey(pEvent.getKogitoBusinessKey()); + return event; + } + + private static Map extractUserTaskInstnaceEventMetadata(UserTaskInstanceDataEvent pEvent) { + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, pEvent.getKogitoProcessInstanceId()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, pEvent.getKogitoProcessInstanceVersion()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, pEvent.getKogitoProcessId()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, pEvent.getKogitoProcessInstanceState()); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, pEvent.getKogitoProcessType()); + metadata.put(ProcessInstanceEventMetadata.PARENT_PROCESS_INSTANCE_ID_META_DATA, pEvent.getKogitoParentProcessInstanceId()); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_ID_META_DATA, pEvent.getKogitoRootProcessId()); + metadata.put(ProcessInstanceEventMetadata.ROOT_PROCESS_INSTANCE_ID_META_DATA, pEvent.getKogitoRootProcessInstanceId()); + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_ID_META_DATA, pEvent.getKogitoUserTaskInstanceId()); + metadata.put(UserTaskInstanceEventMetadata.USER_TASK_INSTANCE_STATE_META_DATA, pEvent.getKogitoUserTaskInstanceState()); + return metadata; + } +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditJobServiceTest.java b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditJobServiceTest.java new file mode 100644 index 0000000000..152306e74d --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditJobServiceTest.java @@ -0,0 +1,354 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.kie.kogito.app.audit.api.SubsystemConstants; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.jobs.service.model.JobStatus; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; + +import jakarta.inject.Inject; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.deriveNewState; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newJobEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.wrapQuery; + +@QuarkusTest +@TestInstance(Lifecycle.PER_CLASS) +public class QuarkusAuditJobServiceTest { + + @Inject + EventPublisher publisher; + + @BeforeAll + public void init() throws Exception { + + JobInstanceDataEvent jobEvent; + jobEvent = newJobEvent("job1", "nodeInstanceId1", 1, "processId1", "processInstanceId1", 100L, 10, "rootProcessId1", "rootProcessInstanceId1", JobStatus.SCHEDULED, 0); + publisher.publish(jobEvent); + + jobEvent = deriveNewState(jobEvent, 1, JobStatus.EXECUTED); + publisher.publish(jobEvent); + + jobEvent = newJobEvent("job2", "nodeInstanceId1", 1, "processId1", "processInstanceId2", 100L, 10, "rootProcessId1", "rootProcessInstanceId1", JobStatus.SCHEDULED, 0); + publisher.publish(jobEvent); + + jobEvent = newJobEvent("job3", "nodeInstanceId1", 1, "processId1", "processInstanceId3", 100L, 10, "rootProcessId1", "rootProcessInstanceId1", JobStatus.SCHEDULED, 0); + publisher.publish(jobEvent); + + jobEvent = deriveNewState(jobEvent, 1, JobStatus.CANCELED); + publisher.publish(jobEvent); + + jobEvent = newJobEvent("job4", "nodeInstanceId1", 1, "processId1", "processInstanceId4", 100L, 10, "rootProcessId1", "rootProcessInstanceId1", JobStatus.SCHEDULED, 0); + publisher.publish(jobEvent); + + jobEvent = deriveNewState(jobEvent, 1, JobStatus.RETRY); + publisher.publish(jobEvent); + + jobEvent = deriveNewState(jobEvent, 2, JobStatus.EXECUTED); + publisher.publish(jobEvent); + + jobEvent = newJobEvent("job5", "nodeInstanceId1", 1, "processId1", "processInstanceI51", 100L, 10, "rootProcessId1", "rootProcessInstanceId1", JobStatus.SCHEDULED, 0); + publisher.publish(jobEvent); + + jobEvent = deriveNewState(jobEvent, 1, JobStatus.ERROR); + publisher.publish(jobEvent); + } + + @Test + public void testGetAllScheduledJobs() { + String query = "{ GetAllScheduledJobs { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + + List> response = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .log() + .body() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllScheduledJobs"); + + assertThat(response) + .hasSize(1) + .extracting(e -> e.get("jobId"), e -> e.get("processInstanceId"), e -> e.get("status")) + .containsExactlyInAnyOrder(tuple("job2", "processInstanceId2", "SCHEDULED")); + + } + + @Test + public void testGetJobById() { + String query = + "{ GetJobById ( jobId : \\\"job1\\\") { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> response = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .log() + .body() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetJobById"); + + assertThat(response) + .hasSize(1); + } + + @Test + public void testGetJobHistoryById() { + String query = + "{ GetJobHistoryById ( jobId : \\\"job4\\\") { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> response = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .log() + .body() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetJobHistoryById"); + + assertThat(response) + .hasSize(3) + .allMatch(e -> "job4".equals(e.get("jobId"))) + .extracting(e -> e.get("status")) + .containsExactlyInAnyOrder("SCHEDULED", "RETRY", "EXECUTED"); + + } + + @Test + public void testGetJobHistoryByProcessInstanceId() { + String query = + "{ GetJobHistoryByProcessInstanceId ( processInstanceId : \\\"processInstanceId4\\\") { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetJobHistoryByProcessInstanceId"); + + assertThat(data) + .hasSize(3) + .allMatch(e -> "job4".equals(e.get("jobId"))) + .allMatch(e -> "processInstanceId4".equals(e.get("processInstanceId"))) + .extracting(e -> e.get("status")) + .containsExactlyInAnyOrder("SCHEDULED", "RETRY", "EXECUTED"); + } + + @Test + public void testGetAllPendingJobs() { + String query = "{ GetAllPendingJobs { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllPendingJobs"); + + assertThat(data).hasSize(1); + } + + @Test + public void testGetAllEligibleJobsForExecution() { + String query = + "{ GetAllEligibleJobsForExecution { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .log() + .body() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllEligibleJobsForExecution"); + + assertThat(data).hasSize(1); + + } + + @Test + public void testGetAllEligibleJobsForRetry() { + String query = + "{ GetAllEligibleJobsForRetry { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllEligibleJobsForRetry"); + + assertThat(data).hasSize(1); + } + + @Test + public void testGetAllJobs() { + String query = "{ GetAllJobs { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllJobs"); + + assertThat(data) + .hasSize(5) + .extracting(e -> e.get("jobId")) + .containsExactlyInAnyOrder("job1", "job2", "job3", "job4", "job5"); + } + + @Test + public void testGetAllCompletedJobs() { + String query = "{ GetAllCompletedJobs { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllCompletedJobs"); + + assertThat(data) + .hasSize(2) + .allMatch(e -> "EXECUTED".equals(e.get("status"))) + .extracting(e -> e.get("jobId")) + .containsExactlyInAnyOrder("job1", "job4"); + } + + @Test + public void testGetAllInErrorJobs() { + + String query = "{ GetAllInErrorJobs { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllInErrorJobs"); + + assertThat(data) + .hasSize(1) + .allMatch(e -> "ERROR".equals(e.get("status"))) + .extracting(e -> e.get("jobId")) + .containsExactlyInAnyOrder("job5"); + } + + @Test + public void testGetAllJobsByStatus() { + + String query = + "{ GetAllJobsByStatus (status : \\\"EXECUTED\\\") { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllJobsByStatus"); + + assertThat(data) + .allMatch(e -> "EXECUTED".equals(e.get("status"))) + .extracting(e -> e.get("jobId")) + .containsExactlyInAnyOrder("job1", "job4"); + } + + @Test + public void testGetJobByProcessInstanceId() { + + String query = + "{ GetJobByProcessInstanceId (processInstanceId : \\\"processInstanceId1\\\") { jobId, expirationTime, priority, processInstanceId, nodeInstanceId, repeatInterval, repeatLimit, scheduledId, retries, status, executionCounter } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetJobByProcessInstanceId"); + + assertThat(data).first() + .hasFieldOrPropertyWithValue("processInstanceId", "processInstanceId1"); + + } + +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditProcessInstanceServiceTest.java b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditProcessInstanceServiceTest.java new file mode 100644 index 0000000000..83f9954039 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditProcessInstanceServiceTest.java @@ -0,0 +1,344 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.kie.kogito.app.audit.api.SubsystemConstants; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.process.ProcessInstanceErrorDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeDataEvent; +import org.kie.kogito.event.process.ProcessInstanceNodeEventBody; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; +import org.kie.kogito.event.process.ProcessInstanceVariableDataEvent; +import org.kie.kogito.process.ProcessInstance; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; + +import jakarta.inject.Inject; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.deriveProcessInstanceStateEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newProcessInstanceErrorEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newProcessInstanceNodeEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newProcessInstanceStateEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newProcessInstanceVariableEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.wrapQuery; + +@QuarkusTest +@TestInstance(Lifecycle.PER_CLASS) +public class QuarkusAuditProcessInstanceServiceTest { + + @Inject + EventPublisher publisher; + + @BeforeAll + public void init() { + + ProcessInstanceStateDataEvent processInstanceEvent; + + // the first process started + processInstanceEvent = newProcessInstanceStateEvent("processId1", "1", ProcessInstance.STATE_ACTIVE, "rootI1", "rootP1", "parent1", "identity", + ProcessInstanceStateEventBody.EVENT_TYPE_STARTED); + publisher.publish(processInstanceEvent); + + ProcessInstanceVariableDataEvent processInstanceVariableEvent = newProcessInstanceVariableEvent(processInstanceEvent, "var_id1", "varName", "errorMessage", "identity"); + publisher.publish(processInstanceVariableEvent); + + processInstanceVariableEvent = newProcessInstanceVariableEvent(processInstanceEvent, "var_id1", "varName", "variableValue", "identity"); + publisher.publish(processInstanceVariableEvent); + + ProcessInstanceNodeDataEvent processInstanceNodeEvent; + processInstanceNodeEvent = newProcessInstanceNodeEvent(processInstanceEvent, "StartNode", "nd1", "ni1", "name1", null, "myuser", ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER); + publisher.publish(processInstanceNodeEvent); + + processInstanceNodeEvent = newProcessInstanceNodeEvent(processInstanceEvent, "StartNode", "nd1", "ni1", "name1", null, "myuser", ProcessInstanceNodeEventBody.EVENT_TYPE_EXIT); + publisher.publish(processInstanceNodeEvent); + + processInstanceNodeEvent = newProcessInstanceNodeEvent(processInstanceEvent, "EndNode", "nd2", "ni2", "name2", null, "myuser", ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER); + publisher.publish(processInstanceNodeEvent); + + // the second completed + processInstanceEvent = newProcessInstanceStateEvent("processId1", "2", ProcessInstance.STATE_ACTIVE, "rootI1", "rootP1", "parent1", "identity", + ProcessInstanceStateEventBody.EVENT_TYPE_STARTED); + publisher.publish(processInstanceEvent); + + processInstanceEvent = deriveProcessInstanceStateEvent(processInstanceEvent, "identity2", ProcessInstance.STATE_COMPLETED, ProcessInstanceStateEventBody.EVENT_TYPE_ENDED); + publisher.publish(processInstanceEvent); + + // the third in error + processInstanceEvent = newProcessInstanceStateEvent("processId2", "3", ProcessInstance.STATE_ACTIVE, "rootI1", "rootP1", "parent1", "identity", + ProcessInstanceStateEventBody.EVENT_TYPE_STARTED); + publisher.publish(processInstanceEvent); + + ProcessInstanceErrorDataEvent processInstanceErrorEvent = newProcessInstanceErrorEvent(processInstanceEvent, "nd1", "ni1", "errorMessage1", "identity"); + publisher.publish(processInstanceErrorEvent); + + processInstanceErrorEvent = newProcessInstanceErrorEvent(processInstanceEvent, "nd2", "ni2", "errorMessage2", "identity"); + publisher.publish(processInstanceErrorEvent); + + processInstanceEvent = deriveProcessInstanceStateEvent(processInstanceEvent, "identity3", ProcessInstance.STATE_ERROR, ProcessInstanceStateEventBody.EVENT_TYPE_ENDED); + publisher.publish(processInstanceEvent); + + } + + @Test + public void testGetAllProcessInstancesState() { + + String query = + "{ GetAllProcessInstancesState { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate, roles} }"; + + query = wrapQuery(query); + + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesState"); + + assertThat(data) + .hasSize(3) + .extracting(e -> e.get("processInstanceId"), e -> e.get("state")) + .containsExactlyInAnyOrder( + tuple("1", String.valueOf(ProcessInstance.STATE_ACTIVE)), + tuple("2", String.valueOf(ProcessInstance.STATE_COMPLETED)), + tuple("3", String.valueOf(ProcessInstance.STATE_ERROR))); + + } + + @Test + public void testGetProcessInstancesStateHistory() { + String query = + "{ GetProcessInstancesStateHistory ( processInstanceId : \\\"2\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate, roles} }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetProcessInstancesStateHistory"); + + assertThat(data) + .hasSize(2) + .extracting(e -> e.get("processInstanceId"), e -> e.get("state")) + .containsExactlyInAnyOrder( + tuple("2", String.valueOf(ProcessInstance.STATE_ACTIVE)), + tuple("2", String.valueOf(ProcessInstance.STATE_COMPLETED))); + + } + + @Test + public void testGetProcessInstancesStateHistoryByBusinessKey() { + String query = + "{ GetProcessInstancesStateHistoryByBusinessKey ( businessKey : \\\"BusinessKey2\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate, roles} }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetProcessInstancesStateHistoryByBusinessKey"); + + assertThat(data) + .hasSize(2) + .extracting(e -> e.get("processInstanceId"), e -> e.get("state")) + .containsExactlyInAnyOrder( + tuple("2", String.valueOf(ProcessInstance.STATE_ACTIVE)), + tuple("2", String.valueOf(ProcessInstance.STATE_COMPLETED))); + + } + + @Test + public void testGetAllProcessInstancesStateByStatus() { + + String query = + "{ GetAllProcessInstancesStateByStatus (status : \\\"1\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate, roles} }"; + + query = wrapQuery(query); + + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesStateByStatus"); + + assertThat(data) + .hasSize(1) + .extracting(e -> e.get("processInstanceId"), e -> e.get("state")) + .containsExactlyInAnyOrder( + tuple("1", String.valueOf(ProcessInstance.STATE_ACTIVE))); + + } + + @Test + public void testGetAllProcessInstancesStateByProcessId() { + + String query = + "{ GetAllProcessInstancesStateByProcessId (processId : \\\"processId1\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate, roles} }"; + + query = wrapQuery(query); + + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesStateByProcessId"); + + assertThat(data) + .hasSize(2) + .extracting(e -> e.get("processInstanceId"), e -> e.get("state")) + .containsExactlyInAnyOrder( + tuple("1", String.valueOf(ProcessInstance.STATE_ACTIVE)), + tuple("2", String.valueOf(ProcessInstance.STATE_COMPLETED))); + + } + + @Test + public void testGetAllProcessInstancesNodeByProcessInstanceId() { + String query = + "{ GetAllProcessInstancesNodeByProcessInstanceId ( processInstanceId : \\\"1\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, nodeType , nodeName, nodeInstanceId, connection, slaDueDate , eventData } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesNodeByProcessInstanceId"); + + assertThat(data) + .hasSize(2) + .extracting(e -> e.get("processInstanceId"), e -> e.get("nodeInstanceId"), e -> e.get("eventType")) + .containsExactlyInAnyOrder( + tuple("1", "ni1", "EXIT"), + tuple("1", "ni2", "ENTER")); + + } + + @Test + public void testGetAllProcessInstancesErrorByProcessInstanceId() { + + String query = + "{ GetAllProcessInstancesErrorByProcessInstanceId ( processInstanceId : \\\"3\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, errorMessage, nodeDefinitionId, nodeInstanceId } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesErrorByProcessInstanceId"); + + assertThat(data) + .hasSize(2) + .extracting(e -> e.get("errorMessage"), e -> e.get("nodeDefinitionId"), e -> e.get("nodeInstanceId")) + .containsExactlyInAnyOrder( + tuple("errorMessage1", "nd1", "ni1"), + tuple("errorMessage2", "nd2", "ni2")); + + } + + @Test + public void testGetAllProcessInstancesVariablebyProcessInstanceId() { + + String query = + "{ GetAllProcessInstancesVariableByProcessInstanceId ( processInstanceId : \\\"1\\\") { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, variableId, variableName, variableValue } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesVariableByProcessInstanceId"); + + assertThat(data) + .hasSize(1) + .extracting(e -> e.get("variableId"), e -> e.get("variableName"), e -> e.get("variableValue")) + .containsExactlyInAnyOrder( + tuple("var_id1", "varName", "variableValue")); + + } + + @Test + public void testGetAllProcessInstancesVariableHistoryByProcessInstanceId() { + + String query = + "{ GetAllProcessInstancesVariableHistoryByProcessInstanceId ( processInstanceId : \\\"1\\\") { variableId, variableName, logs { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, variableId, variableName, variableValue} } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllProcessInstancesVariableHistoryByProcessInstanceId"); + + assertThat(data) + .hasSize(1) + .extracting(e -> e.get("variableId"), e -> e.get("variableName")) + .containsExactlyInAnyOrder( + tuple("var_id1", "varName")); + + } +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditUserTaskInstanceServiceTest.java b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditUserTaskInstanceServiceTest.java new file mode 100644 index 0000000000..f1c7a52ab1 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditUserTaskInstanceServiceTest.java @@ -0,0 +1,252 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.kie.kogito.app.audit.api.SubsystemConstants; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.usertask.UserTaskInstanceAssignmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceAttachmentEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceCommentEventBody; +import org.kie.kogito.event.usertask.UserTaskInstanceDeadlineDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceVariableDataEvent; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; + +import jakarta.inject.Inject; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newUserTaskInstanceAssignmentEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newUserTaskInstanceAttachmentEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newUserTaskInstanceCommentEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newUserTaskInstanceDeadlineEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newUserTaskInstanceStateEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.newUserTaskInstanceVariableEvent; +import static org.kie.kogito.app.audit.quarkus.DataAuditTestUtils.wrapQuery; + +@QuarkusTest +@TestInstance(Lifecycle.PER_CLASS) +public class QuarkusAuditUserTaskInstanceServiceTest { + + @Inject + EventPublisher publisher; + + class Pojo { + public Pojo(Integer value) { + this.value = value; + } + + Integer value; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + } + + @BeforeAll + public void init() { + + UserTaskInstanceStateDataEvent uEvent; + uEvent = newUserTaskInstanceStateEvent("eventUser", "utd1", "1", "utn1", "1", "utd1", "utp1", "utrn1", "Ready", "owner", "1"); + publisher.publish(uEvent); + + uEvent = newUserTaskInstanceStateEvent("eventUser", "utd1", "1", "utn1", "1", "utd1", "utp1", "utrn1", "Claimed", "owner", "1"); + publisher.publish(uEvent); + + UserTaskInstanceVariableDataEvent vEvent; + vEvent = newUserTaskInstanceVariableEvent(uEvent, "eventUser", "varId1", "varName1", "INPUT", new Pojo(1)); + publisher.publish(vEvent); + + vEvent = newUserTaskInstanceVariableEvent(uEvent, "eventUser", "varId1", "varName1", "INPUT", new Pojo(2)); + publisher.publish(vEvent); + + vEvent = newUserTaskInstanceVariableEvent(uEvent, "eventUser", "varId2", "varName2", "OUTPUT", new Pojo(1)); + publisher.publish(vEvent); + + vEvent = newUserTaskInstanceVariableEvent(uEvent, "eventUser", "varId3", "varName3", "OUTPUT", new Pojo(1)); + publisher.publish(vEvent); + + UserTaskInstanceAssignmentDataEvent aEvent; + aEvent = newUserTaskInstanceAssignmentEvent(uEvent, "eventUser", "POT_OWNERS", "user1", "user2", "user3"); + publisher.publish(aEvent); + + aEvent = newUserTaskInstanceAssignmentEvent(uEvent, "eventUser", "ADMINISTRATORS", "user1", "user2", "user3"); + publisher.publish(aEvent); + + UserTaskInstanceAttachmentDataEvent attEvent; + attEvent = newUserTaskInstanceAttachmentEvent(uEvent, "eventUser", "att1", "attName1", URI.create("http://localhost:8080/att1"), + UserTaskInstanceAttachmentEventBody.EVENT_TYPE_ADDED); + publisher.publish(attEvent); + + attEvent = newUserTaskInstanceAttachmentEvent(uEvent, "eventUser", "att2", "attName2", null, + UserTaskInstanceAttachmentEventBody.EVENT_TYPE_DELETED); + publisher.publish(attEvent); + + UserTaskInstanceCommentDataEvent commentEvent; + commentEvent = newUserTaskInstanceCommentEvent(uEvent, "eventUser", "att1", "attName1", UserTaskInstanceCommentEventBody.EVENT_TYPE_ADDED); + publisher.publish(commentEvent); + + UserTaskInstanceDeadlineDataEvent deadlineEvent; + deadlineEvent = newUserTaskInstanceDeadlineEvent(uEvent, "eventUser", Collections.singletonMap("input1", "value1"), Collections.singletonMap("notification1", "notificationValue")); + publisher.publish(deadlineEvent); + + uEvent = newUserTaskInstanceStateEvent("eventUser", "utd2", "2", "utn2", "1", "utd2", "utp2", "utrn2", "Claimed", "owner", "1"); + publisher.publish(uEvent); + + } + + @Test + public void testGetAllUserTaskInstanceState() { + + String query = + "{ GetAllUserTaskInstanceState { eventId, eventDate, userTaskDefinitionId, userTaskInstanceId, processInstanceId, businessKey, name, description, actualUser, state, eventType } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllUserTaskInstanceState"); + + assertThat(data).hasSize(3); + + } + + @Test + public void testGetAllUserTaskInstanceAssignments() { + String query = + "{ GetAllUserTaskInstanceAssignments (userTaskInstanceId : \\\"1\\\") { eventId, eventDate, userTaskDefinitionId, userTaskInstanceId, processInstanceId, businessKey, userTaskName, assignmentType, users } }"; + + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllUserTaskInstanceAssignments"); + + assertThat(data).hasSize(2); + + } + + @Test + public void testGetAllUserTaskInstanceAttachments() { + String query = + "{ GetAllUserTaskInstanceAttachments (userTaskInstanceId : \\\"1\\\") { eventId, eventDate, userTaskDefinitionId, userTaskInstanceId, processInstanceId, businessKey, attachmentId, attachmentName, attachmentURI, eventType } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllUserTaskInstanceAttachments"); + + assertThat(data).hasSize(2); + + } + + @Test + public void testGetAllUserTaskInstanceComment() { + String query = + "{ GetAllUserTaskInstanceComments (userTaskInstanceId : \\\"1\\\") { eventId, eventDate, userTaskDefinitionId, userTaskInstanceId, processInstanceId, businessKey, commentId, commentContent, eventType } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllUserTaskInstanceComments"); + + assertThat(data).hasSize(1); + + } + + @Test + public void testGetAllUserTaskInstanceDeadline() { + String query = + "{ GetAllUserTaskInstanceDeadlines (userTaskInstanceId : \\\"1\\\") { eventId, eventDate, userTaskDefinitionId, userTaskInstanceId, processInstanceId, businessKey, eventType, notification } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllUserTaskInstanceDeadlines"); + + assertThat(data).hasSize(1); + + } + + @Test + public void testGetAllUserTaskInstanceVariable() { + String query = + "{ GetAllUserTaskInstanceVariables (userTaskInstanceId : \\\"1\\\") { eventId, eventDate, userTaskDefinitionId, userTaskInstanceId, processInstanceId, businessKey, variableId, variableName, variableValue, variableType } }"; + query = wrapQuery(query); + List> data = given() + .contentType(ContentType.JSON) + .body(query) + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract().path("data.GetAllUserTaskInstanceVariables"); + + assertThat(data).hasSize(3); + + } +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusEmbeddedJPADataAuditTest.java b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusEmbeddedJPADataAuditTest.java new file mode 100644 index 0000000000..6edbcb0fb9 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusEmbeddedJPADataAuditTest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.quarkus; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.app.audit.api.SubsystemConstants; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.process.ProcessInstanceEventMetadata; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import io.restassured.response.Response; + +import jakarta.inject.Inject; + +import static io.restassured.RestAssured.given; + +@QuarkusTest +public class QuarkusEmbeddedJPADataAuditTest { + private static final Logger LOGGER = LoggerFactory.getLogger(QuarkusEmbeddedJPADataAuditTest.class); + + @Inject + EventPublisher eventPublisher; + + @Test + public void testQuarkusEventPublisher() { + + String processId = "processId"; + String processVersion = "1.0"; + String processType = "BPMN2"; + ProcessInstanceStateEventBody body = ProcessInstanceStateEventBody.create() + .processId(processId) + .processInstanceId("1") + .parentInstanceId(null) + .processType(processType) + .processVersion(processVersion) + .processName(UUID.randomUUID().toString()) + .eventDate(new Date()) + .state(1) + .businessKey(UUID.randomUUID().toString()) + .roles("admin") + .eventUser("myUser") + .eventType(ProcessInstanceStateEventBody.EVENT_TYPE_STARTED) + .build(); + + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, "1"); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, processId); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, processVersion); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(1)); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, processType); + + ProcessInstanceStateDataEvent event = + new ProcessInstanceStateDataEvent("http://localhost:8080/" + processId, "", "myUser", metadata, body); + + event.setKogitoBusinessKey(body.getBusinessKey()); + + eventPublisher.publish(event); + + Response response = given() + .contentType(ContentType.JSON) + .body("{\"query\": \"{ GetAllProcessInstancesState { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate } }\"}") + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract() + .response(); + + LOGGER.info("Data response is {}", response.asPrettyString()); + + } + +} diff --git a/data-audit/kogito-addons-data-audit-quarkus/src/test/resources/application.properties b/data-audit/kogito-addons-data-audit-quarkus/src/test/resources/application.properties new file mode 100644 index 0000000000..21c5f97026 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-quarkus/src/test/resources/application.properties @@ -0,0 +1,10 @@ +quarkus.datasource.db-kind=h2 +quarkus.datasource.username=hibernate +quarkus.datasource.password=hibernate +quarkus.datasource.jdbc.url=jdbc:h2:mem:test + +quarkus.hibernate-orm.database.generation=create-drop + + + + diff --git a/data-audit/kogito-addons-data-audit-springboot/pom.xml b/data-audit/kogito-addons-data-audit-springboot/pom.xml new file mode 100644 index 0000000000..88aa5b5a5b --- /dev/null +++ b/data-audit/kogito-addons-data-audit-springboot/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + org.kie.kogito + data-audit + 999-SNAPSHOT + + + kogito-addons-data-audit-springboot + + Kogito Apps :: Data Audit :: SpringBoot + + + UTF-8 + + + + + + org.kie.kogito + data-audit-common + + + org.kie.kogito + kogito-events-core + + + org.slf4j + slf4j-api + + + + org.springframework.boot + spring-boot-starter + ${version.org.springframework.boot} + + + org.springframework.boot + spring-boot-starter-web + ${version.org.springframework.boot} + + + + + org.springframework.boot + spring-boot-starter-test + ${version.org.springframework.boot} + test + + + io.rest-assured + rest-assured + test + + + + + + + jpa-h2 + + true + + + + + org.kie.kogito + kogito-addons-data-audit-jpa-springboot + + + + + + diff --git a/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/GraphQLJPAAuditDataRouteMapping.java b/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/GraphQLJPAAuditDataRouteMapping.java new file mode 100644 index 0000000000..4d99ceff1a --- /dev/null +++ b/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/GraphQLJPAAuditDataRouteMapping.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.springboot; + +import java.util.Map; + +import org.kie.kogito.app.audit.api.DataAuditQueryService; +import org.kie.kogito.app.audit.spi.DataAuditContextFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.databind.JsonNode; + +import graphql.ExecutionResult; +import jakarta.annotation.PostConstruct; + +import static org.kie.kogito.app.audit.api.SubsystemConstants.DATA_AUDIT_PATH; + +@RestController +@Transactional +public class GraphQLJPAAuditDataRouteMapping { + + private DataAuditQueryService dataAuditQueryService; + + @Autowired + DataAuditContextFactory dataAuditContextFactory; + + @PostConstruct + public void init() { + dataAuditQueryService = DataAuditQueryService.newAuditQuerySerice(); + + } + + @PostMapping(value = DATA_AUDIT_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public Map executeQuery(@RequestBody JsonNode query) { + ExecutionResult executionResult = dataAuditQueryService.executeQuery(dataAuditContextFactory.newDataAuditContext(), query.get("query").asText()); + return executionResult.toSpecification(); + } + +} diff --git a/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootAuditDataConfiguration.java b/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootAuditDataConfiguration.java new file mode 100644 index 0000000000..f7cbe6c52a --- /dev/null +++ b/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootAuditDataConfiguration.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.springboot; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootConfiguration +@EnableAutoConfiguration +@ComponentScan +public class SpringbootAuditDataConfiguration { + +} diff --git a/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditEventPublisher.java b/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditEventPublisher.java new file mode 100644 index 0000000000..9f011e3394 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditEventPublisher.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.springboot; + +import java.util.Collection; + +import org.kie.kogito.app.audit.api.DataAuditStoreProxyService; +import org.kie.kogito.app.audit.spi.DataAuditContextFactory; +import org.kie.kogito.event.DataEvent; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.job.JobInstanceDataEvent; +import org.kie.kogito.event.process.ProcessInstanceDataEvent; +import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Component +@Transactional +public class SpringbootJPADataAuditEventPublisher implements EventPublisher { + + private static final Logger LOGGER = LoggerFactory.getLogger(SpringbootJPADataAuditEventPublisher.class); + + private DataAuditStoreProxyService proxy; + + @Autowired + DataAuditContextFactory dataAuditContextFactory; + + public SpringbootJPADataAuditEventPublisher() { + proxy = DataAuditStoreProxyService.newAuditStoreService(); + } + + @Override + public void publish(Collection> events) { + events.forEach(this::publish); + } + + @Override + + public void publish(DataEvent event) { + if (event instanceof ProcessInstanceDataEvent) { + LOGGER.debug("Processing process instance event {}", event); + proxy.storeProcessInstanceDataEvent(dataAuditContextFactory.newDataAuditContext(), (ProcessInstanceDataEvent) event); + return; + } else if (event instanceof UserTaskInstanceDataEvent) { + LOGGER.debug("Processing user task instacne event {}", event); + proxy.storeUserTaskInstanceDataEvent(dataAuditContextFactory.newDataAuditContext(), (UserTaskInstanceDataEvent) event); + return; + } else if (event instanceof JobInstanceDataEvent) { + LOGGER.info("Processing job instance event {}", event); + proxy.storeJobDataEvent(dataAuditContextFactory.newDataAuditContext(), (JobInstanceDataEvent) event); + return; + } + + LOGGER.debug("Discard event {} as class {} is not supported by this", event, event.getClass().getName()); + } + +} diff --git a/data-audit/kogito-addons-data-audit-springboot/src/test/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditTest.java b/data-audit/kogito-addons-data-audit-springboot/src/test/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditTest.java new file mode 100644 index 0000000000..0ffc2136a3 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-springboot/src/test/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditTest.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.kogito.app.audit.springboot; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.app.audit.api.SubsystemConstants; +import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.process.ProcessInstanceEventMetadata; +import org.kie.kogito.event.process.ProcessInstanceStateDataEvent; +import org.kie.kogito.event.process.ProcessInstanceStateEventBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; + +import io.restassured.http.ContentType; +import io.restassured.response.Response; + +import static io.restassured.RestAssured.given; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server_port=0") +public class SpringbootJPADataAuditTest { + private static final Logger LOGGER = LoggerFactory.getLogger(SpringbootJPADataAuditTest.class); + + @LocalServerPort + int randomServerPort; + + @Autowired + EventPublisher eventPublisher; + + @Test + public void testSpringbootEventPublisher() { + + String processId = "processId"; + String processVersion = "1.0"; + String processType = "BPMN2"; + ProcessInstanceStateEventBody body = ProcessInstanceStateEventBody.create() + .processId(processId) + .processInstanceId("1") + .parentInstanceId(null) + .processType(processType) + .processVersion(processVersion) + .processName(UUID.randomUUID().toString()) + .eventDate(new Date()) + .state(1) + .businessKey(UUID.randomUUID().toString()) + .roles("admin") + .eventUser("myUser") + .eventType(ProcessInstanceStateEventBody.EVENT_TYPE_STARTED) + .build(); + + Map metadata = new HashMap<>(); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_ID_META_DATA, "1"); + metadata.put(ProcessInstanceEventMetadata.PROCESS_ID_META_DATA, processId); + metadata.put(ProcessInstanceEventMetadata.PROCESS_VERSION_META_DATA, processVersion); + metadata.put(ProcessInstanceEventMetadata.PROCESS_INSTANCE_STATE_META_DATA, String.valueOf(1)); + metadata.put(ProcessInstanceEventMetadata.PROCESS_TYPE_META_DATA, processType); + + ProcessInstanceStateDataEvent event = + new ProcessInstanceStateDataEvent("http://localhost:8080/" + processId, "", "myUser", metadata, body); + + event.setKogitoBusinessKey(body.getBusinessKey()); + + eventPublisher.publish(event); + + Response response = given() + .port(randomServerPort) + .contentType(ContentType.JSON) + .body("{\"query\": \"{ GetAllProcessInstancesState { eventId, eventDate, processType, processId, processVersion, parentProcessInstanceId, rootProcessId, rootProcessInstanceId, processInstanceId, businessKey, eventType, outcome, state, slaDueDate } }\"}") + .when() + .post(SubsystemConstants.DATA_AUDIT_PATH) + .then() + .assertThat() + .statusCode(200) + .and() + .extract() + .response(); + + LOGGER.info("Data response is {}", response.asPrettyString()); + + } + +} diff --git a/data-audit/kogito-addons-data-audit-springboot/src/test/resources/application.properties b/data-audit/kogito-addons-data-audit-springboot/src/test/resources/application.properties new file mode 100644 index 0000000000..60ec8b5691 --- /dev/null +++ b/data-audit/kogito-addons-data-audit-springboot/src/test/resources/application.properties @@ -0,0 +1,10 @@ +# configure data source + +spring.datasource.jdbc-url=jdbc:h2:mem:test +spring.datasource.driver-class-name=org.h2.Driver + +spring.jpa.database=H2 +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect +spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop + + diff --git a/data-audit/pom.xml b/data-audit/pom.xml new file mode 100644 index 0000000000..103a871d43 --- /dev/null +++ b/data-audit/pom.xml @@ -0,0 +1,30 @@ + + + + + + org.kie.kogito + kogito-apps-build-parent + 999-SNAPSHOT + ../kogito-apps-build-parent/pom.xml + + + + 4.0.0 + data-audit + pom + Kogito Apps :: Data Audit :: App + + + + data-audit-common + data-audit-common-service + kogito-addons-data-audit-jpa + kogito-addons-data-audit-quarkus + kogito-addons-data-audit-springboot + data-audit-quarkus-service + + + diff --git a/data-index/data-index-common/.gitignore b/data-index/data-index-common/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/data-index/data-index-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/Merger.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/Merger.java index 0f685661ed..b036703303 100644 --- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/Merger.java +++ b/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/Merger.java @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.kie.kogito.index.event.mapper; public interface Merger { diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/ProcessInstanceNodeDataEventMerger.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/ProcessInstanceNodeDataEventMerger.java index c3ad9ede1b..da5d9e1339 100644 --- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/ProcessInstanceNodeDataEventMerger.java +++ b/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/ProcessInstanceNodeDataEventMerger.java @@ -36,8 +36,6 @@ import jakarta.enterprise.context.ApplicationScoped; -import static org.kie.kogito.event.process.ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER; -import static org.kie.kogito.event.process.ProcessInstanceNodeEventBody.EVENT_TYPE_EXIT; import static org.kie.kogito.index.DateTimeUtils.toZonedDateTime; @ApplicationScoped @@ -68,10 +66,13 @@ public ProcessInstance merge(ProcessInstance pi, ProcessInstanceDataEvent dat nodeInstance.setName(body.getNodeName()); nodeInstance.setType(body.getNodeType()); switch (body.getEventType()) { - case EVENT_TYPE_ENTER: + case ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER: nodeInstance.setEnter(toZonedDateTime(body.getEventDate())); break; - case EVENT_TYPE_EXIT: + case ProcessInstanceNodeEventBody.EVENT_TYPE_ERROR: + // we do noothing + break; + default: nodeInstance.setExit(toZonedDateTime(body.getEventDate())); if (nodeInstance.getEnter() == null) { diff --git a/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/UserTaskInstanceStateEventMerger.java b/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/UserTaskInstanceStateEventMerger.java index 8689b1fd85..7fa52f5b1f 100644 --- a/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/UserTaskInstanceStateEventMerger.java +++ b/data-index/data-index-common/src/main/java/org/kie/kogito/index/event/mapper/UserTaskInstanceStateEventMerger.java @@ -19,6 +19,7 @@ package org.kie.kogito.index.event.mapper; import java.net.URI; +import java.util.List; import org.kie.kogito.event.usertask.UserTaskInstanceDataEvent; import org.kie.kogito.event.usertask.UserTaskInstanceStateDataEvent; @@ -44,6 +45,8 @@ public boolean accept(Object event) { @Override public UserTaskInstance merge(UserTaskInstance task, UserTaskInstanceDataEvent data) { + List finalState = List.of("Completed", "Aborted"); + UserTaskInstanceStateDataEvent event = (UserTaskInstanceStateDataEvent) data; LOGGER.debug("value before merging: {}", task); task.setId(event.getData().getUserTaskInstanceId()); @@ -55,9 +58,9 @@ public UserTaskInstance merge(UserTaskInstance task, UserTaskInstanceDataEvent eventPublisher; private final ObjectMapper objectMapper; @@ -64,10 +67,7 @@ public EventPublisherJobStreams(@ConfigProperty(name = "kogito.service.url", def Instance eventPublishers, ObjectMapper objectMapper) { this.url = url; - eventPublisher = eventPublishers.stream() - .filter(publisher -> publisher.getClass().getName().startsWith(DATA_INDEX_EVENT_PUBLISHER)) - .findFirst() - .orElse(null); + eventPublisher = eventPublishers.stream().collect(Collectors.toList()); this.objectMapper = objectMapper; } @@ -83,7 +83,7 @@ public void onJobStatusChange(JobDetails jobDetails) { } catch (Exception e) { throw new JobsServiceException("It was not possible to serialize scheduledJob to json: " + scheduledJob, e); } - EventPublisherJobDataEvent event = new EventPublisherJobDataEvent(JOB_EVENT_TYPE, + JobInstanceDataEvent event = new JobInstanceDataEvent(JOB_EVENT_TYPE, url + RestApiConstants.JOBS_PATH, jsonContent, scheduledJob.getProcessInstanceId(), @@ -92,24 +92,11 @@ public void onJobStatusChange(JobDetails jobDetails) { scheduledJob.getRootProcessId(), null); try { - eventPublisher.publish(event); + eventPublisher.forEach(e -> e.publish(event)); } catch (Exception e) { LOGGER.error("Job status change propagation has failed at eventPublisher: " + eventPublisher.getClass() + " execution.", e); } } } - public static class EventPublisherJobDataEvent extends AbstractDataEvent { - public EventPublisherJobDataEvent(String type, - String source, - byte[] data, - String kogitoProcessInstanceId, - String kogitoRootProcessInstanceId, - String kogitoProcessId, - String kogitoRootProcessId, - String kogitoIdentity) { - super(type, source, data, kogitoProcessInstanceId, kogitoRootProcessInstanceId, kogitoProcessId, - kogitoRootProcessId, null, kogitoIdentity); - } - } } diff --git a/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs-service-embedded/runtime/src/test/java/org/kie/kogito/addons/quarkus/jobs/service/embedded/stream/EventPublisherJobStreamsTest.java b/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs-service-embedded/runtime/src/test/java/org/kie/kogito/addons/quarkus/jobs/service/embedded/stream/EventPublisherJobStreamsTest.java index d66b6910b1..3fec2fee68 100644 --- a/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs-service-embedded/runtime/src/test/java/org/kie/kogito/addons/quarkus/jobs/service/embedded/stream/EventPublisherJobStreamsTest.java +++ b/jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs-service-embedded/runtime/src/test/java/org/kie/kogito/addons/quarkus/jobs/service/embedded/stream/EventPublisherJobStreamsTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test; import org.kie.kogito.event.EventPublisher; +import org.kie.kogito.event.job.JobInstanceDataEvent; import org.kie.kogito.index.addon.DataIndexEventPublisherMock; import org.kie.kogito.jobs.service.api.recipient.http.HttpRecipient; import org.kie.kogito.jobs.service.model.JobDetails; @@ -87,7 +88,7 @@ class EventPublisherJobStreamsTest { @Test void onJobStatusChange() throws Exception { - ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(EventPublisherJobStreams.EventPublisherJobDataEvent.class); + ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(JobInstanceDataEvent.class); DataIndexEventPublisherMock eventPublisher = spy(new DataIndexEventPublisherMock()); Instance eventPublisherInstance = mock(Instance.class); Stream eventPublishers = Arrays.stream(new EventPublisher[] { eventPublisher }); @@ -104,7 +105,7 @@ void onJobStatusChange() throws Exception { verify(eventPublisher).publish(eventCaptor.capture()); verify(eventPublisher, never()).publish(anyCollection()); - EventPublisherJobStreams.EventPublisherJobDataEvent event = eventCaptor.getValue(); + JobInstanceDataEvent event = eventCaptor.getValue(); assertThat(event).isNotNull(); assertThat(event.getSpecVersion()).hasToString("1.0"); diff --git a/kogito-apps-bom/pom.xml b/kogito-apps-bom/pom.xml index 095dae2910..3bf624ca5c 100644 --- a/kogito-apps-bom/pom.xml +++ b/kogito-apps-bom/pom.xml @@ -20,8 +20,8 @@ --> + 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"> kogito-apps org.kie.kogito @@ -114,6 +114,71 @@ ${project.version} sources + + + org.kie.kogito + data-audit-common + ${project.version} + + + org.kie.kogito + data-audit-common-service + ${project.version} + + + org.kie.kogito + data-audit-quarkus-tck + ${project.version} + + + org.kie.kogito + data-audit-quarkus-tck + ${project.version} + test-jar + + + org.kie.kogito + data-audit-springboot-tck + ${project.version} + + + org.kie.kogito + data-audit-springboot-tck + ${project.version} + test-jar + + + org.kie.kogito + data-audit-quarkus-service + ${project.version} + + + org.kie.kogito + kogito-addons-data-audit-quarkus + ${project.version} + + + org.kie.kogito + kogito-addons-data-audit-springboot + ${project.version} + + + + org.kie.kogito + kogito-addons-data-audit-jpa-common + ${project.version} + + + org.kie.kogito + kogito-addons-data-audit-jpa-quarkus + ${project.version} + + + org.kie.kogito + kogito-addons-data-audit-jpa-springboot + ${project.version} + + @@ -288,47 +353,51 @@ org.kie.kogito - kogito-addons-quarkus-data-index-persistence-common-runtime + + kogito-addons-quarkus-data-index-persistence-common-runtime ${project.version} org.kie.kogito - kogito-addons-quarkus-data-index-persistence-common-runtime + + kogito-addons-quarkus-data-index-persistence-common-runtime ${project.version} sources org.kie.kogito - kogito-addons-quarkus-data-index-persistence-common-deployment + + kogito-addons-quarkus-data-index-persistence-common-deployment ${project.version} org.kie.kogito - kogito-addons-quarkus-data-index-persistence-common-deployment + + kogito-addons-quarkus-data-index-persistence-common-deployment ${project.version} sources - org.kie.kogito - kogito-addons-quarkus-data-index-common-runtime - ${project.version} + org.kie.kogito + kogito-addons-quarkus-data-index-common-runtime + ${project.version} - org.kie.kogito - kogito-addons-quarkus-data-index-common-runtime - ${project.version} - sources + org.kie.kogito + kogito-addons-quarkus-data-index-common-runtime + ${project.version} + sources - org.kie.kogito - kogito-addons-quarkus-data-index-common-deployment - ${project.version} + org.kie.kogito + kogito-addons-quarkus-data-index-common-deployment + ${project.version} - org.kie.kogito - kogito-addons-quarkus-data-index-common-deployment - ${project.version} - sources + org.kie.kogito + kogito-addons-quarkus-data-index-common-deployment + ${project.version} + sources @@ -506,55 +575,55 @@ ${project.version} javadoc - - - org.kie.kogito - jitexecutor-common - ${project.version} - - - org.kie.kogito - jitexecutor-common - ${project.version} - sources - - - org.kie.kogito - jitexecutor-common - ${project.version} - javadoc - - - org.kie.kogito - jitexecutor-common - ${project.version} - test-jar - test - + + + org.kie.kogito + jitexecutor-common + ${project.version} + + + org.kie.kogito + jitexecutor-common + ${project.version} + sources + + + org.kie.kogito + jitexecutor-common + ${project.version} + javadoc + + + org.kie.kogito + jitexecutor-common + ${project.version} + test-jar + test + - org.kie.kogito - jitexecutor-bpmn - ${project.version} + org.kie.kogito + jitexecutor-bpmn + ${project.version} - org.kie.kogito - jitexecutor-bpmn - ${project.version} - sources + org.kie.kogito + jitexecutor-bpmn + ${project.version} + sources - org.kie.kogito - jitexecutor-bpmn - ${project.version} - javadoc + org.kie.kogito + jitexecutor-bpmn + ${project.version} + javadoc - org.kie.kogito - jitexecutor-bpmn - ${project.version} - test-jar - test + org.kie.kogito + jitexecutor-bpmn + ${project.version} + test-jar + test diff --git a/pom.xml b/pom.xml index 5f4aaa355a..d4defab9d2 100644 --- a/pom.xml +++ b/pom.xml @@ -66,6 +66,7 @@ persistence-commons jobs-service data-index + data-audit ui-packages security-commons management-console