From c69c9964c139f53bae0492adae41edaba57ebef3 Mon Sep 17 00:00:00 2001 From: Enrique Date: Wed, 27 Dec 2023 15:09:51 +0100 Subject: [PATCH] [incubator-kie-issues-576] Data Audit apps for kogito (#1905) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [incubator-kie-issues-576] Data Audit app for kogito * [incubator-kie-issues-576] add tests for data audit * added data audit context to local * make proxy independent of runtime * tweak events * fix deletion of spring boot subsystem * fix logic in data audit * fix tests * fix json objects in variable values * added pagination * fix roles in process state query * add mechanism extension * fix for assignments * fix deadlines notifications * fix spring boot test * add queries for processes * repacle anonymous classe by reusable classes * job log changed to match data index * add microprofile to subsystem * make context factory independent * fix names * readme.md * fix compilation problems * fix artifact id and added new query * fix master pom adding data audit module * fix names in the projects to fit naming conventions * formatting pom.xml * setting configuration * fix service * fix jdbc driver dependencies * fix jdbc driver dependencies * added jpa container service * Fix naming conventions for tables * fix sla * fix configuration. simplification * fix service * fix for orm * fix classloader * clean unnecessary fields * fix readme.md * fix transaction error in springboot * fix try for transactions wthout transaction manager provider * fix * fix query * fix plural queries * Quarkus 3 upgrade fixes: - `999-SNAPSHOT` version bump - javax to jakarta migration - test fixes * - fix log --------- Co-authored-by: Pere Fernández --- data-audit/.gitignore | 167 +++++ data-audit/README.md | 84 +++ data-audit/data-audit-common-service/pom.xml | 40 ++ .../json/JsonJobDataEventDeserializer.java | 70 ++ ...nProcessInstanceDataEventDeserializer.java | 76 ++ ...UserTaskInstanceDataEventDeserializer.java | 79 +++ .../kie/kogito/app/audit/json/JsonUtils.java | 55 ++ .../audit/kafka/JobDataEventDeserializer.java | 43 ++ .../ProcessInstanceDataEventDeserializer.java | 43 ++ ...UserTaskInstanceDataEventDeserializer.java | 43 ++ data-audit/data-audit-common/.gitignore | 1 + data-audit/data-audit-common/pom.xml | 42 ++ .../app/audit/api/DataAuditContext.java | 38 + .../app/audit/api/DataAuditQueryService.java | 68 ++ .../audit/api/DataAuditStoreProxyService.java | 84 +++ .../app/audit/api/SubsystemConstants.java | 32 + .../kie/kogito/app/audit/api/TypeCheck.java | 40 ++ .../audit/graphql/GraphQLSchemaManager.java | 124 ++++ .../audit/graphql/type/JobExecutionTO.java | 167 +++++ .../app/audit/graphql/type/JsonUtil.java | 39 + .../graphql/type/ProcessInstanceErrorTO.java | 174 +++++ .../graphql/type/ProcessInstanceNodeTO.java | 232 ++++++ .../graphql/type/ProcessInstanceStateTO.java | 201 ++++++ .../ProcessInstanceVariableHistoryTO.java | 64 ++ .../type/ProcessInstanceVariableTO.java | 176 +++++ .../type/UserTaskInstanceAssignmentTO.java | 152 ++++ .../type/UserTaskInstanceAttachmentTO.java | 155 ++++ .../type/UserTaskInstanceCommentTO.java | 131 ++++ .../type/UserTaskInstanceDeadlineTO.java | 129 ++++ .../graphql/type/UserTaskInstanceStateTO.java | 153 ++++ .../type/UserTaskInstanceVariableTO.java | 144 ++++ .../audit/spi/DataAuditContextFactory.java | 28 + .../kogito/app/audit/spi/DataAuditStore.java | 61 ++ .../app/audit/spi/GraphQLSchemaQuery.java | 29 + .../audit/spi/GraphQLSchemaQueryProvider.java | 31 + .../META-INF/data-audit-job-query.graphqls | 21 + .../data-audit-process-query.graphqls | 15 + .../META-INF/data-audit-types.graphqls | 183 +++++ .../data-audit-usertask-query.graphqls | 8 + data-audit/data-audit-quarkus-service/pom.xml | 110 +++ .../audit/quarkus/QuarkusDataAuditMain.java | 30 + ...uarkusDataAuditMessagingEventConsumer.java | 71 ++ .../src/main/resources/META-INF/beans.xml | 0 .../META-INF/microprofile-config.properties | 45 ++ .../src/main/resources/application.properties | 1 + data-audit/img/design.png | Bin 0 -> 39375 bytes .../data-audit-quarkus-jpa-service/pom.xml | 55 ++ .../src/main/resources/META-INF/beans.xml | 0 .../src/main/resources/application.properties | 13 + .../.gitignore | 1 + .../pom.xml | 104 +++ .../app/audit/jpa/JPADataAuditStore.java | 400 +++++++++++ .../jpa/model/AbstractProcessInstanceLog.java | 158 +++++ .../model/AbstractUserTaskInstanceLog.java | 116 +++ .../app/audit/jpa/model/JobExecutionLog.java | 181 +++++ .../app/audit/jpa/model/ModelConstants.java | 28 + .../jpa/model/ProcessInstanceErrorLog.java | 94 +++ .../jpa/model/ProcessInstanceNodeLog.java | 165 +++++ .../jpa/model/ProcessInstanceStateLog.java | 128 ++++ .../jpa/model/ProcessInstanceVariableLog.java | 87 +++ .../model/UserTaskInstanceAssignmentLog.java | 111 +++ .../model/UserTaskInstanceAttachmentLog.java | 93 +++ .../jpa/model/UserTaskInstanceCommentLog.java | 81 +++ .../model/UserTaskInstanceDeadlineLog.java | 79 +++ .../jpa/model/UserTaskInstanceStateLog.java | 99 +++ .../model/UserTaskInstanceVariableLog.java | 99 +++ .../app/audit/jpa/queries/DataMapper.java | 25 + .../audit/jpa/queries/JPAAbstractQuery.java | 68 ++ .../jpa/queries/JPAComplexNamedQuery.java | 64 ++ .../JPAGraphQLSchemaJobsQueryProvider.java | 48 ++ ...QLSchemaProcessInstancesQueryProvider.java | 51 ++ ...LSchemaUserTaskInstancesQueryProvider.java | 54 ++ .../jpa/queries/JPASimpleNamedQuery.java | 67 ++ .../app/audit/jpa/queries/MappingFile.java | 74 ++ .../audit/jpa/queries/mapper/PojoMapper.java | 59 ++ .../mapper/ProcessInstanceStateTOMapper.java | 69 ++ ...rocessInstanceVariableHistoryTOMapper.java | 65 ++ .../UserTaskInstanceAssignmentTOMapper.java | 65 ++ .../UserTaskInstanceDeadlineTOMapper.java | 63 ++ .../src/main/resources/META-INF/beans.xml | 0 .../resources/META-INF/data-audit-orm.xml | 666 ++++++++++++++++++ ...rg.kie.kogito.app.audit.spi.DataAuditStore | 1 + ...o.app.audit.spi.GraphQLSchemaQueryProvider | 3 + .../pom.xml | 80 +++ .../QuarkusJPADataAuditContextFactory.java | 39 + .../src/main/resources/META-INF/beans.xml | 0 .../src/main/resources/application.properties | 3 + .../pom.xml | 58 ++ .../SpringbootJPAAuditDataConfiguration.java | 30 + .../SpringbootJPADataAuditContextFactory.java | 39 + .../kogito-addons-data-audit-jpa/pom.xml | 27 + .../kogito-addons-data-audit-quarkus/pom.xml | 120 ++++ .../quarkus/GraphQLJPADataAuditRouter.java | 69 ++ .../QuarkusJPADataAuditEventPublisher.java | 79 +++ .../src/main/resources/META-INF/beans.xml | 0 .../app/audit/quarkus/DataAuditTestUtils.java | 442 ++++++++++++ .../quarkus/QuarkusAuditJobServiceTest.java | 354 ++++++++++ ...uarkusAuditProcessInstanceServiceTest.java | 344 +++++++++ ...arkusAuditUserTaskInstanceServiceTest.java | 252 +++++++ .../QuarkusEmbeddedJPADataAuditTest.java | 101 +++ .../src/test/resources/application.properties | 10 + .../pom.xml | 77 ++ .../GraphQLJPAAuditDataRouteMapping.java | 60 ++ .../SpringbootAuditDataConfiguration.java | 30 + .../SpringbootJPADataAuditEventPublisher.java | 76 ++ .../SpringbootJPADataAuditTest.java | 105 +++ .../src/test/resources/application.properties | 10 + data-audit/pom.xml | 30 + data-index/data-index-common/.gitignore | 1 + .../kie/kogito/index/event/mapper/Merger.java | 19 + .../ProcessInstanceNodeDataEventMerger.java | 9 +- .../UserTaskInstanceStateEventMerger.java | 7 +- data-index/data-index-graphql/.gitignore | 1 + .../data-index-service-common/.gitignore | 1 + .../AbstractDomainIndexingServiceIT.java | 4 +- .../service/AbstractIndexingServiceIT.java | 6 +- .../AbstractGraphQLRuntimesQueriesIT.java | 16 +- .../data-index-service-infinispan/.gitignore | 1 + .../data-index-storage-postgresql/.gitignore | 1 + .../org/kie/kogito/index/test/TestUtils.java | 4 +- .../stream/EventPublisherJobStreams.java | 29 +- .../stream/EventPublisherJobStreamsTest.java | 5 +- kogito-apps-bom/pom.xml | 191 +++-- pom.xml | 1 + 124 files changed, 9839 insertions(+), 105 deletions(-) create mode 100644 data-audit/.gitignore create mode 100644 data-audit/README.md create mode 100644 data-audit/data-audit-common-service/pom.xml create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonJobDataEventDeserializer.java create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonProcessInstanceDataEventDeserializer.java create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUserTaskInstanceDataEventDeserializer.java create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/json/JsonUtils.java create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/JobDataEventDeserializer.java create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/ProcessInstanceDataEventDeserializer.java create mode 100644 data-audit/data-audit-common-service/src/main/java/org/kie/kogito/app/audit/kafka/UserTaskInstanceDataEventDeserializer.java create mode 100644 data-audit/data-audit-common/.gitignore create mode 100644 data-audit/data-audit-common/pom.xml create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditContext.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditQueryService.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/DataAuditStoreProxyService.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/SubsystemConstants.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/api/TypeCheck.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/GraphQLSchemaManager.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JobExecutionTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/JsonUtil.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceErrorTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceNodeTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceStateTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableHistoryTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/ProcessInstanceVariableTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAssignmentTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceAttachmentTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceCommentTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceDeadlineTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceStateTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/graphql/type/UserTaskInstanceVariableTO.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditContextFactory.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/DataAuditStore.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQuery.java create mode 100644 data-audit/data-audit-common/src/main/java/org/kie/kogito/app/audit/spi/GraphQLSchemaQueryProvider.java create mode 100644 data-audit/data-audit-common/src/main/resources/META-INF/data-audit-job-query.graphqls create mode 100644 data-audit/data-audit-common/src/main/resources/META-INF/data-audit-process-query.graphqls create mode 100644 data-audit/data-audit-common/src/main/resources/META-INF/data-audit-types.graphqls create mode 100644 data-audit/data-audit-common/src/main/resources/META-INF/data-audit-usertask-query.graphqls create mode 100644 data-audit/data-audit-quarkus-service/pom.xml create mode 100644 data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMain.java create mode 100644 data-audit/data-audit-quarkus-service/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusDataAuditMessagingEventConsumer.java create mode 100644 data-audit/data-audit-quarkus-service/src/main/resources/META-INF/beans.xml create mode 100644 data-audit/data-audit-quarkus-service/src/main/resources/META-INF/microprofile-config.properties create mode 100644 data-audit/data-audit-quarkus-service/src/main/resources/application.properties create mode 100644 data-audit/img/design.png create mode 100644 data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/META-INF/beans.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/data-audit-quarkus-jpa-service/src/main/resources/application.properties create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/.gitignore create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/java/org/kie/kogito/app/audit/jpa/JPADataAuditStore.java create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/beans.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-common/src/main/resources/META-INF/data-audit-orm.xml create mode 100644 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 create mode 100644 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 create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditContextFactory.java create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/META-INF/beans.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-quarkus/src/main/resources/application.properties create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPAAuditDataConfiguration.java create mode 100644 data-audit/kogito-addons-data-audit-jpa/kogito-addons-data-audit-jpa-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditContextFactory.java create mode 100644 data-audit/kogito-addons-data-audit-jpa/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-quarkus/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/GraphQLJPADataAuditRouter.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/main/java/org/kie/kogito/app/audit/quarkus/QuarkusJPADataAuditEventPublisher.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/main/resources/META-INF/beans.xml create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/DataAuditTestUtils.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditJobServiceTest.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditProcessInstanceServiceTest.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusAuditUserTaskInstanceServiceTest.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/test/java/org/kie/kogito/app/audit/quarkus/QuarkusEmbeddedJPADataAuditTest.java create mode 100644 data-audit/kogito-addons-data-audit-quarkus/src/test/resources/application.properties create mode 100644 data-audit/kogito-addons-data-audit-springboot/pom.xml create mode 100644 data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/GraphQLJPAAuditDataRouteMapping.java create mode 100644 data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootAuditDataConfiguration.java create mode 100644 data-audit/kogito-addons-data-audit-springboot/src/main/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditEventPublisher.java create mode 100644 data-audit/kogito-addons-data-audit-springboot/src/test/java/org/kie/kogito/app/audit/springboot/SpringbootJPADataAuditTest.java create mode 100644 data-audit/kogito-addons-data-audit-springboot/src/test/resources/application.properties create mode 100644 data-audit/pom.xml create mode 100644 data-index/data-index-common/.gitignore create mode 100644 data-index/data-index-graphql/.gitignore create mode 100644 data-index/data-index-service/data-index-service-common/.gitignore create mode 100644 data-index/data-index-service/data-index-service-infinispan/.gitignore create mode 100644 data-index/data-index-storage/data-index-storage-postgresql/.gitignore 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 0000000000000000000000000000000000000000..f12aafeac0cbc3ef460f2d6029510526b8f6b0d4 GIT binary patch literal 39375 zcmeFZcRbhq`#${ER9)>!q(OtwK(d>9lbMx_t3>velGUO?$}F<7-Uta?g0_zd0Na=r|s+F>!Q0Zg0#uWo=_+ zEa+flZ)|MsU~1#oJH1eb!C1>+?%$(v=I;0AvpRu86O(-*@j)D{nhuR$(q<;JLKTlj z3CbyiDaF^PuL{|dl2&V1zJhhvL82y8?#?@%==cSRt?I1HcSI9!hF*+&wD;(WhMUIM zC4%RLj!m@g8m?2*(71j4tW4_lu50H^dd}{XcsCw8{CmJm!@$5m2v0~~qDgkFd4IlT za8A1*{^#4Z?Cf|y`tn@6_R91>-(K)syWr1v?EmM3|7UsrKQM|58>5AyHhyVu7m$^e ztu|&1X*E8ws>!x7%(86QQ5{E5kfqLKUhN+k&{S7n(y3l9muX(3pr7Zcrl+UJQryGW zX}l=g?f2=I#l>B1ezFUkw#XIKJv3HSy1i}BitBv;UP3`jE7(6EV4wahPF7BixS(Fn z&7!Ni@oH!B#k$V2?(6G&Q&y%OCT7Jx+mqALwywju#VtY1>iwn6HF$)mN3ZZ(SJ%h9 zuTP}^FyPpefjb%-8=L+9+5J#wt9`Csw9uT{iOzePes(w3BxwrZ>D5<@S+>4hz&if= z_3Jlp-c;V+ZX|O2*(KEw^0n%@M#VR3UR+&zHqz(j<}F*)@YZ}x{9lYf>WW0?FwtMd zYWb(T71(FbIA7Qms7BGJb@EpWPmBBS?scg%=BwdReMCRyXeH}+>Mxp&U*oI#;0(Jz z-^ndn^n&frw|nIN^XnOGd$|7mY|)JWUq2{%vgL`}`z(u)zN~Y@*4*N@YpacCZWb1< zOVUivJUj5!T)KCuid1yEQ88yrwnd$?V(`}8Jp*HX#XO-RX8w1T6YxK+RK2r%hcfZo z>nj8$qKl{D&E%}I&kgr@c9lt=`^kFzSPEDD_0gLL2E%{0;Dfoe4VLt?qXZxG=+UF* zb*asB!cUF#e+k`X6Y;e)EaCFJm7K*TZ{AFE&z@-Mt+=n7r4Z>cF*2v-{HWjBRIigJ zCY=vUgmylWaO#Z3HYcAdiwKo;?wJ$rFgn=rKG)$?R*kq*r^bA42@NKbS#$c`o7mV` zmfP>2MZ*&-U&o~DrgT=uU0)%j$D+r3@IV!Y(OHumqM)E){@{J6nyPBl{MBNY^8TVd z8Y-W^t7(z#ctg68yuNGS%e=N5l9?u@p-UxBX{I*bC>|)2O^e>=&A)SJhHlxp2dVn` z{Cs>be?7^})EHzk)^I9v{;%dykHYTvSycflGH2`0 z1`8gG$3>ECTApm0oE~kk{z~$3*wv0FbLY*gDfIC0UA;^B;_QVoJr2_2gH<)0FG@p2 z72z1!k1QMRUAS<;T(UR%zE<+$7x=A;y*QVA!Q`ix*N1A4*_ge%yIc2(Yp(i{BSGQe zf_}v@;gZgsi3t%&>ADtga_rjvB%kWrlD&_2wvIY{e0CZ4tcu!maqwrO4NqOJn03>c zw_T6g`r0Es%=oM!Jc%{C2Bz45$z4)1o$ zFO>NewPWYbp?_xcyy`x^Iy)#h*nI3)UtUjMm*dOj+MA`N^$p#If_Tl^--Ww;y>p6} zDO@=A(B9tOr?_CSQjv4V$t&wOY!G!BG({-WP7HSHsx>PK7UbN1;!FV6s-qT=7RR$b$Yi0!71!A#Yy2QVkK(7di2QJ;k74^ufT%lPABG2p3k*=5dX} zKjq@Xry||7%&g%0DZCv?$*FV2-QVqQH|?xW%s&#W-qIQ}ATb(dg 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 + + 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