From 554d033dda25ec7182d6830fb55fae778a681200 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Fri, 20 Oct 2023 15:01:54 +0200
Subject: [PATCH 01/92] [NAE-1546] Plugin library
- implemented plugin registration
---
pom.xml | 50 ++++++++++-
.../plugins/domain/EntryPoint.java | 15 ++++
.../integration/plugins/domain/Method.java | 15 ++++
.../integration/plugins/domain/Plugin.java | 24 ++++++
.../PluginRegistrationConfigProperties.java | 13 +++
.../PluginRegistrationServer.java | 85 +++++++++++++++++++
.../plugins/repository/PluginRepository.java | 11 +++
.../plugins/service/IPluginService.java | 9 ++
.../plugins/service/PluginService.java | 36 ++++++++
src/main/proto/RegistrationService.proto | 33 +++++++
src/main/resources/application.properties | 4 +
11 files changed, 292 insertions(+), 3 deletions(-)
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
create mode 100644 src/main/proto/RegistrationService.proto
diff --git a/pom.xml b/pom.xml
index f0c54d4283f..39377bd2e92 100644
--- a/pom.xml
+++ b/pom.xml
@@ -337,11 +337,26 @@
spring-boot-starter-data-elasticsearch
-
+
+
+ io.grpc
+ grpc-netty
+ 1.53.0
+
+
+ io.grpc
+ grpc-protobuf
+ 1.53.0
+
+
+ io.grpc
+ grpc-stub
+ 1.53.0
+ com.google.protobufprotobuf-java
- 3.19.6
+ 3.17.3
@@ -527,6 +542,13 @@
true
+
+
+ kr.motd.maven
+ os-maven-plugin
+ 1.6.1
+
+ org.springframework.boot
@@ -633,7 +655,7 @@
falsefalsetrue
- src/main/java;target/generated-sources/groovy-stubs/main;target/generated-sources/java
+ src/main/java;target/generated-sources/groovy-stubs/main;target/generated-sources/java;target/generated-sources/protobuf
-Xdoclint:none
@@ -773,6 +795,28 @@
license-maven-plugin2.0.0
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+ 0.6.1
+
+
+ com.google.protobuf:protoc:3.17.3:exe:${os.detected.classifier}
+
+ grpc-java
+
+ io.grpc:protoc-gen-grpc-java:1.53.0:exe:${os.detected.classifier}
+
+
+
+
+
+ compile
+ compile-custom
+
+
+
+
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
new file mode 100644
index 00000000000..1ded626275b
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
@@ -0,0 +1,15 @@
+package com.netgrif.application.engine.integration.plugins.domain;
+
+import lombok.Data;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Data
+public class EntryPoint {
+ private String identifier;
+ private Map methods;
+ public EntryPoint() {
+ this.methods = new LinkedHashMap<>();
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
new file mode 100644
index 00000000000..0fd4c080e29
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
@@ -0,0 +1,15 @@
+package com.netgrif.application.engine.integration.plugins.domain;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class Method {
+ private String name;
+ private List args;
+ public Method() {
+ this.args = new ArrayList<>();
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
new file mode 100644
index 00000000000..fe3357cbb65
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
@@ -0,0 +1,24 @@
+package com.netgrif.application.engine.integration.plugins.domain;
+
+import lombok.Data;
+import org.bson.types.ObjectId;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Data
+@Document
+public class Plugin {
+ @Id
+ private ObjectId _id;
+ private String identifier;
+ private String url;
+ private Map entryPoints;
+
+ public Plugin() {
+ this.entryPoints = new LinkedHashMap<>();
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
new file mode 100644
index 00000000000..3234760551f
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
@@ -0,0 +1,13 @@
+package com.netgrif.application.engine.integration.plugins.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "nae.plugin.registration")
+public class PluginRegistrationConfigProperties {
+ private String url;
+ private int port;
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java b/src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java
new file mode 100644
index 00000000000..be2bf1ee24d
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java
@@ -0,0 +1,85 @@
+package com.netgrif.application.engine.integration.plugins.registration;
+
+import com.netgrif.application.engine.integration.plugins.domain.EntryPoint;
+import com.netgrif.application.engine.integration.plugins.domain.Method;
+import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.integration.plugins.properties.PluginRegistrationConfigProperties;
+import com.netgrif.application.engine.integration.plugins.service.IPluginService;
+import com.netgrif.pluginlibrary.register.MessageStatus;
+import com.netgrif.pluginlibrary.register.RegistrationRequest;
+import com.netgrif.pluginlibrary.register.RegistrationServiceGrpc;
+import com.netgrif.pluginlibrary.register.ResponseMessage;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.stub.StreamObserver;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.io.IOException;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public final class PluginRegistrationServer extends RegistrationServiceGrpc.RegistrationServiceImplBase {
+
+ private final PluginRegistrationConfigProperties properties;
+ private final IPluginService pluginService;
+ private Server server;
+
+ @PostConstruct
+ public void startServer() throws IOException {
+ server = ServerBuilder
+ .forPort(properties.getPort())
+ .addService(this).build();
+ server.start();
+ log.info("[gRPC Server] - Started on port " + properties.getPort());
+ }
+
+ @PreDestroy
+ public void stopServer() {
+ server.shutdown();
+ log.info("[gRPC Server] - Started on port " + properties.getPort());
+ }
+
+ @Override
+ public void register(RegistrationRequest request, StreamObserver responseObserver) {
+ ResponseMessage response;
+ try {
+ pluginService.register(convert(request));
+ response = ResponseMessage.newBuilder()
+ .setStatus(MessageStatus.OK)
+ .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully registered.")
+ .build();
+ } catch (IllegalArgumentException e) {
+ response = ResponseMessage.newBuilder()
+ .setStatus(MessageStatus.NOT_OK)
+ .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" failed to register. " + e.getMessage())
+ .build();
+ }
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
+ }
+
+ private Plugin convert(RegistrationRequest request) {
+ Plugin plugin = new Plugin();
+ plugin.setIdentifier(request.getIdentifier());
+ plugin.setUrl(request.getUrl());
+ plugin.setEntryPoints(request.getEntryPointsList().stream().map(entryPoint -> {
+ EntryPoint ep = new EntryPoint();
+ ep.setIdentifier(entryPoint.getIdentifier());
+ ep.setMethods(entryPoint.getMethodsList().stream().map(method -> {
+ Method mth = new Method();
+ mth.setName(method.getName());
+ mth.setArgs(method.getArgsList());
+ return mth;
+ }).collect(Collectors.toMap(Method::getName, Function.identity())));
+ return ep;
+ }).collect(Collectors.toMap(EntryPoint::getIdentifier, Function.identity())));
+ return plugin;
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java b/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
new file mode 100644
index 00000000000..a33dbda89b8
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
@@ -0,0 +1,11 @@
+package com.netgrif.application.engine.integration.plugins.repository;
+
+import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import org.bson.types.ObjectId;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface PluginRepository extends MongoRepository {
+ Plugin findByIdentifier(String identifier);
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
new file mode 100644
index 00000000000..4173d3ddfdc
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -0,0 +1,9 @@
+package com.netgrif.application.engine.integration.plugins.service;
+
+import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+
+public interface IPluginService {
+ void register(Plugin plugin);
+
+ void unregister(String identifier);
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
new file mode 100644
index 00000000000..c79251ab4dc
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -0,0 +1,36 @@
+package com.netgrif.application.engine.integration.plugins.service;
+
+import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public final class PluginService implements IPluginService {
+ private final PluginRepository pluginRepository;
+
+ @Override
+ public void register(Plugin plugin) {
+ Plugin existingPlugin = pluginRepository.findByIdentifier(plugin.getIdentifier());
+ if (existingPlugin != null) {
+ throw new IllegalArgumentException("Plugin with identifier \"" + plugin.getIdentifier() + "\" cannot be registered. Plugin with this identifier has already been registered.");
+ }
+ pluginRepository.save(plugin);
+ log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was registered.");
+ }
+
+ @Override
+ public void unregister(String identifier) {
+ Plugin existingPlugin = pluginRepository.findByIdentifier(identifier);
+ if (existingPlugin == null) {
+ throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be unregistered. Plugin with this identifier does not exist.");
+ }
+ pluginRepository.delete(existingPlugin);
+ log.info("Plugin with identifier \"" + identifier + "\" was unregistered.");
+ }
+
+
+}
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
new file mode 100644
index 00000000000..14d6382ff36
--- /dev/null
+++ b/src/main/proto/RegistrationService.proto
@@ -0,0 +1,33 @@
+syntax = "proto3";
+option java_multiple_files = true;
+package com.netgrif.pluginlibrary.register;
+
+enum MessageStatus {
+ OK = 0;
+ NOT_OK = 1;
+}
+
+message Method {
+ string name = 1;
+ repeated string args = 2;
+}
+
+message EntryPoint {
+ string identifier = 1;
+ repeated Method methods = 2;
+}
+
+message RegistrationRequest {
+ string identifier = 1;
+ string url = 2;
+ repeated EntryPoint entryPoints = 3;
+}
+
+message ResponseMessage {
+ MessageStatus status = 1;
+ string message = 2;
+}
+
+service RegistrationService {
+ rpc register(RegistrationRequest) returns (ResponseMessage);
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index ff8d47e97ea..fe55352f7ef 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -176,3 +176,7 @@ nae.field-runner.cache-size.namespace-functions=500
# Filter export file name
nae.filter.export.file-name=filters.xml
+
+# Plugin
+nae.plugin.registration.url=${NAE_APP_URL:localhost}
+nae.plugin.registration.port=${NAE_APP_PORT:8081}
From 93f2e3a90a684879921d6e317b36e78fbc2d1f6d Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 24 Oct 2023 07:00:28 +0200
Subject: [PATCH 02/92] [NAE-1546] Plugin library
- plugin registration server
---
.../PluginRegistrationService.java} | 37 +++----------------
.../plugins/service/PluginService.java | 24 ++++++++++++
src/main/proto/RegistrationService.proto | 2 +-
3 files changed, 31 insertions(+), 32 deletions(-)
rename src/main/java/com/netgrif/application/engine/integration/plugins/{registration/PluginRegistrationServer.java => service/PluginRegistrationService.java} (63%)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
similarity index 63%
rename from src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java
rename to src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index be2bf1ee24d..e6f259dac39 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/registration/PluginRegistrationServer.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -1,50 +1,25 @@
-package com.netgrif.application.engine.integration.plugins.registration;
+package com.netgrif.application.engine.integration.plugins.service;
import com.netgrif.application.engine.integration.plugins.domain.EntryPoint;
import com.netgrif.application.engine.integration.plugins.domain.Method;
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
-import com.netgrif.application.engine.integration.plugins.properties.PluginRegistrationConfigProperties;
-import com.netgrif.application.engine.integration.plugins.service.IPluginService;
-import com.netgrif.pluginlibrary.register.MessageStatus;
-import com.netgrif.pluginlibrary.register.RegistrationRequest;
-import com.netgrif.pluginlibrary.register.RegistrationServiceGrpc;
-import com.netgrif.pluginlibrary.register.ResponseMessage;
-import io.grpc.Server;
-import io.grpc.ServerBuilder;
+import com.netgrif.pluginlibrary.core.MessageStatus;
+import com.netgrif.pluginlibrary.core.RegistrationRequest;
+import com.netgrif.pluginlibrary.core.RegistrationServiceGrpc;
+import com.netgrif.pluginlibrary.core.ResponseMessage;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import java.io.IOException;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Component
@RequiredArgsConstructor
-public final class PluginRegistrationServer extends RegistrationServiceGrpc.RegistrationServiceImplBase {
-
- private final PluginRegistrationConfigProperties properties;
+public final class PluginRegistrationService extends RegistrationServiceGrpc.RegistrationServiceImplBase {
private final IPluginService pluginService;
- private Server server;
-
- @PostConstruct
- public void startServer() throws IOException {
- server = ServerBuilder
- .forPort(properties.getPort())
- .addService(this).build();
- server.start();
- log.info("[gRPC Server] - Started on port " + properties.getPort());
- }
-
- @PreDestroy
- public void stopServer() {
- server.shutdown();
- log.info("[gRPC Server] - Started on port " + properties.getPort());
- }
@Override
public void register(RegistrationRequest request, StreamObserver responseObserver) {
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index c79251ab4dc..0651352b67e 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -1,16 +1,40 @@
package com.netgrif.application.engine.integration.plugins.service;
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.integration.plugins.properties.PluginRegistrationConfigProperties;
import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.io.IOException;
+
@Slf4j
@Service
@RequiredArgsConstructor
public final class PluginService implements IPluginService {
private final PluginRepository pluginRepository;
+ private final PluginRegistrationConfigProperties properties;
+ private Server server;
+ @PostConstruct
+ public void startServer() throws IOException {
+ server = ServerBuilder
+ .forPort(properties.getPort())
+ .addService(new PluginRegistrationService(this))
+ .build();
+ server.start();
+ log.info("[gRPC Server] - Started on port " + properties.getPort());
+ }
+
+ @PreDestroy
+ public void stopServer() {
+ server.shutdown();
+ log.info("[gRPC Server] - Started on port " + properties.getPort());
+ }
@Override
public void register(Plugin plugin) {
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
index 14d6382ff36..56abd6abbbf 100644
--- a/src/main/proto/RegistrationService.proto
+++ b/src/main/proto/RegistrationService.proto
@@ -1,6 +1,6 @@
syntax = "proto3";
option java_multiple_files = true;
-package com.netgrif.pluginlibrary.register;
+package com.netgrif.pluginlibrary.core;
enum MessageStatus {
OK = 0;
From 563192947947efe578c3e49962483d9a7ac5f8f4 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 24 Oct 2023 07:59:13 +0200
Subject: [PATCH 03/92] [NAE-1546] Plugin library
- plugin unregistration server
- plugin executin basics
---
.../logic/action/ActionDelegate.groovy | 9 +++++
.../integration/plugins/domain/Plugin.java | 1 +
.../PluginRegistrationConfigProperties.java | 1 -
.../plugins/service/IPluginService.java | 4 ++
.../service/PluginRegistrationService.java | 37 ++++++++++++++-----
.../plugins/service/PluginService.java | 31 +++++++++++++++-
src/main/proto/ExecutionService.proto | 17 +++++++++
src/main/proto/RegistrationService.proto | 17 +++++++--
src/main/resources/application.properties | 1 -
9 files changed, 102 insertions(+), 16 deletions(-)
create mode 100644 src/main/proto/ExecutionService.proto
diff --git a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index 77d1a18c547..f77f116f25c 100644
--- a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -20,6 +20,8 @@ import com.netgrif.application.engine.export.service.interfaces.IExportService
import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService
import com.netgrif.application.engine.history.service.IHistoryService
import com.netgrif.application.engine.importer.service.FieldFactory
+import com.netgrif.application.engine.integration.plugins.service.IPluginService
+import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.mail.domain.MailDraft
import com.netgrif.application.engine.mail.interfaces.IMailAttemptService
import com.netgrif.application.engine.mail.interfaces.IMailService
@@ -191,6 +193,9 @@ class ActionDelegate {
@Autowired
PublicViewProperties publicViewProperties
+ @Autowired
+ IPluginService pluginService
+
/**
* Reference of case and task in which current action is taking place.
*/
@@ -1948,4 +1953,8 @@ class ActionDelegate {
String makeUrl(String publicViewUrl = publicViewProperties.url, String identifier) {
return "${publicViewUrl}/${Base64.getEncoder().encodeToString(identifier.bytes)}" as String
}
+
+ def callPlugin(String plugin, String method, Object... args) {
+
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
index fe3357cbb65..5095b6a4328 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
@@ -16,6 +16,7 @@ public class Plugin {
private ObjectId _id;
private String identifier;
private String url;
+ private long port;
private Map entryPoints;
public Plugin() {
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
index 3234760551f..a62eea660cc 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
@@ -8,6 +8,5 @@
@Component
@ConfigurationProperties(prefix = "nae.plugin.registration")
public class PluginRegistrationConfigProperties {
- private String url;
private int port;
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
index 4173d3ddfdc..d87e41e3056 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -2,8 +2,12 @@
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import java.io.Serializable;
+
public interface IPluginService {
void register(Plugin plugin);
+ Object call(String pluginId, String entryPoint, String method, Serializable... args);
+
void unregister(String identifier);
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index e6f259dac39..8ab6251b49d 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -3,35 +3,32 @@
import com.netgrif.application.engine.integration.plugins.domain.EntryPoint;
import com.netgrif.application.engine.integration.plugins.domain.Method;
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
-import com.netgrif.pluginlibrary.core.MessageStatus;
-import com.netgrif.pluginlibrary.core.RegistrationRequest;
-import com.netgrif.pluginlibrary.core.RegistrationServiceGrpc;
-import com.netgrif.pluginlibrary.core.ResponseMessage;
+import com.netgrif.pluginlibrary.core.*;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
-@Component
+@Service
@RequiredArgsConstructor
public final class PluginRegistrationService extends RegistrationServiceGrpc.RegistrationServiceImplBase {
private final IPluginService pluginService;
@Override
- public void register(RegistrationRequest request, StreamObserver responseObserver) {
- ResponseMessage response;
+ public void register(RegistrationRequest request, StreamObserver responseObserver) {
+ RegistrationResponse response;
try {
pluginService.register(convert(request));
- response = ResponseMessage.newBuilder()
+ response = RegistrationResponse.newBuilder()
.setStatus(MessageStatus.OK)
.setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully registered.")
.build();
} catch (IllegalArgumentException e) {
- response = ResponseMessage.newBuilder()
+ response = RegistrationResponse.newBuilder()
.setStatus(MessageStatus.NOT_OK)
.setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" failed to register. " + e.getMessage())
.build();
@@ -40,10 +37,30 @@ public void register(RegistrationRequest request, StreamObserver responseObserver) {
+ UnRegistrationResponse response;
+ try {
+ pluginService.unregister(request.getIdentifier());
+ response = UnRegistrationResponse.newBuilder()
+ .setStatus(MessageStatus.OK)
+ .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully unregistered.")
+ .build();
+ } catch (IllegalArgumentException e) {
+ response = UnRegistrationResponse.newBuilder()
+ .setStatus(MessageStatus.NOT_OK)
+ .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" failed to unregister. " + e.getMessage())
+ .build();
+ }
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
+ }
+
private Plugin convert(RegistrationRequest request) {
Plugin plugin = new Plugin();
plugin.setIdentifier(request.getIdentifier());
plugin.setUrl(request.getUrl());
+ plugin.setPort(request.getPort());
plugin.setEntryPoints(request.getEntryPointsList().stream().map(entryPoint -> {
EntryPoint ep = new EntryPoint();
ep.setIdentifier(entryPoint.getIdentifier());
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 0651352b67e..087f6317625 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -1,22 +1,31 @@
package com.netgrif.application.engine.integration.plugins.service;
+import com.google.protobuf.ByteString;
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
import com.netgrif.application.engine.integration.plugins.properties.PluginRegistrationConfigProperties;
import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import com.netgrif.pluginlibrary.core.*;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.SerializationUtils;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
-public final class PluginService implements IPluginService {
+public class PluginService implements IPluginService {
private final PluginRepository pluginRepository;
private final PluginRegistrationConfigProperties properties;
private Server server;
@@ -46,6 +55,26 @@ public void register(Plugin plugin) {
log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was registered.");
}
+ @Override
+ public Object call(String pluginId, String entryPoint, String method, Serializable... args) {
+ Plugin plugin = pluginRepository.findByIdentifier(pluginId);
+ if (plugin == null) {
+ throw new IllegalArgumentException("Plugin with identifier \"" + pluginId + "\" cannot be found");
+ }
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(plugin.getUrl(), (int) plugin.getPort())
+ .usePlaintext()
+ .build();
+ List argBytes = Arrays.stream(args).map(arg -> ByteString.copyFrom(SerializationUtils.serialize(arg))).collect(Collectors.toList());
+ ExecutionServiceGrpc.ExecutionServiceBlockingStub stub = ExecutionServiceGrpc.newBlockingStub(channel);
+ ExecutionResponse responseMessage = stub.execute(ExecutionRequest.newBuilder()
+ .setEntryPoint(entryPoint)
+ .setMethod(method)
+ .addAllArgs(argBytes)
+ .build());
+ channel.shutdown();
+ return SerializationUtils.deserialize(responseMessage.getResponse().toByteArray());
+ }
+
@Override
public void unregister(String identifier) {
Plugin existingPlugin = pluginRepository.findByIdentifier(identifier);
diff --git a/src/main/proto/ExecutionService.proto b/src/main/proto/ExecutionService.proto
new file mode 100644
index 00000000000..62094efbc32
--- /dev/null
+++ b/src/main/proto/ExecutionService.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+option java_multiple_files = true;
+package com.netgrif.pluginlibrary.core;
+
+message ExecutionRequest {
+ string entryPoint = 1;
+ string method = 2;
+ repeated bytes args = 3;
+}
+
+message ExecutionResponse {
+ bytes response = 1;
+}
+
+service ExecutionService {
+ rpc execute(ExecutionRequest) returns (ExecutionResponse);
+}
\ No newline at end of file
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
index 56abd6abbbf..f91f2fb8bcc 100644
--- a/src/main/proto/RegistrationService.proto
+++ b/src/main/proto/RegistrationService.proto
@@ -20,14 +20,25 @@ message EntryPoint {
message RegistrationRequest {
string identifier = 1;
string url = 2;
- repeated EntryPoint entryPoints = 3;
+ int64 port = 3;
+ repeated EntryPoint entryPoints = 4;
}
-message ResponseMessage {
+message UnRegistrationRequest {
+ string identifier = 1;
+}
+
+message RegistrationResponse {
+ MessageStatus status = 1;
+ string message = 2;
+}
+
+message UnRegistrationResponse {
MessageStatus status = 1;
string message = 2;
}
service RegistrationService {
- rpc register(RegistrationRequest) returns (ResponseMessage);
+ rpc register(RegistrationRequest) returns (RegistrationResponse);
+ rpc unregister(UnRegistrationRequest) returns (UnRegistrationResponse);
}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index fe55352f7ef..a49b9ca5d12 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -178,5 +178,4 @@ nae.field-runner.cache-size.namespace-functions=500
nae.filter.export.file-name=filters.xml
# Plugin
-nae.plugin.registration.url=${NAE_APP_URL:localhost}
nae.plugin.registration.port=${NAE_APP_PORT:8081}
From 5638482f0324df678c24fbec87fbf58b9c4acc1f Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 24 Oct 2023 11:32:17 +0200
Subject: [PATCH 04/92] [NAE-1546] Plugin library
- implemented execution for plugin
---
.../logic/action/ActionDelegate.groovy | 4 +--
.../integration/plugins/domain/Method.java | 6 +++-
.../service/PluginRegistrationService.java | 30 +++++++------------
.../plugins/service/PluginService.java | 2 +-
.../plugins/utils/ClassToStringConverter.java | 25 ++++++++++++++++
src/main/proto/RegistrationService.proto | 14 +++------
6 files changed, 48 insertions(+), 33 deletions(-)
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
diff --git a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index f77f116f25c..73624eb7bf4 100644
--- a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -1954,7 +1954,7 @@ class ActionDelegate {
return "${publicViewUrl}/${Base64.getEncoder().encodeToString(identifier.bytes)}" as String
}
- def callPlugin(String plugin, String method, Object... args) {
-
+ def callPlugin(String plugin, String entryPoint, String method, Serializable... args) {
+ return pluginService.call(plugin, entryPoint, method, args)
}
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
index 0fd4c080e29..9f88750b4ff 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
@@ -1,6 +1,9 @@
package com.netgrif.application.engine.integration.plugins.domain;
+import com.netgrif.application.engine.integration.plugins.utils.ClassToStringConverter;
import lombok.Data;
+import org.springframework.data.convert.PropertyValueConverter;
+import org.springframework.data.convert.ValueConverter;
import java.util.ArrayList;
import java.util.List;
@@ -8,7 +11,8 @@
@Data
public class Method {
private String name;
- private List args;
+ @ValueConverter(ClassToStringConverter.class)
+ private List> args;
public Method() {
this.args = new ArrayList<>();
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index 8ab6251b49d..d3f5edd7f3e 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -8,6 +8,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+import org.springframework.util.SerializationUtils;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -20,40 +21,31 @@ public final class PluginRegistrationService extends RegistrationServiceGrpc.Reg
@Override
public void register(RegistrationRequest request, StreamObserver responseObserver) {
- RegistrationResponse response;
try {
pluginService.register(convert(request));
- response = RegistrationResponse.newBuilder()
- .setStatus(MessageStatus.OK)
+ RegistrationResponse response = RegistrationResponse.newBuilder()
.setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully registered.")
.build();
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
} catch (IllegalArgumentException e) {
- response = RegistrationResponse.newBuilder()
- .setStatus(MessageStatus.NOT_OK)
- .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" failed to register. " + e.getMessage())
- .build();
+ responseObserver.onError(e);
}
- responseObserver.onNext(response);
- responseObserver.onCompleted();
}
@Override
public void unregister(UnRegistrationRequest request, StreamObserver responseObserver) {
- UnRegistrationResponse response;
try {
pluginService.unregister(request.getIdentifier());
- response = UnRegistrationResponse.newBuilder()
- .setStatus(MessageStatus.OK)
+ UnRegistrationResponse response = UnRegistrationResponse.newBuilder()
.setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully unregistered.")
.build();
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
} catch (IllegalArgumentException e) {
- response = UnRegistrationResponse.newBuilder()
- .setStatus(MessageStatus.NOT_OK)
- .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" failed to unregister. " + e.getMessage())
- .build();
+ responseObserver.onError(e);
}
- responseObserver.onNext(response);
- responseObserver.onCompleted();
+
}
private Plugin convert(RegistrationRequest request) {
@@ -67,7 +59,7 @@ private Plugin convert(RegistrationRequest request) {
ep.setMethods(entryPoint.getMethodsList().stream().map(method -> {
Method mth = new Method();
mth.setName(method.getName());
- mth.setArgs(method.getArgsList());
+ mth.setArgs(method.getArgsList().stream().map(arg -> (Class>) SerializationUtils.deserialize(arg.toByteArray())).collect(Collectors.toList()));
return mth;
}).collect(Collectors.toMap(Method::getName, Function.identity())));
return ep;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 087f6317625..c998dbc3724 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -71,7 +71,7 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
.setMethod(method)
.addAllArgs(argBytes)
.build());
- channel.shutdown();
+ channel.shutdownNow();
return SerializationUtils.deserialize(responseMessage.getResponse().toByteArray());
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
new file mode 100644
index 00000000000..6a44c84a8e5
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
@@ -0,0 +1,25 @@
+package com.netgrif.application.engine.integration.plugins.utils;
+
+import org.springframework.data.convert.PropertyValueConverter;
+import org.springframework.data.mongodb.core.convert.MongoConversionContext;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ClassToStringConverter implements PropertyValueConverter>, List, MongoConversionContext> {
+ @Override
+ public List> read(List value, MongoConversionContext context) {
+ return value.stream().map(v -> {
+ try {
+ return Class.forName(v);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }).collect(Collectors.toList());
+ }
+
+ @Override
+ public List write(List> value, MongoConversionContext context) {
+ return value.stream().map(Class::getName).collect(Collectors.toList());
+ }
+}
\ No newline at end of file
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
index f91f2fb8bcc..c7b48c6f335 100644
--- a/src/main/proto/RegistrationService.proto
+++ b/src/main/proto/RegistrationService.proto
@@ -1,15 +1,11 @@
+
syntax = "proto3";
option java_multiple_files = true;
package com.netgrif.pluginlibrary.core;
-enum MessageStatus {
- OK = 0;
- NOT_OK = 1;
-}
-
message Method {
string name = 1;
- repeated string args = 2;
+ repeated bytes args = 2;
}
message EntryPoint {
@@ -29,13 +25,11 @@ message UnRegistrationRequest {
}
message RegistrationResponse {
- MessageStatus status = 1;
- string message = 2;
+ string message = 1;
}
message UnRegistrationResponse {
- MessageStatus status = 1;
- string message = 2;
+ string message = 1;
}
service RegistrationService {
From 6fc7ef9b1d0352743f41eb3c35f2a75270b79896 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 7 Nov 2023 13:21:10 +0100
Subject: [PATCH 05/92] [NAE-1546] Plugin library
- implemented execution for plugin
---
.../engine/integration/plugins/domain/Plugin.java | 1 +
.../integration/plugins/service/IPluginService.java | 2 +-
.../plugins/service/PluginRegistrationService.java | 7 ++++---
.../integration/plugins/service/PluginService.java | 9 +++++----
src/main/proto/RegistrationService.proto | 6 +++---
5 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
index 5095b6a4328..3c429bc3881 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
@@ -17,6 +17,7 @@ public class Plugin {
private String identifier;
private String url;
private long port;
+ private boolean active;
private Map entryPoints;
public Plugin() {
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
index d87e41e3056..acfd6da4f05 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -9,5 +9,5 @@ public interface IPluginService {
Object call(String pluginId, String entryPoint, String method, Serializable... args);
- void unregister(String identifier);
+ void deactivate(String identifier);
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index d3f5edd7f3e..842bba0f366 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -34,10 +34,10 @@ public void register(RegistrationRequest request, StreamObserver responseObserver) {
+ public void deactivate(DeactivationRequest request, StreamObserver responseObserver) {
try {
- pluginService.unregister(request.getIdentifier());
- UnRegistrationResponse response = UnRegistrationResponse.newBuilder()
+ pluginService.deactivate(request.getIdentifier());
+ DeactivationResponse response = DeactivationResponse.newBuilder()
.setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully unregistered.")
.build();
responseObserver.onNext(response);
@@ -53,6 +53,7 @@ private Plugin convert(RegistrationRequest request) {
plugin.setIdentifier(request.getIdentifier());
plugin.setUrl(request.getUrl());
plugin.setPort(request.getPort());
+ plugin.setActive(true);
plugin.setEntryPoints(request.getEntryPointsList().stream().map(entryPoint -> {
EntryPoint ep = new EntryPoint();
ep.setIdentifier(entryPoint.getIdentifier());
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index c998dbc3724..9924967ab5f 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -76,13 +76,14 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
}
@Override
- public void unregister(String identifier) {
+ public void deactivate(String identifier) {
Plugin existingPlugin = pluginRepository.findByIdentifier(identifier);
if (existingPlugin == null) {
- throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be unregistered. Plugin with this identifier does not exist.");
+ throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be deactivated. Plugin with this identifier does not exist.");
}
- pluginRepository.delete(existingPlugin);
- log.info("Plugin with identifier \"" + identifier + "\" was unregistered.");
+ existingPlugin.setActive(false);
+ pluginRepository.save(existingPlugin);
+ log.info("Plugin with identifier \"" + identifier + "\" was deactivated.");
}
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
index c7b48c6f335..2f16a6ebf5c 100644
--- a/src/main/proto/RegistrationService.proto
+++ b/src/main/proto/RegistrationService.proto
@@ -20,7 +20,7 @@ message RegistrationRequest {
repeated EntryPoint entryPoints = 4;
}
-message UnRegistrationRequest {
+message DeactivationRequest {
string identifier = 1;
}
@@ -28,11 +28,11 @@ message RegistrationResponse {
string message = 1;
}
-message UnRegistrationResponse {
+message DeactivationResponse {
string message = 1;
}
service RegistrationService {
rpc register(RegistrationRequest) returns (RegistrationResponse);
- rpc unregister(UnRegistrationRequest) returns (UnRegistrationResponse);
+ rpc deactivate(DeactivationRequest) returns (DeactivationResponse);
}
\ No newline at end of file
From f3c0b5569e3bad29b5d3a878c00512306ea5efb4 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 7 Nov 2023 15:33:50 +0100
Subject: [PATCH 06/92] [NAE-1546] Plugin library
- added injector to action delegate
---
.../integration/plugin/PluginInjector.groovy | 25 +++++++++++++++++++
.../service/PluginRegistrationService.java | 2 +-
.../plugins/service/PluginService.java | 9 ++++++-
3 files changed, 34 insertions(+), 2 deletions(-)
create mode 100644 src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy
new file mode 100644
index 00000000000..163ac081d28
--- /dev/null
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy
@@ -0,0 +1,25 @@
+package com.netgrif.application.engine.integration.plugin
+
+import com.netgrif.application.engine.integration.plugins.domain.Plugin
+import com.netgrif.application.engine.integration.plugins.service.PluginService
+import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
+import lombok.RequiredArgsConstructor
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+
+@Component
+class PluginInjector {
+
+ @Autowired
+ private final ActionDelegate actionDelegate
+
+ void inject(Plugin plugin, PluginService pluginService) {
+ actionDelegate.metaClass[plugin.identifier] = new Object()
+ plugin.entryPoints.each {ep ->
+ actionDelegate.metaClass[plugin.identifier].metaClass[ep.value.identifier] = new Object()
+ ep.value.methods.each { m ->
+ actionDelegate.metaClass[plugin.identifier].metaClass[ep.value.identifier].metaClass[m.value.name] << { Serializable... args -> pluginService.call(plugin.identifier, ep.value.identifier, m.value.name, args)}
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index 842bba0f366..9e1ba6298c8 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -38,7 +38,7 @@ public void deactivate(DeactivationRequest request, StreamObserver
Date: Tue, 7 Nov 2023 15:51:26 +0100
Subject: [PATCH 07/92] [NAE-1546] Plugin library
- added injector to action delegate
---
.../integration/plugin/PluginInjector.groovy | 25 -------------
.../plugin/injector/EntryPointMeta.groovy | 4 +++
.../plugin/injector/PluginInjector.groovy | 36 +++++++++++++++++++
.../plugin/injector/PluginMeta.groovy | 4 +++
.../logic/action/ActionDelegate.groovy | 9 -----
.../plugins/service/PluginService.java | 8 ++---
6 files changed, 46 insertions(+), 40 deletions(-)
delete mode 100644 src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy
create mode 100644 src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy
create mode 100644 src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
create mode 100644 src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy
deleted file mode 100644
index 163ac081d28..00000000000
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/PluginInjector.groovy
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.netgrif.application.engine.integration.plugin
-
-import com.netgrif.application.engine.integration.plugins.domain.Plugin
-import com.netgrif.application.engine.integration.plugins.service.PluginService
-import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
-import lombok.RequiredArgsConstructor
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.stereotype.Component
-
-@Component
-class PluginInjector {
-
- @Autowired
- private final ActionDelegate actionDelegate
-
- void inject(Plugin plugin, PluginService pluginService) {
- actionDelegate.metaClass[plugin.identifier] = new Object()
- plugin.entryPoints.each {ep ->
- actionDelegate.metaClass[plugin.identifier].metaClass[ep.value.identifier] = new Object()
- ep.value.methods.each { m ->
- actionDelegate.metaClass[plugin.identifier].metaClass[ep.value.identifier].metaClass[m.value.name] << { Serializable... args -> pluginService.call(plugin.identifier, ep.value.identifier, m.value.name, args)}
- }
- }
- }
-}
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy
new file mode 100644
index 00000000000..17d71efc107
--- /dev/null
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy
@@ -0,0 +1,4 @@
+package com.netgrif.application.engine.integration.plugin.injector
+
+class EntryPointMeta {
+}
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
new file mode 100644
index 00000000000..479aa7f7253
--- /dev/null
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -0,0 +1,36 @@
+package com.netgrif.application.engine.integration.plugin.injector
+
+import com.netgrif.application.engine.configuration.ApplicationContextProvider
+import com.netgrif.application.engine.integration.plugins.domain.Plugin
+import com.netgrif.application.engine.integration.plugins.service.PluginService
+import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
+import com.netgrif.pluginlibrary.core.EntryPoint
+import groovy.util.logging.Slf4j
+import org.springframework.stereotype.Component
+
+@Component
+@Slf4j
+class PluginInjector {
+
+ private final ActionDelegate actionDelegate
+
+ PluginInjector(ActionDelegate actionDelegate) {
+ this.actionDelegate = actionDelegate
+ }
+
+ void inject(Plugin plugin) {
+ MetaClass actionDelegateMeta = actionDelegate.metaClass
+ PluginMeta pluginMeta = new PluginMeta()
+ plugin.entryPoints.each {ep ->
+ EntryPointMeta entryPointMeta = new EntryPointMeta()
+ ep.value.methods.each { m ->
+ entryPointMeta.metaClass[m.value.name] << { Serializable... args ->
+ PluginService pluginService = ApplicationContextProvider.getBean("pluginService")
+ return pluginService.call(plugin.identifier, ep.value.identifier, m.value.name, args)}
+ }
+ pluginMeta.metaClass[ep.value.identifier] = entryPointMeta
+ }
+ actionDelegateMeta[plugin.identifier] = pluginMeta
+ log.info("Injected plugin into ActionDelegate")
+ }
+}
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy
new file mode 100644
index 00000000000..96eff9fbbe5
--- /dev/null
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy
@@ -0,0 +1,4 @@
+package com.netgrif.application.engine.integration.plugin.injector
+
+class PluginMeta {
+}
diff --git a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index 73624eb7bf4..77d1a18c547 100644
--- a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -20,8 +20,6 @@ import com.netgrif.application.engine.export.service.interfaces.IExportService
import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService
import com.netgrif.application.engine.history.service.IHistoryService
import com.netgrif.application.engine.importer.service.FieldFactory
-import com.netgrif.application.engine.integration.plugins.service.IPluginService
-import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.mail.domain.MailDraft
import com.netgrif.application.engine.mail.interfaces.IMailAttemptService
import com.netgrif.application.engine.mail.interfaces.IMailService
@@ -193,9 +191,6 @@ class ActionDelegate {
@Autowired
PublicViewProperties publicViewProperties
- @Autowired
- IPluginService pluginService
-
/**
* Reference of case and task in which current action is taking place.
*/
@@ -1953,8 +1948,4 @@ class ActionDelegate {
String makeUrl(String publicViewUrl = publicViewProperties.url, String identifier) {
return "${publicViewUrl}/${Base64.getEncoder().encodeToString(identifier.bytes)}" as String
}
-
- def callPlugin(String plugin, String entryPoint, String method, Serializable... args) {
- return pluginService.call(plugin, entryPoint, method, args)
- }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 60f56fcee60..19c3fd26310 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -1,14 +1,11 @@
package com.netgrif.application.engine.integration.plugins.service;
import com.google.protobuf.ByteString;
-import com.netgrif.application.engine.integration.plugin.PluginInjector;
+import com.netgrif.application.engine.integration.plugin.injector.PluginInjector;
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
import com.netgrif.application.engine.integration.plugins.properties.PluginRegistrationConfigProperties;
import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
-import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate;
import com.netgrif.pluginlibrary.core.*;
-import groovy.lang.GroovyObject;
-import groovy.lang.MetaClass;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Server;
@@ -16,7 +13,6 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SerializationUtils;
-import org.checkerframework.checker.units.qual.A;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@@ -58,7 +54,7 @@ public void register(Plugin plugin) {
log.warn("Plugin with identifier \"" + plugin.getIdentifier() + "\" has already been registered. Plugin will be activated.");
}
pluginRepository.save(plugin);
- pluginInjector.inject(plugin, this);
+ pluginInjector.inject(plugin);
log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was registered.");
}
From 2435397b3c9b69cbd1197f84b23eae3613f735d5 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 7 Nov 2023 15:55:35 +0100
Subject: [PATCH 08/92] [NAE-1546] Plugin library
- added injector to action delegate
---
.../integration/plugin/injector/PluginInjector.groovy | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 479aa7f7253..36401ae3862 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -4,7 +4,6 @@ import com.netgrif.application.engine.configuration.ApplicationContextProvider
import com.netgrif.application.engine.integration.plugins.domain.Plugin
import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
-import com.netgrif.pluginlibrary.core.EntryPoint
import groovy.util.logging.Slf4j
import org.springframework.stereotype.Component
@@ -12,14 +11,8 @@ import org.springframework.stereotype.Component
@Slf4j
class PluginInjector {
- private final ActionDelegate actionDelegate
-
- PluginInjector(ActionDelegate actionDelegate) {
- this.actionDelegate = actionDelegate
- }
-
void inject(Plugin plugin) {
- MetaClass actionDelegateMeta = actionDelegate.metaClass
+ MetaClass actionDelegateMeta = ActionDelegate.metaClass
PluginMeta pluginMeta = new PluginMeta()
plugin.entryPoints.each {ep ->
EntryPointMeta entryPointMeta = new EntryPointMeta()
From 3619c4e34998db39b1f6964eda0838c2a26fc9f0 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Wed, 8 Nov 2023 08:15:14 +0100
Subject: [PATCH 09/92] [NAE-1546] Plugin library
- modified injector
---
.../plugin/injector/PluginInjector.groovy | 20 ++++++++-----------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 36401ae3862..60e18470d24 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -4,26 +4,22 @@ import com.netgrif.application.engine.configuration.ApplicationContextProvider
import com.netgrif.application.engine.integration.plugins.domain.Plugin
import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
-import groovy.util.logging.Slf4j
-import org.springframework.stereotype.Component
-@Component
-@Slf4j
+
class PluginInjector {
- void inject(Plugin plugin) {
+ static void inject(Plugin plugin) {
MetaClass actionDelegateMeta = ActionDelegate.metaClass
- PluginMeta pluginMeta = new PluginMeta()
+ MetaClass pluginMetaClass = PluginMeta.metaClass
plugin.entryPoints.each {ep ->
- EntryPointMeta entryPointMeta = new EntryPointMeta()
+ MetaClass entryPointMetaClass = EntryPointMeta.metaClass
ep.value.methods.each { m ->
- entryPointMeta.metaClass[m.value.name] << { Serializable... args ->
- PluginService pluginService = ApplicationContextProvider.getBean("pluginService")
+ entryPointMetaClass[m.value.name] << { Serializable... args ->
+ PluginService pluginService = ApplicationContextProvider.getBean("pluginService") as PluginService
return pluginService.call(plugin.identifier, ep.value.identifier, m.value.name, args)}
}
- pluginMeta.metaClass[ep.value.identifier] = entryPointMeta
+ pluginMetaClass[ep.value.identifier] = new EntryPointMeta()
}
- actionDelegateMeta[plugin.identifier] = pluginMeta
- log.info("Injected plugin into ActionDelegate")
+ actionDelegateMeta[plugin.identifier] = new PluginMeta()
}
}
From 10da1ec692ab7641ce27526da5fe1ce61a0951b2 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Wed, 8 Nov 2023 08:25:37 +0100
Subject: [PATCH 10/92] [NAE-1546] Plugin library
- moved meta objects
---
.../engine/integration/plugin/injector/PluginInjector.groovy | 2 ++
.../plugin/injector/{ => meta}/EntryPointMeta.groovy | 2 +-
.../integration/plugin/injector/{ => meta}/PluginMeta.groovy | 2 +-
.../com/netgrif/application/engine/startup/DemoRunner.groovy | 2 ++
4 files changed, 6 insertions(+), 2 deletions(-)
rename src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/{ => meta}/EntryPointMeta.groovy (91%)
rename src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/{ => meta}/PluginMeta.groovy (91%)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 60e18470d24..bb8419f3f7c 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -1,6 +1,8 @@
package com.netgrif.application.engine.integration.plugin.injector
import com.netgrif.application.engine.configuration.ApplicationContextProvider
+import com.netgrif.application.engine.integration.plugin.injector.meta.EntryPointMeta
+import com.netgrif.application.engine.integration.plugin.injector.meta.PluginMeta
import com.netgrif.application.engine.integration.plugins.domain.Plugin
import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy
similarity index 91%
rename from src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy
rename to src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy
index 17d71efc107..ae43eb76efd 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/EntryPointMeta.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy
@@ -1,4 +1,4 @@
-package com.netgrif.application.engine.integration.plugin.injector
+package com.netgrif.application.engine.integration.plugin.injector.meta
class EntryPointMeta {
}
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy
similarity index 91%
rename from src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy
rename to src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy
index 96eff9fbbe5..ef8d40cb333 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginMeta.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy
@@ -1,4 +1,4 @@
-package com.netgrif.application.engine.integration.plugin.injector
+package com.netgrif.application.engine.integration.plugin.injector.meta
class PluginMeta {
}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy b/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
index 4d7eb1b6e02..e31ed91745c 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
@@ -3,6 +3,7 @@ package com.netgrif.application.engine.startup
import com.netgrif.application.engine.elastic.domain.ElasticCaseRepository
import com.netgrif.application.engine.elastic.domain.ElasticTaskRepository
import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService
+import com.netgrif.application.engine.petrinet.domain.VersionType
import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository
import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository
import com.netgrif.application.engine.workflow.service.interfaces.IDataService
@@ -46,5 +47,6 @@ class DemoRunner extends AbstractOrderedCommandLineRunner {
@Override
void run(String... args) throws Exception {
// Code what is written here DO NOT COMMIT!
+ helper.createCase("Test", helper.createNet("nae_1546.xml", VersionType.MAJOR).get())
}
}
From e9a8faae8be25068daf3518fa1e33838793900d6 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Wed, 8 Nov 2023 09:12:05 +0100
Subject: [PATCH 11/92] [NAE-1546] Plugin library
- modified injector
- added name attribute to plugin
---
.../integration/plugin/injector/PluginInjector.groovy | 3 +--
.../engine/integration/plugins/domain/Plugin.java | 1 +
.../plugins/service/PluginRegistrationService.java | 1 +
.../integration/plugins/service/PluginService.java | 4 ++--
src/main/proto/RegistrationService.proto | 9 +++++----
5 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index bb8419f3f7c..2dead0ecbe4 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -7,7 +7,6 @@ import com.netgrif.application.engine.integration.plugins.domain.Plugin
import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
-
class PluginInjector {
static void inject(Plugin plugin) {
@@ -22,6 +21,6 @@ class PluginInjector {
}
pluginMetaClass[ep.value.identifier] = new EntryPointMeta()
}
- actionDelegateMeta[plugin.identifier] = new PluginMeta()
+ actionDelegateMeta[plugin.name] = new PluginMeta()
}
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
index 3c429bc3881..41a3201e288 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
@@ -15,6 +15,7 @@ public class Plugin {
@Id
private ObjectId _id;
private String identifier;
+ private String name;
private String url;
private long port;
private boolean active;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index 9e1ba6298c8..3158a2a09e4 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -51,6 +51,7 @@ public void deactivate(DeactivationRequest request, StreamObserver
Date: Wed, 8 Nov 2023 09:15:14 +0100
Subject: [PATCH 12/92] [NAE-1546] Plugin library
- added logging
---
.../engine/integration/plugins/service/PluginService.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index e2e248118e5..68c818b5af3 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -55,7 +55,11 @@ public void register(Plugin plugin) {
}
pluginRepository.save(plugin);
PluginInjector.inject(plugin);
- log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was registered.");
+ if (existingPlugin != null) {
+ log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was activated.");
+ } else {
+ log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was registered.");
+ }
}
@Override
From c39316fac21b53cb3e2ac51062bb21081e7ecc5c Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Wed, 8 Nov 2023 10:34:30 +0100
Subject: [PATCH 13/92] [NAE-1546] Plugin library
- modified convention
---
.../engine/integration/plugin/injector/PluginInjector.groovy | 4 ++--
.../engine/integration/plugins/domain/EntryPoint.java | 2 +-
.../plugins/service/PluginRegistrationService.java | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 2dead0ecbe4..76ec6892914 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -17,9 +17,9 @@ class PluginInjector {
ep.value.methods.each { m ->
entryPointMetaClass[m.value.name] << { Serializable... args ->
PluginService pluginService = ApplicationContextProvider.getBean("pluginService") as PluginService
- return pluginService.call(plugin.identifier, ep.value.identifier, m.value.name, args)}
+ return pluginService.call(plugin.identifier, ep.value.name, m.value.name, args)}
}
- pluginMetaClass[ep.value.identifier] = new EntryPointMeta()
+ pluginMetaClass[ep.value.name] = new EntryPointMeta()
}
actionDelegateMeta[plugin.name] = new PluginMeta()
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
index 1ded626275b..f7ec28fe01a 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
@@ -7,7 +7,7 @@
@Data
public class EntryPoint {
- private String identifier;
+ private String name;
private Map methods;
public EntryPoint() {
this.methods = new LinkedHashMap<>();
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index 3158a2a09e4..79b72e7bd49 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -57,7 +57,7 @@ private Plugin convert(RegistrationRequest request) {
plugin.setActive(true);
plugin.setEntryPoints(request.getEntryPointsList().stream().map(entryPoint -> {
EntryPoint ep = new EntryPoint();
- ep.setIdentifier(entryPoint.getIdentifier());
+ ep.setName(entryPoint.getName());
ep.setMethods(entryPoint.getMethodsList().stream().map(method -> {
Method mth = new Method();
mth.setName(method.getName());
@@ -65,7 +65,7 @@ private Plugin convert(RegistrationRequest request) {
return mth;
}).collect(Collectors.toMap(Method::getName, Function.identity())));
return ep;
- }).collect(Collectors.toMap(EntryPoint::getIdentifier, Function.identity())));
+ }).collect(Collectors.toMap(EntryPoint::getName, Function.identity())));
return plugin;
}
}
From 9d1dcba414c91797262ae2402fe827e4ae6f3bef Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Tue, 14 Nov 2023 09:45:46 +0100
Subject: [PATCH 14/92] [NAE-1546] Plugin library
- modified convention
---
.../service/PluginRegistrationService.java | 4 ++++
.../plugins/service/PluginService.java | 20 ++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index 79b72e7bd49..d38e8db8bd5 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -13,6 +13,10 @@
import java.util.function.Function;
import java.util.stream.Collectors;
+/**
+ * Implementation of {@link com.netgrif.pluginlibrary.core.RegistrationServiceGrpc.RegistrationServiceImplBase}. This
+ * serves as gRPC controller, that provides remotely executable functions.
+ * */
@Slf4j
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 68c818b5af3..aa1f9f8b73a 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -23,6 +23,10 @@
import java.util.List;
import java.util.stream.Collectors;
+/**
+ * Base service that manages gRPC server on application startup, registers, activates and deactivates plugins, sends
+ * plugin execution requests to desired plugin.
+ * */
@Slf4j
@Service
@RequiredArgsConstructor
@@ -30,6 +34,7 @@ public class PluginService implements IPluginService {
private final PluginRepository pluginRepository;
private final PluginRegistrationConfigProperties properties;
private Server server;
+
@PostConstruct
public void startServer() throws IOException {
server = ServerBuilder
@@ -43,9 +48,12 @@ public void startServer() throws IOException {
@PreDestroy
public void stopServer() {
server.shutdown();
- log.info("[gRPC Server] - Started on port " + properties.getPort());
+ log.info("[gRPC Server] - Sopped server on port " + properties.getPort());
}
+ /**
+ * @param plugin - plugin to be registered, or if already registered, then activate
+ * */
@Override
public void register(Plugin plugin) {
Plugin existingPlugin = pluginRepository.findByIdentifier(plugin.getIdentifier());
@@ -62,6 +70,13 @@ public void register(Plugin plugin) {
}
}
+ /**
+ * @param pluginId ID of plugin that contains the method that should be executed
+ * @param entryPoint name of entry point in plugin that contains the method that should be executed
+ * @param method name of method that should be executed
+ * @param args arguments to send to plugin method. All args should be the exact type of method input arguments type (not superclass, or subclass)
+ * @return the returned object of the executed plugin method
+ * */
@Override
public Object call(String pluginId, String entryPoint, String method, Serializable... args) {
Plugin plugin = pluginRepository.findByIdentifier(pluginId);
@@ -82,6 +97,9 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
return SerializationUtils.deserialize(responseMessage.getResponse().toByteArray());
}
+ /**
+ * @param identifier Identifier of plugin, that should be deactivated.
+ * */
@Override
public void deactivate(String identifier) {
Plugin existingPlugin = pluginRepository.findByIdentifier(identifier);
From 2700d0fe0ec6f1d2f1f214dda0cfbbde8aba9b09 Mon Sep 17 00:00:00 2001
From: Stefan Renczes
Date: Wed, 17 Jan 2024 13:29:35 +0100
Subject: [PATCH 15/92] [NAE-1935] Improved breadcrumbs from menu items
- modified pom
- added conditional on property
---
pom.xml | 14 ++++++++------
.../engine/startup/DemoRunner.groovy | 1 -
.../integration/plugins/domain/Plugin.java | 3 +--
.../properties/PluginConfigProperties.java | 19 +++++++++++++++++++
.../PluginRegistrationConfigProperties.java | 12 ------------
.../plugins/repository/PluginRepository.java | 6 ++++++
.../service/PluginRegistrationService.java | 6 ++++++
.../plugins/service/PluginService.java | 12 +++++++++---
src/main/resources/application.properties | 3 ++-
9 files changed, 51 insertions(+), 25 deletions(-)
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginConfigProperties.java
delete mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
diff --git a/pom.xml b/pom.xml
index 39377bd2e92..1c88265c559 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,8 @@
7.70.0.Finalnetgrif-osshttps://sonarcloud.io
+ 1.53.0
+ 3.17.3
@@ -341,22 +343,22 @@
io.grpcgrpc-netty
- 1.53.0
+ ${grpc.version}io.grpcgrpc-protobuf
- 1.53.0
+ ${grpc.version}io.grpcgrpc-stub
- 1.53.0
+ ${grpc.version}com.google.protobufprotobuf-java
- 3.17.3
+ ${protobuf.version}
@@ -801,11 +803,11 @@
0.6.1
- com.google.protobuf:protoc:3.17.3:exe:${os.detected.classifier}
+ com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
grpc-java
- io.grpc:protoc-gen-grpc-java:1.53.0:exe:${os.detected.classifier}
+ io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy b/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
index e31ed91745c..79553aca790 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
@@ -47,6 +47,5 @@ class DemoRunner extends AbstractOrderedCommandLineRunner {
@Override
void run(String... args) throws Exception {
// Code what is written here DO NOT COMMIT!
- helper.createCase("Test", helper.createNet("nae_1546.xml", VersionType.MAJOR).get())
}
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
index 41a3201e288..657bb668c6e 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
@@ -5,7 +5,6 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
-import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -13,7 +12,7 @@
@Document
public class Plugin {
@Id
- private ObjectId _id;
+ private ObjectId id;
private String identifier;
private String name;
private String url;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginConfigProperties.java b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginConfigProperties.java
new file mode 100644
index 00000000000..2bc0f1c54bc
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginConfigProperties.java
@@ -0,0 +1,19 @@
+package com.netgrif.application.engine.integration.plugins.properties;
+
+import lombok.Data;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConditionalOnProperty(
+ value = "nae.plugin.enabled",
+ havingValue = "true",
+ matchIfMissing = true
+)
+@ConfigurationProperties(prefix = "nae.plugin")
+public class PluginConfigProperties {
+ private boolean enabled;
+ private int port;
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java b/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
deleted file mode 100644
index a62eea660cc..00000000000
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/properties/PluginRegistrationConfigProperties.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.netgrif.application.engine.integration.plugins.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-@Data
-@Component
-@ConfigurationProperties(prefix = "nae.plugin.registration")
-public class PluginRegistrationConfigProperties {
- private int port;
-}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java b/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
index a33dbda89b8..2e7e9cb2308 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
@@ -2,10 +2,16 @@
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
import org.bson.types.ObjectId;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
+@ConditionalOnProperty(
+ value = "nae.plugin.enabled",
+ havingValue = "true",
+ matchIfMissing = true
+)
public interface PluginRepository extends MongoRepository {
Plugin findByIdentifier(String identifier);
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index d38e8db8bd5..b4a2bf8768b 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -7,6 +7,7 @@
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.SerializationUtils;
@@ -20,6 +21,11 @@
@Slf4j
@Service
@RequiredArgsConstructor
+@ConditionalOnProperty(
+ value = "nae.plugin.enabled",
+ havingValue = "true",
+ matchIfMissing = true
+)
public final class PluginRegistrationService extends RegistrationServiceGrpc.RegistrationServiceImplBase {
private final IPluginService pluginService;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index aa1f9f8b73a..821a1e852ca 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -3,7 +3,7 @@
import com.google.protobuf.ByteString;
import com.netgrif.application.engine.integration.plugin.injector.PluginInjector;
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
-import com.netgrif.application.engine.integration.plugins.properties.PluginRegistrationConfigProperties;
+import com.netgrif.application.engine.integration.plugins.properties.PluginConfigProperties;
import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
import com.netgrif.pluginlibrary.core.*;
import io.grpc.ManagedChannel;
@@ -13,6 +13,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SerializationUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@@ -30,9 +31,14 @@
@Slf4j
@Service
@RequiredArgsConstructor
+@ConditionalOnProperty(
+ value = "nae.plugin.enabled",
+ havingValue = "true",
+ matchIfMissing = true
+)
public class PluginService implements IPluginService {
private final PluginRepository pluginRepository;
- private final PluginRegistrationConfigProperties properties;
+ private final PluginConfigProperties properties;
private Server server;
@PostConstruct
@@ -59,7 +65,7 @@ public void register(Plugin plugin) {
Plugin existingPlugin = pluginRepository.findByIdentifier(plugin.getIdentifier());
if (existingPlugin != null) {
log.warn("Plugin with identifier \"" + plugin.getIdentifier() + "\" has already been registered. Plugin will be activated.");
- plugin.set_id(existingPlugin.get_id());
+ plugin.setId(existingPlugin.getId());
}
pluginRepository.save(plugin);
PluginInjector.inject(plugin);
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index a49b9ca5d12..024f09dda41 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -178,4 +178,5 @@ nae.field-runner.cache-size.namespace-functions=500
nae.filter.export.file-name=filters.xml
# Plugin
-nae.plugin.registration.port=${NAE_APP_PORT:8081}
+nae.plugin.enabled=${NAE_PLUGIN_ENABLED:false}
+nae.plugin.registration.port=${NAE_REGISTRATION_PORT:8081}
From d6bfcbe7322da34ee4765d2ea43eb9645a4e5393 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 6 May 2024 10:24:03 +0200
Subject: [PATCH 16/92] [NAE-1546] Plugin library - add or update javadoc -
optimize imports in DemoRunner - implement PluginRunner - make
Plugin.identifier indexed - refactor in PluginRegistrationService - refactor
methods in PluginService - fix warning in ClassToStringConverter - fix
properties for plugin management - update gRPC version
---
pom.xml | 2 +-
.../plugin/injector/PluginInjector.groovy | 5 ++
.../injector/meta/EntryPointMeta.groovy | 4 +
.../plugin/injector/meta/PluginMeta.groovy | 4 +
.../engine/startup/DemoRunner.groovy | 1 -
.../engine/startup/PluginRunner.groovy | 27 +++++++
.../engine/startup/RunnerController.groovy | 1 +
.../plugins/domain/EntryPoint.java | 1 +
.../integration/plugins/domain/Method.java | 2 +-
.../integration/plugins/domain/Plugin.java | 2 +
.../plugins/service/IPluginService.java | 9 ++-
.../service/PluginRegistrationService.java | 56 +++++++++-----
.../plugins/service/PluginService.java | 76 ++++++++++++++-----
.../plugins/utils/ClassToStringConverter.java | 16 +++-
src/main/resources/application.properties | 2 +-
15 files changed, 156 insertions(+), 52 deletions(-)
create mode 100644 src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
diff --git a/pom.xml b/pom.xml
index 90c528dfa95..00ea6afbf1b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@
7.70.0.Finalnetgrif-osshttps://sonarcloud.io
- 1.53.0
+ 1.63.03.17.3
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 76ec6892914..8a208dc2b4c 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -9,6 +9,11 @@ import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.Actio
class PluginInjector {
+ /**
+ * Injects provided plugin into meta class of {@link ActionDelegate}
+ *
+ * @param plugin model of plugin to be injected
+ * */
static void inject(Plugin plugin) {
MetaClass actionDelegateMeta = ActionDelegate.metaClass
MetaClass pluginMetaClass = PluginMeta.metaClass
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy
index ae43eb76efd..32772273c8f 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/EntryPointMeta.groovy
@@ -1,4 +1,8 @@
package com.netgrif.application.engine.integration.plugin.injector.meta
+/**
+ * Class, that has modified meta class and is injected into
+ * {@link com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate}. No class-attributes needed.
+ * */
class EntryPointMeta {
}
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy
index ef8d40cb333..be087ec59bd 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/meta/PluginMeta.groovy
@@ -1,4 +1,8 @@
package com.netgrif.application.engine.integration.plugin.injector.meta
+/**
+ * Class, that has modified meta class and is injected into
+ * {@link com.netgrif.application.engine.integration.plugin.injector.meta.EntryPointMeta}. No class-attributes needed.
+ * */
class PluginMeta {
}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy b/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
index 79553aca790..4d7eb1b6e02 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/DemoRunner.groovy
@@ -3,7 +3,6 @@ package com.netgrif.application.engine.startup
import com.netgrif.application.engine.elastic.domain.ElasticCaseRepository
import com.netgrif.application.engine.elastic.domain.ElasticTaskRepository
import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService
-import com.netgrif.application.engine.petrinet.domain.VersionType
import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository
import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository
import com.netgrif.application.engine.workflow.service.interfaces.IDataService
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy b/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
new file mode 100644
index 00000000000..a4acf41330f
--- /dev/null
+++ b/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
@@ -0,0 +1,27 @@
+package com.netgrif.application.engine.startup
+
+import com.netgrif.application.engine.integration.plugin.injector.PluginInjector
+import com.netgrif.application.engine.integration.plugins.domain.Plugin
+import com.netgrif.application.engine.integration.plugins.service.IPluginService
+import groovy.util.logging.Slf4j
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+
+@Slf4j
+@Component
+class PluginRunner extends AbstractOrderedCommandLineRunner {
+
+ @Autowired
+ private IPluginService pluginService
+
+ @Override
+ void run(String... args) throws Exception {
+ List plugins = pluginService.findAll()
+ plugins.size()
+
+ log.info("Re-injecting ${plugins.size()} plugins from database into memory.")
+ plugins.each { plugin ->
+ PluginInjector.inject(plugin)
+ }
+ }
+}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy b/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy
index f02d30e1c8f..16280193ab1 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy
@@ -15,6 +15,7 @@ class RunnerController {
AuthorityRunner,
SystemUserRunner,
UriRunner,
+ PluginRunner,
FunctionsCacheRunner,
FilterRunner,
GroupRunner,
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
index f7ec28fe01a..5498e8ceaf5 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
@@ -9,6 +9,7 @@
public class EntryPoint {
private String name;
private Map methods;
+
public EntryPoint() {
this.methods = new LinkedHashMap<>();
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
index 9f88750b4ff..3b700b3200e 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
@@ -2,7 +2,6 @@
import com.netgrif.application.engine.integration.plugins.utils.ClassToStringConverter;
import lombok.Data;
-import org.springframework.data.convert.PropertyValueConverter;
import org.springframework.data.convert.ValueConverter;
import java.util.ArrayList;
@@ -13,6 +12,7 @@ public class Method {
private String name;
@ValueConverter(ClassToStringConverter.class)
private List> args;
+
public Method() {
this.args = new ArrayList<>();
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
index 657bb668c6e..678270fdaaf 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
@@ -3,6 +3,7 @@
import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.LinkedHashMap;
@@ -13,6 +14,7 @@
public class Plugin {
@Id
private ObjectId id;
+ @Indexed
private String identifier;
private String name;
private String url;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
index acfd6da4f05..33977f82247 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -3,11 +3,14 @@
import com.netgrif.application.engine.integration.plugins.domain.Plugin;
import java.io.Serializable;
+import java.util.List;
public interface IPluginService {
- void register(Plugin plugin);
+ String registerOrActivate(Plugin plugin);
- Object call(String pluginId, String entryPoint, String method, Serializable... args);
+ Object call(String pluginId, String entryPoint, String method, Serializable... args) throws IllegalArgumentException;
- void deactivate(String identifier);
+ String deactivate(String identifier) throws IllegalArgumentException;
+
+ List findAll();
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index b4a2bf8768b..3c7c78a58b4 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -11,6 +11,8 @@
import org.springframework.stereotype.Service;
import org.springframework.util.SerializationUtils;
+import java.util.List;
+import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -29,13 +31,17 @@
public final class PluginRegistrationService extends RegistrationServiceGrpc.RegistrationServiceImplBase {
private final IPluginService pluginService;
+
+ /**
+ * Registers or activate plugin provided by request.
+ *
+ * @param request request containing information about the plugin to be registered
+ * */
@Override
public void register(RegistrationRequest request, StreamObserver responseObserver) {
try {
- pluginService.register(convert(request));
- RegistrationResponse response = RegistrationResponse.newBuilder()
- .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully registered.")
- .build();
+ String responseMsg = pluginService.registerOrActivate(convertRequestToModel(request));
+ RegistrationResponse response = RegistrationResponse.newBuilder().setMessage(responseMsg).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (IllegalArgumentException e) {
@@ -43,13 +49,16 @@ public void register(RegistrationRequest request, StreamObserver responseObserver) {
try {
- pluginService.deactivate(request.getIdentifier());
- DeactivationResponse response = DeactivationResponse.newBuilder()
- .setMessage("Plugin with identifier \"" + request.getIdentifier() + "\" was successfully deactivated.")
- .build();
+ String responseMsg = pluginService.deactivate(request.getIdentifier());
+ DeactivationResponse response = DeactivationResponse.newBuilder().setMessage(responseMsg).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (IllegalArgumentException e) {
@@ -58,24 +67,31 @@ public void deactivate(DeactivationRequest request, StreamObserver {
- EntryPoint ep = new EntryPoint();
- ep.setName(entryPoint.getName());
- ep.setMethods(entryPoint.getMethodsList().stream().map(method -> {
- Method mth = new Method();
- mth.setName(method.getName());
- mth.setArgs(method.getArgsList().stream().map(arg -> (Class>) SerializationUtils.deserialize(arg.toByteArray())).collect(Collectors.toList()));
- return mth;
- }).collect(Collectors.toMap(Method::getName, Function.identity())));
- return ep;
- }).collect(Collectors.toMap(EntryPoint::getName, Function.identity())));
+ plugin.setEntryPoints(convertEntryPointsFromRequest(request.getEntryPointsList()));
return plugin;
}
+
+ private Map convertEntryPointsFromRequest(List entryPoints) {
+ return entryPoints.stream().map(epReq -> {
+ EntryPoint epModel = new EntryPoint();
+ epModel.setName(epReq.getName());
+ epModel.setMethods(epReq.getMethodsList().stream().map(methodReq -> {
+ Method methodModel = new Method();
+ methodModel.setName(methodReq.getName());
+ methodModel.setArgs(methodReq.getArgsList().stream()
+ .map(arg -> (Class>) SerializationUtils.deserialize(arg.toByteArray()))
+ .collect(Collectors.toList())
+ );
+ return methodModel;
+ }).collect(Collectors.toMap(Method::getName, Function.identity())));
+ return epModel;
+ }).collect(Collectors.toMap(EntryPoint::getName, Function.identity()));
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 821a1e852ca..f74f0c56595 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -13,6 +13,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SerializationUtils;
+import org.bson.types.ObjectId;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@@ -25,7 +26,7 @@
import java.util.stream.Collectors;
/**
- * Base service that manages gRPC server on application startup, registers, activates and deactivates plugins, sends
+ * Base service, that manages gRPC server on application startup, registers, activates and deactivates plugins, sends
* plugin execution requests to desired plugin.
* */
@Slf4j
@@ -41,6 +42,8 @@ public class PluginService implements IPluginService {
private final PluginConfigProperties properties;
private Server server;
+ private static final String LOG_PREFIX = "[gRPC Server] -";
+
@PostConstruct
public void startServer() throws IOException {
server = ServerBuilder
@@ -48,47 +51,65 @@ public void startServer() throws IOException {
.addService(new PluginRegistrationService(this))
.build();
server.start();
- log.info("[gRPC Server] - Started on port " + properties.getPort());
+ log.info(LOG_PREFIX + " Started on port " + properties.getPort());
}
@PreDestroy
public void stopServer() {
server.shutdown();
- log.info("[gRPC Server] - Sopped server on port " + properties.getPort());
+ log.info(LOG_PREFIX + " Stopped server on port " + properties.getPort());
}
/**
- * @param plugin - plugin to be registered, or if already registered, then activate
+ * Registers provided plugin into repository. If the plugin already exists, it's activated.
+ * @param plugin - plugin to be registered, or if already registered, then activated
+ *
+ * @return activation or registration string message is returned
* */
@Override
- public void register(Plugin plugin) {
+ public String registerOrActivate(Plugin plugin) {
Plugin existingPlugin = pluginRepository.findByIdentifier(plugin.getIdentifier());
- if (existingPlugin != null) {
- log.warn("Plugin with identifier \"" + plugin.getIdentifier() + "\" has already been registered. Plugin will be activated.");
- plugin.setId(existingPlugin.getId());
- }
+ return existingPlugin == null ? register(plugin) : activate(plugin, existingPlugin.getId());
+ }
+
+ private String register(Plugin plugin) {
+ return saveAndInject(plugin, "registered");
+ }
+
+ private String activate(Plugin plugin, ObjectId existingPluginId) {
+ plugin.setActive(true);
+ plugin.setId(existingPluginId);
+ return saveAndInject(plugin, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
+ }
+
+ private String saveAndInject(Plugin plugin, String state) {
pluginRepository.save(plugin);
PluginInjector.inject(plugin);
- if (existingPlugin != null) {
- log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was activated.");
- } else {
- log.info("Plugin with identifier \"" + plugin.getIdentifier() + "\" was registered.");
- }
+
+ String responseMsg = "Plugin with identifier \"" + plugin.getIdentifier() + "\" was " + state + ".";
+ log.info(responseMsg);
+ return responseMsg;
}
/**
- * @param pluginId ID of plugin that contains the method that should be executed
- * @param entryPoint name of entry point in plugin that contains the method that should be executed
- * @param method name of method that should be executed
+ * Calls method with arguments of a specified entry point
+ *
+ * @param pluginId plugin identifier, that contains the method to be executed
+ * @param entryPoint name of entry point in plugin, that contains the method to be executed
+ * @param method name of method to be executed
* @param args arguments to send to plugin method. All args should be the exact type of method input arguments type (not superclass, or subclass)
+ *
* @return the returned object of the executed plugin method
* */
@Override
- public Object call(String pluginId, String entryPoint, String method, Serializable... args) {
+ public Object call(String pluginId, String entryPoint, String method, Serializable... args) throws IllegalArgumentException {
Plugin plugin = pluginRepository.findByIdentifier(pluginId);
if (plugin == null) {
throw new IllegalArgumentException("Plugin with identifier \"" + pluginId + "\" cannot be found");
}
+ if (!plugin.isActive()) {
+ throw new IllegalArgumentException("Plugin with name \"" + plugin.getName() + "\" is deactivated");
+ }
ManagedChannel channel = ManagedChannelBuilder.forAddress(plugin.getUrl(), (int) plugin.getPort())
.usePlaintext()
.build();
@@ -104,18 +125,31 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
}
/**
- * @param identifier Identifier of plugin, that should be deactivated.
+ * Deactivates the plugin of the provided identifier
+ *
+ * @param identifier Identifier of the plugin, that should be deactivated.
* */
@Override
- public void deactivate(String identifier) {
+ public String deactivate(String identifier) throws IllegalArgumentException {
Plugin existingPlugin = pluginRepository.findByIdentifier(identifier);
if (existingPlugin == null) {
throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be deactivated. Plugin with this identifier does not exist.");
}
existingPlugin.setActive(false);
pluginRepository.save(existingPlugin);
- log.info("Plugin with identifier \"" + identifier + "\" was deactivated.");
+
+ String responseMsg = "Plugin with identifier \"" + identifier + "\" was deactivated.";
+ log.info(responseMsg);
+ return responseMsg;
}
+ /**
+ * Finds all plugins in the database
+ *
+ * @return list of plugins
+ * */
+ public List findAll() {
+ return pluginRepository.findAll();
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
index 6a44c84a8e5..e86df265790 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
@@ -1,5 +1,6 @@
package com.netgrif.application.engine.integration.plugins.utils;
+import com.mongodb.lang.NonNull;
import org.springframework.data.convert.PropertyValueConverter;
import org.springframework.data.mongodb.core.convert.MongoConversionContext;
@@ -7,19 +8,26 @@
import java.util.stream.Collectors;
public class ClassToStringConverter implements PropertyValueConverter>, List, MongoConversionContext> {
+
+ /**
+ * Maps provided class names into list of {@link Class} objects
+ * */
@Override
- public List> read(List value, MongoConversionContext context) {
- return value.stream().map(v -> {
+ public List> read(List classNames, @NonNull MongoConversionContext context) {
+ return classNames.stream().map(name -> {
try {
- return Class.forName(v);
+ return Class.forName(name);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
}
+ /**
+ * Maps provided objects of {@link Class} into list of class names
+ * */
@Override
- public List write(List> value, MongoConversionContext context) {
+ public List write(List> value, @NonNull MongoConversionContext context) {
return value.stream().map(Class::getName).collect(Collectors.toList());
}
}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 590c89a7fb6..32d34b1fa85 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -183,4 +183,4 @@ nae.filter.export.file-name=filters.xml
# Plugin
nae.plugin.enabled=${NAE_PLUGIN_ENABLED:false}
-nae.plugin.registration.port=${NAE_REGISTRATION_PORT:8081}
+nae.plugin.port=${NAE_REGISTRATION_PORT:8081}
From 382a714398e3cdc74db092738379d07d81059ee8 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 6 May 2024 10:25:33 +0200
Subject: [PATCH 17/92] [NAE-1546] Plugin library - move methods in
PluginService
---
.../plugins/service/PluginService.java | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index f74f0c56595..16d5b2f5a10 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -72,25 +72,6 @@ public String registerOrActivate(Plugin plugin) {
return existingPlugin == null ? register(plugin) : activate(plugin, existingPlugin.getId());
}
- private String register(Plugin plugin) {
- return saveAndInject(plugin, "registered");
- }
-
- private String activate(Plugin plugin, ObjectId existingPluginId) {
- plugin.setActive(true);
- plugin.setId(existingPluginId);
- return saveAndInject(plugin, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
- }
-
- private String saveAndInject(Plugin plugin, String state) {
- pluginRepository.save(plugin);
- PluginInjector.inject(plugin);
-
- String responseMsg = "Plugin with identifier \"" + plugin.getIdentifier() + "\" was " + state + ".";
- log.info(responseMsg);
- return responseMsg;
- }
-
/**
* Calls method with arguments of a specified entry point
*
@@ -152,4 +133,23 @@ public List findAll() {
return pluginRepository.findAll();
}
+ private String register(Plugin plugin) {
+ return saveAndInject(plugin, "registered");
+ }
+
+ private String activate(Plugin plugin, ObjectId existingPluginId) {
+ plugin.setActive(true);
+ plugin.setId(existingPluginId);
+ return saveAndInject(plugin, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
+ }
+
+ private String saveAndInject(Plugin plugin, String state) {
+ pluginRepository.save(plugin);
+ PluginInjector.inject(plugin);
+
+ String responseMsg = "Plugin with identifier \"" + plugin.getIdentifier() + "\" was " + state + ".";
+ log.info(responseMsg);
+ return responseMsg;
+ }
+
}
From d020ee56d0907e095bbae263ff1aa269b5518c18 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 6 May 2024 11:03:59 +0200
Subject: [PATCH 18/92] [NAE-1546] Plugin library - implement
PluginRegistrationServiceTest
---
.../integrations/plugins/mock/MockPlugin.java | 40 ++++++++++++++++++
.../PluginRegistrationServiceTest.java | 42 +++++++++++++++++++
.../resources/application-test.properties | 6 ++-
3 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
create mode 100644 src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
new file mode 100644
index 00000000000..7d2c523c99c
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
@@ -0,0 +1,40 @@
+package com.netgrif.application.engine.integrations.plugins.mock;
+
+import com.netgrif.pluginlibrary.core.DeactivationRequest;
+import com.netgrif.pluginlibrary.core.RegistrationRequest;
+import com.netgrif.pluginlibrary.core.RegistrationServiceGrpc;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+
+public class MockPlugin {
+
+ public static final String mockIdentifier = "mock_plugin";
+ public static final String mockName = "mockPlugin";
+
+ public static void registerOrActivatePlugin() {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
+ .usePlaintext()
+ .build();
+
+ RegistrationServiceGrpc.RegistrationServiceBlockingStub stub = RegistrationServiceGrpc.newBlockingStub(channel);
+ stub.register(RegistrationRequest.newBuilder()
+ .setIdentifier(mockIdentifier)
+ .setName(mockName)
+ .setUrl("mockurl")
+ .setPort(9999)
+ .build());
+ channel.shutdown();
+ }
+
+ public static void deactivatePlugin() {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
+ .usePlaintext()
+ .build();
+
+ RegistrationServiceGrpc.RegistrationServiceBlockingStub stub = RegistrationServiceGrpc.newBlockingStub(channel);
+ stub.deactivate(DeactivationRequest.newBuilder()
+ .setIdentifier(mockIdentifier)
+ .build());
+ channel.shutdown();
+ }
+}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
new file mode 100644
index 00000000000..c34ae256365
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -0,0 +1,42 @@
+package com.netgrif.application.engine.integrations.plugins.service;
+
+import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import com.netgrif.application.engine.integrations.plugins.mock.MockPlugin;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+@SpringBootTest
+@ActiveProfiles({"test"})
+public class PluginRegistrationServiceTest {
+
+ @Autowired
+ private PluginRepository repository;
+
+ @BeforeEach
+ public void before() {
+ repository.deleteAll();
+ }
+
+ @Test
+ public void testRegistrationDeactivationAndActivation() {
+ MockPlugin.registerOrActivatePlugin();
+ Plugin foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
+ assert foundPlugin != null;
+ assert foundPlugin.isActive();
+
+ MockPlugin.deactivatePlugin();
+ foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
+ assert foundPlugin != null;
+ assert !foundPlugin.isActive();
+
+ MockPlugin.registerOrActivatePlugin();
+ foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
+ assert foundPlugin != null;
+ assert foundPlugin.isActive();
+ }
+
+}
diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties
index 0c38d3eb36d..eb510e50b5b 100644
--- a/src/test/resources/application-test.properties
+++ b/src/test/resources/application-test.properties
@@ -68,4 +68,8 @@ nae.ldap.enabled=false
# case field expression runner
expressions.runner.cache-size=200
-nae.public.url=test.public.url
\ No newline at end of file
+nae.public.url=test.public.url
+
+# Plugin
+nae.plugin.enabled=true
+nae.plugin.port=8081
\ No newline at end of file
From 048199c64e9d9da8bfa4704b37d1b3fbf93242f7 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 6 May 2024 11:36:28 +0200
Subject: [PATCH 19/92] [NAE-1546] Plugin library - implement PluginServiceTest
---
.../plugins/mock/MockExecutionService.java | 52 +++++++++++++
.../plugins/service/PluginServiceTest.java | 74 +++++++++++++++++++
2 files changed, 126 insertions(+)
create mode 100644 src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java
create mode 100644 src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java
new file mode 100644
index 00000000000..713a4d0beb1
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java
@@ -0,0 +1,52 @@
+package com.netgrif.application.engine.integrations.plugins.mock;
+
+import com.google.protobuf.ByteString;
+import com.netgrif.pluginlibrary.core.ExecutionRequest;
+import com.netgrif.pluginlibrary.core.ExecutionResponse;
+import com.netgrif.pluginlibrary.core.ExecutionServiceGrpc;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.commons.lang3.SerializationUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.io.IOException;
+
+@Service
+public class MockExecutionService extends ExecutionServiceGrpc.ExecutionServiceImplBase {
+
+ private static final int port = 8090;
+ private Server server;
+
+ public ExecutionRequest lastExecutionRequest;
+
+ @PostConstruct
+ public void startServer() throws IOException {
+ server = ServerBuilder
+ .forPort(port)
+ .addService(this)
+ .build();
+ server.start();
+ }
+
+ @PreDestroy
+ public void stopServer() {
+ server.shutdown();
+ }
+
+ @Override
+ public void execute(ExecutionRequest request, StreamObserver responseObserver) {
+ lastExecutionRequest = request;
+ try {
+ ExecutionResponse executionResponse = ExecutionResponse.newBuilder()
+ .setResponse(ByteString.copyFrom(SerializationUtils.serialize("mockResponse")))
+ .build();
+ responseObserver.onNext(executionResponse);
+ responseObserver.onCompleted();
+ } catch (Exception e) {
+ responseObserver.onError(e);
+ }
+ }
+}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
new file mode 100644
index 00000000000..8c09ba61abb
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
@@ -0,0 +1,74 @@
+package com.netgrif.application.engine.integrations.plugins.service;
+
+import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import com.netgrif.application.engine.integration.plugins.service.IPluginService;
+import com.netgrif.application.engine.integrations.plugins.mock.MockExecutionService;
+import com.netgrif.pluginlibrary.core.ExecutionRequest;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@SpringBootTest
+@ActiveProfiles({"test"})
+public class PluginServiceTest {
+
+ @Autowired
+ private PluginRepository repository;
+
+ @Autowired
+ private IPluginService pluginService;
+
+ @Autowired
+ private MockExecutionService mockExecutionService;
+
+ private static final String pluginIdentifier = "mock_plugin";
+
+ @BeforeEach
+ public void before() {
+ repository.deleteAll();
+ }
+
+ @Test
+ public void testCallRequestAndResponse() {
+ Plugin plugin = new Plugin();
+ plugin.setIdentifier(pluginIdentifier);
+ plugin.setName("mockPlugin");
+ plugin.setUrl("localhost");
+ plugin.setPort(8090);
+ plugin.setActive(true);
+ repository.save(plugin);
+
+ Object response = pluginService.call(pluginIdentifier, "mockEP", "mockMethod", "mockArg1", "mockArg2");
+
+ ExecutionRequest request = mockExecutionService.lastExecutionRequest;
+
+ assert request.getEntryPoint().equals("mockEP");
+ assert request.getMethod().equals("mockMethod");
+ assert request.getArgsList().size() == 2;
+
+ assert response.equals("mockResponse");
+ }
+
+ @Test
+ public void testCallMissingPlugin() {
+ assertThrows(IllegalArgumentException.class, () -> pluginService.call("missingIdentifier", "missingEP", "missingMethod"));
+ }
+
+ @Test
+ public void testCallDeactivatedPlugin() {
+ Plugin plugin = new Plugin();
+ plugin.setIdentifier(pluginIdentifier);
+ plugin.setName("mockPlugin");
+ plugin.setUrl("localhost");
+ plugin.setPort(8090);
+ plugin.setActive(false);
+ repository.save(plugin);
+
+ assertThrows(IllegalArgumentException.class, () -> pluginService.call(pluginIdentifier, "mockEP", "mockMethod"));
+ }
+}
From 46cc13df0d6cbb436c6ad1913298b227e95a798b Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 7 May 2024 09:52:09 +0200
Subject: [PATCH 20/92] [NAE-1546] Plugin library - implement unregistration of
plugin
---
.../plugin/injector/PluginInjector.groovy | 28 +++++++++++++++----
.../plugins/service/IPluginService.java | 2 ++
.../service/PluginRegistrationService.java | 17 +++++++++++
.../plugins/service/PluginService.java | 21 ++++++++++++++
src/main/proto/RegistrationService.proto | 9 ++++++
5 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 8a208dc2b4c..643bb5144dc 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -15,17 +15,35 @@ class PluginInjector {
* @param plugin model of plugin to be injected
* */
static void inject(Plugin plugin) {
+ updateMetaClasses(plugin, false)
+ }
+
+ /**
+ * Removes provided plugin from the meta class of {@link ActionDelegate}.
+ *
+ * @param plugin model of plugin to be uninjected
+ * */
+ static void uninject(Plugin plugin) {
+ updateMetaClasses(plugin, true)
+ }
+
+ protected static void updateMetaClasses(Plugin plugin, boolean isRemoval) {
MetaClass actionDelegateMeta = ActionDelegate.metaClass
MetaClass pluginMetaClass = PluginMeta.metaClass
plugin.entryPoints.each {ep ->
MetaClass entryPointMetaClass = EntryPointMeta.metaClass
ep.value.methods.each { m ->
- entryPointMetaClass[m.value.name] << { Serializable... args ->
- PluginService pluginService = ApplicationContextProvider.getBean("pluginService") as PluginService
- return pluginService.call(plugin.identifier, ep.value.name, m.value.name, args)}
+ if (isRemoval) {
+ entryPointMetaClass[m.value.name] = null
+ } else {
+ entryPointMetaClass[m.value.name] << { Serializable... args ->
+ PluginService pluginService = ApplicationContextProvider.getBean("pluginService") as PluginService
+ return pluginService.call(plugin.identifier, ep.value.name, m.value.name, args)
+ }
+ }
}
- pluginMetaClass[ep.value.name] = new EntryPointMeta()
+ pluginMetaClass[ep.value.name] = isRemoval ? null : new EntryPointMeta()
}
- actionDelegateMeta[plugin.name] = new PluginMeta()
+ actionDelegateMeta[plugin.name] = isRemoval ? null : new PluginMeta()
}
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
index 33977f82247..0b52a2fa415 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -8,6 +8,8 @@
public interface IPluginService {
String registerOrActivate(Plugin plugin);
+ String unregister(String identifier) throws IllegalArgumentException;
+
Object call(String pluginId, String entryPoint, String method, Serializable... args) throws IllegalArgumentException;
String deactivate(String identifier) throws IllegalArgumentException;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index 3c7c78a58b4..a99fec51c4e 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -49,6 +49,23 @@ public void register(RegistrationRequest request, StreamObserver responseObserver) {
+ try {
+ String responseMsg = pluginService.unregister(request.getIdentifier());
+ UnregistrationResponse response = UnregistrationResponse.newBuilder().setMessage(responseMsg).build();
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
+ } catch (IllegalArgumentException e) {
+ responseObserver.onError(e);
+ }
+ }
+
/**
* Deactivates plugin provided by request.
*
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 16d5b2f5a10..c36e5c8ee3b 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -72,6 +72,27 @@ public String registerOrActivate(Plugin plugin) {
return existingPlugin == null ? register(plugin) : activate(plugin, existingPlugin.getId());
}
+ /**
+ * Unregisters provided plugin from memory and database
+ * @param identifier - identifier of the plugin to be unregistered
+ *
+ * @return unregistration string message is returned
+ * */
+ @Override
+ public String unregister(String identifier) {
+ Plugin plugin = pluginRepository.findByIdentifier(identifier);
+ if (plugin == null) {
+ throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be found");
+ }
+
+ PluginInjector.uninject(plugin);
+ pluginRepository.delete(plugin);
+
+ String responseMsg = "Plugin with identifier \"" + identifier + "\" was unregistered.";
+ log.info(responseMsg);
+ return responseMsg;
+ }
+
/**
* Calls method with arguments of a specified entry point
*
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
index 079c657f627..f58badafde8 100644
--- a/src/main/proto/RegistrationService.proto
+++ b/src/main/proto/RegistrationService.proto
@@ -21,6 +21,10 @@ message RegistrationRequest {
repeated EntryPoint entryPoints = 5;
}
+message UnregistrationRequest {
+ string identifier = 1;
+}
+
message DeactivationRequest {
string identifier = 1;
}
@@ -29,11 +33,16 @@ message RegistrationResponse {
string message = 1;
}
+message UnregistrationResponse {
+ string message = 1;
+}
+
message DeactivationResponse {
string message = 1;
}
service RegistrationService {
rpc register(RegistrationRequest) returns (RegistrationResponse);
+ rpc unregister(UnregistrationRequest) returns (UnregistrationResponse);
rpc deactivate(DeactivationRequest) returns (DeactivationResponse);
}
\ No newline at end of file
From fc9b8f99f7cabf47ff49eb265d25d1cd0b9d3572 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 7 May 2024 10:04:22 +0200
Subject: [PATCH 21/92] [NAE-1546] Plugin library - implement
PluginRegistrationServiceTest.testUnregister
---
.../integrations/plugins/mock/MockPlugin.java | 13 +++++++++++++
.../service/PluginRegistrationServiceTest.java | 11 +++++++++++
2 files changed, 24 insertions(+)
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
index 7d2c523c99c..b192e569a69 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
@@ -3,6 +3,7 @@
import com.netgrif.pluginlibrary.core.DeactivationRequest;
import com.netgrif.pluginlibrary.core.RegistrationRequest;
import com.netgrif.pluginlibrary.core.RegistrationServiceGrpc;
+import com.netgrif.pluginlibrary.core.UnregistrationRequest;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
@@ -26,6 +27,18 @@ public static void registerOrActivatePlugin() {
channel.shutdown();
}
+ public static void unregisterPlugin() {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
+ .usePlaintext()
+ .build();
+
+ RegistrationServiceGrpc.RegistrationServiceBlockingStub stub = RegistrationServiceGrpc.newBlockingStub(channel);
+ stub.unregister(UnregistrationRequest.newBuilder()
+ .setIdentifier(mockIdentifier)
+ .build());
+ channel.shutdown();
+ }
+
public static void deactivatePlugin() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
.usePlaintext()
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index c34ae256365..ad1efe5cb7b 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -39,4 +39,15 @@ public void testRegistrationDeactivationAndActivation() {
assert foundPlugin.isActive();
}
+ @Test
+ public void testUnregister() {
+ MockPlugin.registerOrActivatePlugin();
+ Plugin foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
+ assert foundPlugin != null;
+
+ MockPlugin.unregisterPlugin();
+ foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
+ assert foundPlugin == null;
+ }
+
}
From d59976592e3d04a19bcb8a79dec4564ad5a1547e Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 13 May 2024 14:26:48 +0200
Subject: [PATCH 22/92] [NAE-1546] Plugin library - rework plugin as process -
update plugin runner - remove plugin models and repository - add method in
ImportHelper - mark method ImportHelper.populateDataset as deprecated - add
error logging in PluginRegistrationService - create plugin constants in
PluginConstants - create plugin utils in PluginUtils - update javadoc - fix
and update tests
---
.../plugin/injector/PluginInjector.groovy | 47 ++-
.../engine/startup/ImportHelper.groovy | 7 +
.../engine/startup/PluginRunner.groovy | 29 +-
.../plugins/domain/EntryPoint.java | 16 -
.../integration/plugins/domain/Method.java | 19 -
.../integration/plugins/domain/Plugin.java | 28 --
.../outcomes/CreateOrUpdateOutcome.java | 38 ++
.../plugins/outcomes/GetOrCreateOutcome.java | 12 +
.../plugins/repository/PluginRepository.java | 17 -
.../plugins/service/IPluginService.java | 10 +-
.../service/PluginRegistrationService.java | 50 +--
.../plugins/service/PluginService.java | 328 +++++++++++++++---
.../plugins/utils/ClassToStringConverter.java | 33 --
.../plugins/utils/PluginConstants.java | 24 ++
.../plugins/utils/PluginUtils.java | 168 +++++++++
.../engine-processes/plugin/entry_point.xml | 76 ++++
.../engine-processes/plugin/method.xml | 73 ++++
.../engine-processes/plugin/plugin.xml | 275 +++++++++++++++
.../plugin/injector/PluginInjectorTest.java | 6 +
.../integrations/plugins/mock/MockPlugin.java | 17 +-
.../PluginRegistrationServiceTest.java | 102 +++++-
.../plugins/service/PluginServiceTest.java | 58 ++--
22 files changed, 1165 insertions(+), 268 deletions(-)
delete mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
delete mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
delete mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/CreateOrUpdateOutcome.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java
delete mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
delete mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
create mode 100644 src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
create mode 100644 src/main/resources/petriNets/engine-processes/plugin/method.xml
create mode 100644 src/main/resources/petriNets/engine-processes/plugin/plugin.xml
create mode 100644 src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 643bb5144dc..39e35bdb3b5 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -3,47 +3,68 @@ package com.netgrif.application.engine.integration.plugin.injector
import com.netgrif.application.engine.configuration.ApplicationContextProvider
import com.netgrif.application.engine.integration.plugin.injector.meta.EntryPointMeta
import com.netgrif.application.engine.integration.plugin.injector.meta.PluginMeta
-import com.netgrif.application.engine.integration.plugins.domain.Plugin
import com.netgrif.application.engine.integration.plugins.service.PluginService
+import com.netgrif.application.engine.integration.plugins.utils.PluginUtils
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
+import com.netgrif.application.engine.workflow.domain.Case
+import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+@Service
class PluginInjector {
+ @Autowired
+ protected IWorkflowService workflowService
+
+ @Autowired
+ protected PluginUtils utils
+
/**
* Injects provided plugin into meta class of {@link ActionDelegate}
*
- * @param plugin model of plugin to be injected
+ * @param plugin case of plugin to be injected
* */
- static void inject(Plugin plugin) {
+ void inject(Case plugin) {
updateMetaClasses(plugin, false)
}
/**
* Removes provided plugin from the meta class of {@link ActionDelegate}.
*
- * @param plugin model of plugin to be uninjected
+ * @param plugin case of plugin to be uninjected
* */
- static void uninject(Plugin plugin) {
+ void uninject(Case plugin) {
updateMetaClasses(plugin, true)
}
- protected static void updateMetaClasses(Plugin plugin, boolean isRemoval) {
+ protected void updateMetaClasses(Case pluginCase, boolean isRemoval) {
MetaClass actionDelegateMeta = ActionDelegate.metaClass
MetaClass pluginMetaClass = PluginMeta.metaClass
- plugin.entryPoints.each {ep ->
+
+ List entryPointCases = utils.getPluginEntryPoints(pluginCase)
+ String pluginIdentifier = PluginUtils.getPluginIdentifier(pluginCase)
+ String pluginName = PluginUtils.getPluginName(pluginCase)
+
+ entryPointCases.each { epCase ->
MetaClass entryPointMetaClass = EntryPointMeta.metaClass
- ep.value.methods.each { m ->
+ List methodCases = utils.getEntryPointMethods(epCase)
+ String epName = PluginUtils.getEntryPointName(epCase)
+
+ methodCases.each { methodCase ->
+ String methodName = PluginUtils.getMethodName(methodCase)
+
if (isRemoval) {
- entryPointMetaClass[m.value.name] = null
+ entryPointMetaClass[methodName] = null
} else {
- entryPointMetaClass[m.value.name] << { Serializable... args ->
+ entryPointMetaClass[methodName] << { Serializable... args ->
PluginService pluginService = ApplicationContextProvider.getBean("pluginService") as PluginService
- return pluginService.call(plugin.identifier, ep.value.name, m.value.name, args)
+ return pluginService.call(pluginIdentifier, epName, methodName, args)
}
}
}
- pluginMetaClass[ep.value.name] = isRemoval ? null : new EntryPointMeta()
+ pluginMetaClass[epName] = isRemoval ? null : new EntryPointMeta()
}
- actionDelegateMeta[plugin.name] = isRemoval ? null : new PluginMeta()
+ actionDelegateMeta[pluginName] = isRemoval ? null : new PluginMeta()
}
}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy b/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy
index 0a92f223747..29f65708009 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/ImportHelper.groovy
@@ -239,12 +239,19 @@ class ImportHelper {
superCreator.setAllToSuperUser();
}
+ @Deprecated
static ObjectNode populateDataset(Map> data) {
ObjectMapper mapper = new ObjectMapper()
String json = mapper.writeValueAsString(data)
return mapper.readTree(json) as ObjectNode
}
+ static ObjectNode populateDatasetAsObjects(Map> data) {
+ ObjectMapper mapper = new ObjectMapper()
+ String json = mapper.writeValueAsString(data)
+ return mapper.readTree(json) as ObjectNode
+ }
+
static String getCaseColor() {
return "color-fg-amber-500"
}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy b/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
index a4acf41330f..e80b63e4a2f 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
@@ -1,8 +1,8 @@
package com.netgrif.application.engine.startup
import com.netgrif.application.engine.integration.plugin.injector.PluginInjector
-import com.netgrif.application.engine.integration.plugins.domain.Plugin
import com.netgrif.application.engine.integration.plugins.service.IPluginService
+import com.netgrif.application.engine.workflow.domain.Case
import groovy.util.logging.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@@ -11,17 +11,40 @@ import org.springframework.stereotype.Component
@Component
class PluginRunner extends AbstractOrderedCommandLineRunner {
+ @Autowired
+ private ImportHelper helper
+
@Autowired
private IPluginService pluginService
+ @Autowired
+ private PluginInjector pluginInjector
+
+ private static final String PLUGIN_FILE_NAME = "engine-processes/plugin/plugin.xml"
+ private static final String PLUGIN_PETRI_NET_IDENTIFIER = "plugin"
+
+ private static final String ENTRY_POINT_FILE_NAME = "engine-processes/plugin/entry_point.xml"
+ private static final String ENTRY_POINT_NET_IDENTIFIER = "entry_point"
+
+ private static final String METHOD_FILE_NAME = "engine-processes/plugin/method.xml"
+ private static final String METHOD_NET_IDENTIFIER = "method"
+
@Override
void run(String... args) throws Exception {
- List plugins = pluginService.findAll()
+ importPluginNets()
+
+ List plugins = pluginService.findAll()
plugins.size()
log.info("Re-injecting ${plugins.size()} plugins from database into memory.")
plugins.each { plugin ->
- PluginInjector.inject(plugin)
+ pluginInjector.inject(plugin)
}
}
+
+ private void importPluginNets() {
+ helper.upsertNet(PLUGIN_FILE_NAME, PLUGIN_PETRI_NET_IDENTIFIER)
+ helper.upsertNet(ENTRY_POINT_FILE_NAME, ENTRY_POINT_NET_IDENTIFIER)
+ helper.upsertNet(METHOD_FILE_NAME, METHOD_NET_IDENTIFIER)
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
deleted file mode 100644
index 5498e8ceaf5..00000000000
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/EntryPoint.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.netgrif.application.engine.integration.plugins.domain;
-
-import lombok.Data;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-@Data
-public class EntryPoint {
- private String name;
- private Map methods;
-
- public EntryPoint() {
- this.methods = new LinkedHashMap<>();
- }
-}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
deleted file mode 100644
index 3b700b3200e..00000000000
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Method.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.netgrif.application.engine.integration.plugins.domain;
-
-import com.netgrif.application.engine.integration.plugins.utils.ClassToStringConverter;
-import lombok.Data;
-import org.springframework.data.convert.ValueConverter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Data
-public class Method {
- private String name;
- @ValueConverter(ClassToStringConverter.class)
- private List> args;
-
- public Method() {
- this.args = new ArrayList<>();
- }
-}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java b/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
deleted file mode 100644
index 678270fdaaf..00000000000
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/domain/Plugin.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.netgrif.application.engine.integration.plugins.domain;
-
-import lombok.Data;
-import org.bson.types.ObjectId;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.index.Indexed;
-import org.springframework.data.mongodb.core.mapping.Document;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-@Data
-@Document
-public class Plugin {
- @Id
- private ObjectId id;
- @Indexed
- private String identifier;
- private String name;
- private String url;
- private long port;
- private boolean active;
- private Map entryPoints;
-
- public Plugin() {
- this.entryPoints = new LinkedHashMap<>();
- }
-}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/CreateOrUpdateOutcome.java b/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/CreateOrUpdateOutcome.java
new file mode 100644
index 00000000000..52d7ec86412
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/CreateOrUpdateOutcome.java
@@ -0,0 +1,38 @@
+package com.netgrif.application.engine.integration.plugins.outcomes;
+
+import lombok.Getter;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Getter
+public class CreateOrUpdateOutcome {
+ private final Set createdCaseIds;
+ private final Set subjectCaseIds;
+
+ public CreateOrUpdateOutcome() {
+ createdCaseIds = new HashSet<>();
+ subjectCaseIds = new HashSet<>();
+ }
+
+ public boolean addCreatedAndSubjectCaseId(String caseId) {
+ if (caseId == null) {
+ return false;
+ } else {
+ boolean isCreatedChanged = createdCaseIds.add(caseId);
+ return subjectCaseIds.add(caseId) || isCreatedChanged; // do not change expression order
+ }
+ }
+
+ public boolean addSubjectCaseId(String caseId) {
+ if (caseId == null) {
+ return false;
+ } else {
+ return subjectCaseIds.add(caseId);
+ }
+ }
+
+ public boolean addAllCreatedCaseId(Set caseIds) {
+ return createdCaseIds.addAll(caseIds);
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java b/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java
new file mode 100644
index 00000000000..82532f0d1cc
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java
@@ -0,0 +1,12 @@
+package com.netgrif.application.engine.integration.plugins.outcomes;
+
+import com.netgrif.application.engine.workflow.domain.Case;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public class GetOrCreateOutcome {
+ private final Case subjectCase;
+ private final boolean isNew;
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java b/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
deleted file mode 100644
index 2e7e9cb2308..00000000000
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/repository/PluginRepository.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.netgrif.application.engine.integration.plugins.repository;
-
-import com.netgrif.application.engine.integration.plugins.domain.Plugin;
-import org.bson.types.ObjectId;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.data.mongodb.repository.MongoRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-@ConditionalOnProperty(
- value = "nae.plugin.enabled",
- havingValue = "true",
- matchIfMissing = true
-)
-public interface PluginRepository extends MongoRepository {
- Plugin findByIdentifier(String identifier);
-}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
index 0b52a2fa415..b5b6ab951b3 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -1,12 +1,14 @@
package com.netgrif.application.engine.integration.plugins.service;
-import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.workflow.domain.Case;
+import com.netgrif.pluginlibrary.core.RegistrationRequest;
import java.io.Serializable;
import java.util.List;
+import java.util.Optional;
public interface IPluginService {
- String registerOrActivate(Plugin plugin);
+ String registerOrActivate(RegistrationRequest request);
String unregister(String identifier) throws IllegalArgumentException;
@@ -14,5 +16,7 @@ public interface IPluginService {
String deactivate(String identifier) throws IllegalArgumentException;
- List findAll();
+ List findAll();
+
+ Optional findByIdentifier(String identifier);
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index a99fec51c4e..d46a09273a3 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -1,20 +1,11 @@
package com.netgrif.application.engine.integration.plugins.service;
-import com.netgrif.application.engine.integration.plugins.domain.EntryPoint;
-import com.netgrif.application.engine.integration.plugins.domain.Method;
-import com.netgrif.application.engine.integration.plugins.domain.Plugin;
import com.netgrif.pluginlibrary.core.*;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
-import org.springframework.util.SerializationUtils;
-
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
/**
* Implementation of {@link com.netgrif.pluginlibrary.core.RegistrationServiceGrpc.RegistrationServiceImplBase}. This
@@ -31,7 +22,6 @@
public final class PluginRegistrationService extends RegistrationServiceGrpc.RegistrationServiceImplBase {
private final IPluginService pluginService;
-
/**
* Registers or activate plugin provided by request.
*
@@ -40,11 +30,12 @@ public final class PluginRegistrationService extends RegistrationServiceGrpc.Reg
@Override
public void register(RegistrationRequest request, StreamObserver responseObserver) {
try {
- String responseMsg = pluginService.registerOrActivate(convertRequestToModel(request));
+ String responseMsg = pluginService.registerOrActivate(request);
RegistrationResponse response = RegistrationResponse.newBuilder().setMessage(responseMsg).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
- } catch (IllegalArgumentException e) {
+ } catch (RuntimeException e) {
+ log.error("Something went wrong when registering or activating plugin with identifier [{}]", request.getIdentifier(), e);
responseObserver.onError(e);
}
}
@@ -61,7 +52,8 @@ public void unregister(UnregistrationRequest request, StreamObserver convertEntryPointsFromRequest(List entryPoints) {
- return entryPoints.stream().map(epReq -> {
- EntryPoint epModel = new EntryPoint();
- epModel.setName(epReq.getName());
- epModel.setMethods(epReq.getMethodsList().stream().map(methodReq -> {
- Method methodModel = new Method();
- methodModel.setName(methodReq.getName());
- methodModel.setArgs(methodReq.getArgsList().stream()
- .map(arg -> (Class>) SerializationUtils.deserialize(arg.toByteArray()))
- .collect(Collectors.toList())
- );
- return methodModel;
- }).collect(Collectors.toMap(Method::getName, Function.identity())));
- return epModel;
- }).collect(Collectors.toMap(EntryPoint::getName, Function.identity()));
}
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index c36e5c8ee3b..4448d860715 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -1,10 +1,25 @@
package com.netgrif.application.engine.integration.plugins.service;
import com.google.protobuf.ByteString;
+import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.auth.domain.LoggedUser;
+import com.netgrif.application.engine.auth.service.interfaces.IUserService;
+import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
+import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
import com.netgrif.application.engine.integration.plugin.injector.PluginInjector;
-import com.netgrif.application.engine.integration.plugins.domain.Plugin;
+import com.netgrif.application.engine.integration.plugins.outcomes.CreateOrUpdateOutcome;
+import com.netgrif.application.engine.integration.plugins.outcomes.GetOrCreateOutcome;
import com.netgrif.application.engine.integration.plugins.properties.PluginConfigProperties;
-import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import com.netgrif.application.engine.integration.plugins.utils.PluginConstants;
+import com.netgrif.application.engine.integration.plugins.utils.PluginUtils;
+import com.netgrif.application.engine.petrinet.domain.dataset.FieldType;
+import com.netgrif.application.engine.petrinet.domain.throwable.TransitionNotExecutableException;
+import com.netgrif.application.engine.startup.ImportHelper;
+import com.netgrif.application.engine.workflow.domain.Case;
+import com.netgrif.application.engine.workflow.domain.Task;
+import com.netgrif.application.engine.workflow.service.interfaces.IDataService;
+import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
+import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import com.netgrif.pluginlibrary.core.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
@@ -13,22 +28,25 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SerializationUtils;
-import org.bson.types.ObjectId;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
+import static com.netgrif.application.engine.integration.plugins.utils.PluginConstants.*;
+import static com.netgrif.application.engine.integration.plugins.utils.PluginUtils.*;
+
/**
* Base service, that manages gRPC server on application startup, registers, activates and deactivates plugins, sends
* plugin execution requests to desired plugin.
- * */
+ */
@Slf4j
@Service
@RequiredArgsConstructor
@@ -38,8 +56,14 @@
matchIfMissing = true
)
public class PluginService implements IPluginService {
- private final PluginRepository pluginRepository;
private final PluginConfigProperties properties;
+ private final IElasticCaseService elasticCaseService;
+ private final IWorkflowService workflowService;
+ private final IUserService userService;
+ private final IDataService dataService;
+ private final ITaskService taskService;
+ private final PluginInjector pluginInjector;
+ private final PluginUtils utils;
private Server server;
private static final String LOG_PREFIX = "[gRPC Server] -";
@@ -62,31 +86,46 @@ public void stopServer() {
/**
* Registers provided plugin into repository. If the plugin already exists, it's activated.
- * @param plugin - plugin to be registered, or if already registered, then activated
*
+ * @param request - plugin to be registered or if already registered, then activated
* @return activation or registration string message is returned
- * */
+ */
@Override
- public String registerOrActivate(Plugin plugin) {
- Plugin existingPlugin = pluginRepository.findByIdentifier(plugin.getIdentifier());
- return existingPlugin == null ? register(plugin) : activate(plugin, existingPlugin.getId());
+ public String registerOrActivate(RegistrationRequest request) {
+ Optional existingPluginOpt = findByIdentifier(request.getIdentifier());
+ try {
+ if (existingPluginOpt.isPresent()) {
+ return activate(existingPluginOpt.get(), request);
+ } else {
+ return register(request);
+ }
+ } catch (TransitionNotExecutableException e) {
+ throw new RuntimeException(e);
+ }
}
/**
- * Unregisters provided plugin from memory and database
- * @param identifier - identifier of the plugin to be unregistered
+ * Unregisters plugin by identifier from memory and database
*
+ * @param identifier - identifier of the plugin to be unregistered
* @return unregistration string message is returned
- * */
+ */
@Override
public String unregister(String identifier) {
- Plugin plugin = pluginRepository.findByIdentifier(identifier);
- if (plugin == null) {
+ Optional existingPluginOpt = findByIdentifier(identifier);
+ if (existingPluginOpt.isEmpty()) {
throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be found");
}
- PluginInjector.uninject(plugin);
- pluginRepository.delete(plugin);
+ pluginInjector.uninject(existingPluginOpt.get());
+
+ for (Case entryPointCase : utils.getPluginEntryPoints(existingPluginOpt.get())) {
+ for (Case methodCase : utils.getEntryPointMethods(entryPointCase)) {
+ workflowService.deleteCase(methodCase);
+ }
+ workflowService.deleteCase(entryPointCase);
+ }
+ workflowService.deleteCase(existingPluginOpt.get());
String responseMsg = "Plugin with identifier \"" + identifier + "\" was unregistered.";
log.info(responseMsg);
@@ -94,25 +133,25 @@ public String unregister(String identifier) {
}
/**
- * Calls method with arguments of a specified entry point
+ * Calls method with arguments of a specified entry point. Plugin must exist and be activated.
*
- * @param pluginId plugin identifier, that contains the method to be executed
+ * @param pluginId plugin identifier, that contains the method to be executed
* @param entryPoint name of entry point in plugin, that contains the method to be executed
- * @param method name of method to be executed
- * @param args arguments to send to plugin method. All args should be the exact type of method input arguments type (not superclass, or subclass)
- *
+ * @param method name of method to be executed
+ * @param args arguments to send to plugin method. All args should be the exact type of method input arguments type (not superclass, or subclass)
* @return the returned object of the executed plugin method
- * */
+ */
@Override
public Object call(String pluginId, String entryPoint, String method, Serializable... args) throws IllegalArgumentException {
- Plugin plugin = pluginRepository.findByIdentifier(pluginId);
- if (plugin == null) {
+ Optional pluginCaseOpt = findByIdentifier(pluginId);
+ if (pluginCaseOpt.isEmpty()) {
throw new IllegalArgumentException("Plugin with identifier \"" + pluginId + "\" cannot be found");
}
- if (!plugin.isActive()) {
- throw new IllegalArgumentException("Plugin with name \"" + plugin.getName() + "\" is deactivated");
+ Case pluginCase = pluginCaseOpt.get();
+ if (!isPluginActive(pluginCase)) {
+ throw new IllegalArgumentException("Plugin with name \"" + getPluginName(pluginCase) + "\" is deactivated");
}
- ManagedChannel channel = ManagedChannelBuilder.forAddress(plugin.getUrl(), (int) plugin.getPort())
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(getPluginUrl(pluginCase), getPluginPort(pluginCase))
.usePlaintext()
.build();
List argBytes = Arrays.stream(args).map(arg -> ByteString.copyFrom(SerializationUtils.serialize(arg))).collect(Collectors.toList());
@@ -130,16 +169,23 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
* Deactivates the plugin of the provided identifier
*
* @param identifier Identifier of the plugin, that should be deactivated.
- * */
+ */
@Override
public String deactivate(String identifier) throws IllegalArgumentException {
- Plugin existingPlugin = pluginRepository.findByIdentifier(identifier);
- if (existingPlugin == null) {
- throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be deactivated. Plugin with this identifier does not exist.");
+ Optional pluginOpt = findByIdentifier(identifier);
+ if (pluginOpt.isEmpty()) {
+ throw new IllegalArgumentException("Plugin with identifier \"" + identifier + "\" cannot be found");
+ }
+ if (isPluginActive(pluginOpt.get())) {
+ String taskId = findTaskIdInCase(pluginOpt.get(), PLUGIN_DEACTIVATE_TRANS_ID);
+ IUser user = userService.getLoggedOrSystem();
+ try {
+ Task deactivateTask = utils.safelyAssignTask(taskId).getTask();
+ taskService.finishTask(deactivateTask, user);
+ } catch (TransitionNotExecutableException e) {
+ throw new RuntimeException(e);
+ }
}
- existingPlugin.setActive(false);
- pluginRepository.save(existingPlugin);
-
String responseMsg = "Plugin with identifier \"" + identifier + "\" was deactivated.";
log.info(responseMsg);
return responseMsg;
@@ -148,29 +194,209 @@ public String deactivate(String identifier) throws IllegalArgumentException {
/**
* Finds all plugins in the database
*
- * @return list of plugins
- * */
- public List findAll() {
- return pluginRepository.findAll();
+ * @return list of plugin cases
+ */
+ @Override
+ public List findAll() {
+ String query = String.format("processIdentifier:%s", PLUGIN_PROCESS_IDENTIFIER);
+ List requestAsList = List.of(CaseSearchRequest.builder().query(query).build());
+ LoggedUser loggedUser = userService.getLoggedOrSystem().transformToLoggedUser();
+ int count = (int) elasticCaseService.count(requestAsList, loggedUser, Locale.getDefault(), false);
+ if (count > 0) {
+ return elasticCaseService.search(requestAsList, loggedUser, PageRequest.ofSize(count), Locale.getDefault(), false).getContent();
+ } else {
+ return new ArrayList<>();
+ }
}
- private String register(Plugin plugin) {
- return saveAndInject(plugin, "registered");
+ /**
+ * Finds plugin case by provided identifier
+ *
+ * @param identifier identifier of the plugin
+ * @return optional case of the plugin
+ */
+ @Override
+ public Optional findByIdentifier(String identifier) {
+ String query = String.format("processIdentifier:%s AND dataSet.%s.textValue:\"%s\"", PLUGIN_PROCESS_IDENTIFIER,
+ PLUGIN_IDENTIFIER_FIELD_ID, identifier);
+ List requestAsList = List.of(CaseSearchRequest.builder().query(query).build());
+ LoggedUser loggedUser = userService.getLoggedOrSystem().transformToLoggedUser();
+ Page result = elasticCaseService.search(requestAsList, loggedUser, PageRequest.ofSize(1), Locale.getDefault(), false);
+
+ return result.hasContent() ? Optional.of(result.getContent().get(0)) : Optional.empty();
+ }
+
+ private String register(RegistrationRequest request) throws TransitionNotExecutableException {
+ Case pluginCase = createOrUpdatePluginCase(request, Optional.empty());
+ pluginCase = doActivation(pluginCase);
+ return inject(pluginCase, "registered");
+ }
+
+ private String activate(Case pluginCase, RegistrationRequest request) throws TransitionNotExecutableException {
+ pluginCase = createOrUpdatePluginCase(request, Optional.of(pluginCase));
+ if (!isPluginActive(pluginCase)) {
+ pluginCase = doActivation(pluginCase);
+ }
+ return inject(pluginCase, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
}
- private String activate(Plugin plugin, ObjectId existingPluginId) {
- plugin.setActive(true);
- plugin.setId(existingPluginId);
- return saveAndInject(plugin, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
+ private Case doActivation(Case pluginCase) throws TransitionNotExecutableException {
+ String taskId = findTaskIdInCase(pluginCase, PLUGIN_ACTIVATE_TRANS_ID);
+ IUser user = userService.getLoggedOrSystem();
+ Task activateTask = utils.safelyAssignTask(taskId).getTask();
+ return taskService.finishTask(activateTask, user).getCase();
}
- private String saveAndInject(Plugin plugin, String state) {
- pluginRepository.save(plugin);
- PluginInjector.inject(plugin);
+ private String inject(Case plugin, String state) {
+ pluginInjector.inject(plugin);
- String responseMsg = "Plugin with identifier \"" + plugin.getIdentifier() + "\" was " + state + ".";
+ String responseMsg = String.format("Plugin with identifier \"%s\" was %s.", getPluginIdentifier(plugin), state);
log.info(responseMsg);
return responseMsg;
}
+ private Case createOrUpdatePluginCase(RegistrationRequest request, Optional pluginCaseOpt) {
+ Set createdCaseIds = new HashSet<>();
+ LoggedUser loggedUser = userService.getLoggedOrSystem().transformToLoggedUser();
+
+ try {
+ Case pluginCase = pluginCaseOpt.orElseGet(() -> {
+ Case newPluginCase = workflowService.createCaseByIdentifier(PluginConstants.PLUGIN_PROCESS_IDENTIFIER, request.getName(),
+ "", loggedUser).getCase();
+ createdCaseIds.add(newPluginCase.getStringId());
+ return newPluginCase;
+ });
+
+ CreateOrUpdateOutcome epOutcome = createOrUpdateEntryPointCases(request.getEntryPointsList(), loggedUser,
+ utils.getPluginEntryPoints(pluginCase));
+
+ createdCaseIds.addAll(epOutcome.getCreatedCaseIds());
+ Set epToBeRemovedIds = new HashSet<>(getPluginEntryPointIds(pluginCase));
+ epToBeRemovedIds.removeAll(epOutcome.getSubjectCaseIds());
+
+ Map> dataToSet = new HashMap<>();
+ dataToSet.put(PLUGIN_IDENTIFIER_FIELD_ID, Map.of("value", request.getIdentifier(), "type",
+ FieldType.TEXT.getName()));
+ dataToSet.put(PLUGIN_NAME_FIELD_ID, Map.of("value", request.getName(), "type", FieldType.TEXT.getName()));
+ dataToSet.put(PLUGIN_URL_FIELD_ID, Map.of("value", request.getUrl(), "type", FieldType.TEXT.getName()));
+ dataToSet.put(PLUGIN_PORT_FIELD_ID, Map.of("value", String.valueOf(request.getPort()), "type",
+ FieldType.NUMBER.getName()));
+ dataToSet.put(PLUGIN_ENTRY_POINTS_FIELD_ID, Map.of("value", epOutcome.getSubjectCaseIds(), "type",
+ FieldType.CASE_REF.getName()));
+
+ String taskId = findTaskIdInCase(pluginCase, PLUGIN_ACTIVATE_TRANS_ID);
+ dataService.setData(taskId, ImportHelper.populateDatasetAsObjects(dataToSet));
+
+ removeCases(epToBeRemovedIds);
+
+ return pluginCase;
+ } catch (Exception rethrow) {
+ removeCases(createdCaseIds);
+ throw rethrow;
+ }
+ }
+
+ private CreateOrUpdateOutcome createOrUpdateEntryPointCases(List entryPoints, LoggedUser loggedUser, List existingEpCases) {
+ CreateOrUpdateOutcome outcome = new CreateOrUpdateOutcome();
+
+ try {
+ for (EntryPoint entryPoint : entryPoints) {
+ GetOrCreateOutcome epOutcome = getOrCreateEntryPointCase(entryPoint, loggedUser, existingEpCases);
+ Case entryPointCase = epOutcome.getSubjectCase();
+ if (epOutcome.isNew()) {
+ outcome.addCreatedAndSubjectCaseId(entryPointCase.getStringId());
+ } else {
+ outcome.addSubjectCaseId(entryPointCase.getStringId());
+ }
+
+ CreateOrUpdateOutcome methodOutcome = createOrUpdateMethodCases(entryPoint, loggedUser,
+ utils.getEntryPointMethods(entryPointCase));
+ outcome.addAllCreatedCaseId(methodOutcome.getCreatedCaseIds());
+ Set epToBeRemovedIds = new HashSet<>(getEntryPointMethodIds(entryPointCase));
+ epToBeRemovedIds.removeAll(methodOutcome.getSubjectCaseIds());
+
+ Map> dataToSet = new HashMap<>();
+ dataToSet.put(ENTRY_POINT_NAME_FIELD_ID, Map.of("value", entryPoint.getName(), "type",
+ FieldType.TEXT.getName()));
+ dataToSet.put(ENTRY_POINT_METHODS_FIELD_ID, Map.of("value", methodOutcome.getSubjectCaseIds(),
+ "type", FieldType.CASE_REF.getName()));
+
+ String taskId = findTaskIdInCase(entryPointCase, ENTRY_POINT_DETAIL_TRANS_ID);
+ dataService.setData(taskId, ImportHelper.populateDatasetAsObjects(dataToSet));
+
+ removeCases(epToBeRemovedIds);
+ }
+
+ return outcome;
+ } catch (Exception rethrow) {
+ removeCases(outcome.getCreatedCaseIds());
+ throw rethrow;
+ }
+ }
+
+ private GetOrCreateOutcome getOrCreateEntryPointCase(EntryPoint ep, LoggedUser loggedUser, List existingEpCases) {
+ Optional epCaseOpt = existingEpCases.stream()
+ .filter((aCase) -> getEntryPointName(aCase).equals(ep.getName()))
+ .findFirst();
+ Case epCase = epCaseOpt.orElseGet(() -> workflowService.createCaseByIdentifier(ENTRY_POINT_PROCESS_IDENTIFIER,
+ ep.getName(), "", loggedUser).getCase());
+ return new GetOrCreateOutcome(epCase, epCaseOpt.isEmpty());
+ }
+
+ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, LoggedUser loggedUser,
+ List existingMethodCases) {
+ CreateOrUpdateOutcome outcome = new CreateOrUpdateOutcome();
+
+ try {
+ for (com.netgrif.pluginlibrary.core.Method method : entryPoint.getMethodsList()) {
+ GetOrCreateOutcome methodOutcome = getOrCreateMethodCase(method, loggedUser, existingMethodCases);
+
+ Case methodCase = methodOutcome.getSubjectCase();
+ if (methodOutcome.isNew()) {
+ outcome.addCreatedAndSubjectCaseId(methodCase.getStringId());
+ } else {
+ outcome.addSubjectCaseId(methodCase.getStringId());
+ }
+
+ Map> dataToSet = new HashMap<>();
+ dataToSet.put(METHOD_NAME_FIELD_ID, Map.of("value", method.getName(),
+ "type", FieldType.TEXT.getName()));
+ List argTypesAsString = method.getArgsList().stream()
+ .map(arg -> {
+ Class> clazz = (Class>) org.springframework.util.SerializationUtils.deserialize(arg.toByteArray());
+ assert clazz != null;
+ return clazz.getName();
+ })
+ .collect(Collectors.toList());
+ dataToSet.put(METHOD_ARGUMENTS_FIELD_ID, Map.of("value", argTypesAsString, "type",
+ FieldType.STRING_COLLECTION.getName()));
+
+ String taskId = findTaskIdInCase(methodCase, METHOD_DETAIL_TRANS_ID);
+ dataService.setData(taskId, ImportHelper.populateDatasetAsObjects(dataToSet));
+ }
+
+ return outcome;
+ } catch (Exception rethrow) {
+ removeCases(outcome.getCreatedCaseIds());
+ throw rethrow;
+ }
+ }
+
+ private GetOrCreateOutcome getOrCreateMethodCase(Method method, LoggedUser loggedUser, List existingMethodCases) {
+ Optional methodCaseOpt = existingMethodCases.stream()
+ .filter((aCase) -> getMethodName(aCase).equals(method.getName()))
+ .findFirst();
+ Case methodCase = methodCaseOpt.orElseGet(() -> workflowService.createCaseByIdentifier(METHOD_PROCESS_IDENTIFIER,
+ method.getName(), "", loggedUser).getCase());
+ return new GetOrCreateOutcome(methodCase, methodCaseOpt.isEmpty());
+ }
+
+ private void removeCases(Set createdCaseIds) {
+ for (String caseId : createdCaseIds) {
+ Case caseToRemove = workflowService.findOne(caseId);
+ if (caseToRemove != null) {
+ workflowService.deleteCase(caseId);
+ }
+ }
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
deleted file mode 100644
index e86df265790..00000000000
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/ClassToStringConverter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.netgrif.application.engine.integration.plugins.utils;
-
-import com.mongodb.lang.NonNull;
-import org.springframework.data.convert.PropertyValueConverter;
-import org.springframework.data.mongodb.core.convert.MongoConversionContext;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class ClassToStringConverter implements PropertyValueConverter>, List, MongoConversionContext> {
-
- /**
- * Maps provided class names into list of {@link Class} objects
- * */
- @Override
- public List> read(List classNames, @NonNull MongoConversionContext context) {
- return classNames.stream().map(name -> {
- try {
- return Class.forName(name);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- }).collect(Collectors.toList());
- }
-
- /**
- * Maps provided objects of {@link Class} into list of class names
- * */
- @Override
- public List write(List> value, @NonNull MongoConversionContext context) {
- return value.stream().map(Class::getName).collect(Collectors.toList());
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
new file mode 100644
index 00000000000..b9d198d3b2d
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
@@ -0,0 +1,24 @@
+package com.netgrif.application.engine.integration.plugins.utils;
+
+public class PluginConstants {
+
+ public static final String PLUGIN_PROCESS_IDENTIFIER = "plugin";
+ public static final String ENTRY_POINT_PROCESS_IDENTIFIER = "entry_point";
+ public static final String METHOD_PROCESS_IDENTIFIER = "method";
+
+ public static final String PLUGIN_IDENTIFIER_FIELD_ID = "identifier";
+ public static final String PLUGIN_NAME_FIELD_ID = "name";
+ public static final String PLUGIN_URL_FIELD_ID = "url";
+ public static final String PLUGIN_PORT_FIELD_ID = "port";
+ public static final String PLUGIN_ACTIVE_FIELD_ID = "active";
+ public static final String PLUGIN_ENTRY_POINTS_FIELD_ID = "entry_point_ids";
+ public static final String ENTRY_POINT_METHODS_FIELD_ID = "method_ids";
+ public static final String ENTRY_POINT_NAME_FIELD_ID = "name";
+ public static final String METHOD_NAME_FIELD_ID = "name";
+ public static final String METHOD_ARGUMENTS_FIELD_ID = "arguments";
+
+ public static final String PLUGIN_ACTIVATE_TRANS_ID = "activate";
+ public static final String PLUGIN_DEACTIVATE_TRANS_ID = "deactivate";
+ public static final String ENTRY_POINT_DETAIL_TRANS_ID = "detail";
+ public static final String METHOD_DETAIL_TRANS_ID = "detail";
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
new file mode 100644
index 00000000000..031750742eb
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
@@ -0,0 +1,168 @@
+package com.netgrif.application.engine.integration.plugins.utils;
+
+import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.auth.service.interfaces.IUserService;
+import com.netgrif.application.engine.petrinet.domain.throwable.TransitionNotExecutableException;
+import com.netgrif.application.engine.workflow.domain.Case;
+import com.netgrif.application.engine.workflow.domain.Task;
+import com.netgrif.application.engine.workflow.domain.TaskPair;
+import com.netgrif.application.engine.workflow.domain.eventoutcomes.taskoutcomes.AssignTaskEventOutcome;
+import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
+import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+public class PluginUtils {
+ private final IWorkflowService workflowService;
+ private final ITaskService taskService;
+ private final IUserService userService;
+
+ /**
+ * Finds task id in provided case by transition id
+ *
+ * @param aCase Case instance where to find task id
+ * @param transId transition id of the task id
+ *
+ * @return optional task id
+ * */
+ public static String findTaskIdInCase(Case aCase, String transId) {
+ Optional taskPairOpt = aCase.getTasks().stream()
+ .filter((taskPair -> taskPair.getTransition().equals(transId)))
+ .findFirst();
+ if (taskPairOpt.isEmpty()) {
+ throw new IllegalStateException("Case with id [" + aCase.getStringId() + "] should have at least 1 existing task.");
+ }
+ return taskPairOpt.get().getTask();
+ }
+
+ /**
+ * Checks if the plugin is active.
+ *
+ * @param pluginCase case instance to be checked
+ *
+ * @return true if the plugin is active
+ * */
+ public static boolean isPluginActive(Case pluginCase) {
+ return (Boolean) pluginCase.getFieldValue(PluginConstants.PLUGIN_ACTIVE_FIELD_ID);
+ }
+
+ /**
+ * Finds plugin name from the dataSet of the provided plugin case
+ * */
+ public static String getPluginName(Case pluginCase) {
+ return (String) pluginCase.getFieldValue(PluginConstants.PLUGIN_NAME_FIELD_ID);
+ }
+
+ /**
+ * Finds plugin url from the dataSet of the provided plugin case
+ * */
+ public static String getPluginUrl(Case pluginCase) {
+ return (String) pluginCase.getFieldValue(PluginConstants.PLUGIN_URL_FIELD_ID);
+ }
+
+ /**
+ * Finds plugin port from the dataSet of the provided plugin case
+ * */
+ public static int getPluginPort(Case pluginCase) {
+ Double result = (Double) pluginCase.getFieldValue(PluginConstants.PLUGIN_PORT_FIELD_ID);
+ return result.intValue();
+ }
+
+ /**
+ * Finds plugin identifier from the dataSet of the provided plugin case
+ * */
+ public static String getPluginIdentifier(Case pluginCase) {
+ return (String) pluginCase.getFieldValue(PluginConstants.PLUGIN_IDENTIFIER_FIELD_ID);
+ }
+
+ /**
+ * Gets plugin entry point cases
+ *
+ * @param pluginCase case instance, which is associated with the entry points
+ *
+ * @return list of entry point cases
+ * */
+ @SuppressWarnings("unchecked")
+ public List getPluginEntryPoints(Case pluginCase) {
+ List caseIds = (List) pluginCase.getFieldValue(PluginConstants.PLUGIN_ENTRY_POINTS_FIELD_ID);
+ return caseIds == null || caseIds.isEmpty() ? new ArrayList<>() : workflowService.findAllById(caseIds);
+ }
+
+ /**
+ * Finds entry point case ids from the dataSet of the provided plugin case
+ * */
+ @SuppressWarnings("unchecked")
+ public static List getPluginEntryPointIds(Case pluginCase) {
+ return (List) pluginCase.getFieldValue(PluginConstants.PLUGIN_ENTRY_POINTS_FIELD_ID);
+ }
+
+ /**
+ * Gets plugin entry point cases
+ *
+ * @param entryPointCase case instance, which is associated with the methods
+ *
+ * @return list of method cases
+ * */
+ @SuppressWarnings("unchecked")
+ public List getEntryPointMethods(Case entryPointCase) {
+ List caseIds = (List) entryPointCase.getFieldValue(PluginConstants.ENTRY_POINT_METHODS_FIELD_ID);
+ return caseIds == null || caseIds.isEmpty() ? new ArrayList<>() : workflowService.findAllById(caseIds);
+ }
+
+ /**
+ * Finds method case ids from the dataSet of the provided entry point case
+ * */
+ @SuppressWarnings("unchecked")
+ public static List getEntryPointMethodIds(Case entryPointCase) {
+ return (List) entryPointCase.getFieldValue(PluginConstants.ENTRY_POINT_METHODS_FIELD_ID);
+ }
+
+ /**
+ * Finds entry point name from the dataSet of the provided entry point case
+ * */
+ public static String getEntryPointName(Case entryPointCase) {
+ return (String) entryPointCase.getFieldValue(PluginConstants.ENTRY_POINT_NAME_FIELD_ID);
+ }
+
+ /**
+ * Finds method name from the dataSet of the provided method case
+ * */
+ public static String getMethodName(Case methodCase) {
+ return (String) methodCase.getFieldValue(PluginConstants.METHOD_NAME_FIELD_ID);
+ }
+
+ /**
+ * Finds method arguments from the dataSet of the provided method case
+ * */
+ @SuppressWarnings("unchecked")
+ public static List getMethodArguments(Case methodCase) {
+ return (List) methodCase.getFieldValue(PluginConstants.METHOD_ARGUMENTS_FIELD_ID);
+ }
+
+ /**
+ * Assigns task by provided task id. If the task is already assigned, it cancels the task and tries again.
+ *
+ * @param taskId task id of the task to be assigned
+ *
+ * @return task assign outcome
+ * */
+ public AssignTaskEventOutcome safelyAssignTask(String taskId) throws TransitionNotExecutableException {
+ try {
+ return taskService.assignTask(taskId);
+ } catch (TransitionNotExecutableException maybeRethrow) {
+ Task aTask = taskService.findOne(taskId);
+ if (aTask == null) {
+ throw maybeRethrow;
+ }
+ IUser user = userService.getLoggedOrSystem();
+ aTask = taskService.cancelTask(aTask, user).getTask();
+ return taskService.assignTask(aTask, user);
+ }
+ }
+}
diff --git a/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml b/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
new file mode 100644
index 00000000000..2a35630836b
--- /dev/null
+++ b/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
@@ -0,0 +1,76 @@
+
+ entry_point
+ 1.0.0
+ ENP
+ Entry point
+ class
+ true
+ false
+ false
+
+ name
+ Name
+
+
+ method_ids
+ Table of methods
+
+ method
+
+
+
+
+ detail
+ 432
+ 144
+
+
+ detail_0
+ 4
+ grid
+
+ name
+
+ visible
+
+
+ 0
+ 0
+ 1
+ 4
+ material
+ outline
+
+
+
+ method_ids
+
+ visible
+
+
+ 0
+ 1
+ 1
+ 4
+ material
+ outline
+
+
+
+
+
+ p1
+ 304
+ 144
+
+ 1
+ false
+
+
+ a1
+ read
+ p1
+ detail
+ 1
+
+
\ No newline at end of file
diff --git a/src/main/resources/petriNets/engine-processes/plugin/method.xml b/src/main/resources/petriNets/engine-processes/plugin/method.xml
new file mode 100644
index 00000000000..bddcb1d9b00
--- /dev/null
+++ b/src/main/resources/petriNets/engine-processes/plugin/method.xml
@@ -0,0 +1,73 @@
+
+ method
+ 1.0.0
+ MTH
+ Method
+ task
+ true
+ false
+ false
+
+ name
+ Name
+
+
+ arguments
+ Method arguments
+
+
+
+ detail
+ 368
+ 112
+
+
+ detail_0
+ 4
+ grid
+
+ name
+
+ visible
+
+
+ 0
+ 0
+ 1
+ 4
+ material
+ outline
+
+
+
+ arguments
+
+ visible
+
+
+ 0
+ 1
+ 1
+ 4
+ material
+ outline
+
+
+
+
+
+ p1
+ 240
+ 112
+
+ 1
+ false
+
+
+ a1
+ read
+ p1
+ detail
+ 1
+
+
\ No newline at end of file
diff --git a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
new file mode 100644
index 00000000000..b5ee4993c03
--- /dev/null
+++ b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
@@ -0,0 +1,275 @@
+
+ plugin
+ 1.0.0
+ PLG
+ Plugin
+ auto_awesome_motion
+ true
+ false
+ false
+
+ identifier
+ Identifier
+
+
+ name
+ Name
+
+
+ url
+ Url
+
+
+ port
+ Port
+
+
+ active
+ Is active
+ false
+
+
+ entry_point_ids
+ Table of EntryPoints
+
+ entry_point
+
+
+
+
+ init
+ 400
+ 368
+
+
+
+
+ detail
+ 400
+ 176
+
+
+ detail_0
+ 4
+ grid
+
+ identifier
+
+ visible
+
+
+ 0
+ 0
+ 1
+ 4
+ material
+ outline
+
+
+
+ name
+
+ visible
+
+
+ 0
+ 1
+ 1
+ 2
+ material
+ outline
+
+
+
+ active
+
+ visible
+
+
+ 2
+ 1
+ 1
+ 2
+ material
+ outline
+
+
+
+ url
+
+ visible
+
+
+ 0
+ 2
+ 1
+ 2
+ material
+ outline
+
+
+
+ port
+
+ visible
+
+
+ 2
+ 2
+ 1
+ 2
+ material
+ outline
+
+
+
+ entry_point_ids
+
+ visible
+
+
+ 0
+ 3
+ 1
+ 4
+ material
+ outline
+
+
+
+
+
+ activate
+ 624
+ 304
+
+
+ onFinish_activate
+
+
+ active: f.active;
+ change active value { true }
+
+
+
+
+
+ deactivate
+ 624
+ 432
+
+
+ onFinish_deactivate
+
+
+ active: f.active;
+ change active value { false }
+
+
+
+
+
+ active
+ 752
+ 368
+
+ 0
+ false
+
+
+ inactive
+ 496
+ 368
+
+ 0
+ false
+
+
+ p1
+ 304
+ 368
+
+ 1
+ false
+
+
+ initialized
+ 400
+ 272
+
+ 0
+ false
+
+
+ a1
+ regular
+ inactive
+ activate
+ 1
+
+ 496
+ 304
+
+
+
+ a2
+ regular
+ activate
+ active
+ 1
+
+ 752
+ 304
+
+
+
+ a3
+ regular
+ active
+ deactivate
+ 1
+
+ 752
+ 432
+
+
+
+ a4
+ regular
+ deactivate
+ inactive
+ 1
+
+ 496
+ 432
+
+
+
+ a5
+ regular
+ p1
+ init
+ 1
+
+
+ a6
+ regular
+ init
+ inactive
+ 1
+
+
+ a7
+ regular
+ init
+ initialized
+ 1
+
+
+ a8
+ regular
+ initialized
+ detail
+ 1
+
+
\ No newline at end of file
diff --git a/src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java b/src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java
new file mode 100644
index 00000000000..ea436746f0d
--- /dev/null
+++ b/src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java
@@ -0,0 +1,6 @@
+package com.netgrif.application.engine.integration.plugin.injector;
+
+public class PluginInjectorTest {
+ // todo implement tests
+ // test by action delegate?
+}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
index b192e569a69..070258a2b61 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
@@ -1,16 +1,18 @@
package com.netgrif.application.engine.integrations.plugins.mock;
-import com.netgrif.pluginlibrary.core.DeactivationRequest;
-import com.netgrif.pluginlibrary.core.RegistrationRequest;
-import com.netgrif.pluginlibrary.core.RegistrationServiceGrpc;
-import com.netgrif.pluginlibrary.core.UnregistrationRequest;
+import com.google.protobuf.ByteString;
+import com.netgrif.pluginlibrary.core.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
+import org.apache.commons.lang3.SerializationUtils;
public class MockPlugin {
public static final String mockIdentifier = "mock_plugin";
public static final String mockName = "mockPlugin";
+ public static final String mockEntryPointName = "mockEntryPoint";
+ public static final String mockMethodName = "mockMethodName";
+ public static final Class mockArgumentType = String.class;
public static void registerOrActivatePlugin() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
@@ -23,6 +25,13 @@ public static void registerOrActivatePlugin() {
.setName(mockName)
.setUrl("mockurl")
.setPort(9999)
+ .addEntryPoints(EntryPoint.newBuilder()
+ .setName(mockEntryPointName)
+ .addMethods(Method.newBuilder()
+ .setName(mockMethodName)
+ .addArgs(ByteString.copyFrom(SerializationUtils.serialize(mockArgumentType)))
+ .build())
+ .build())
.build());
channel.shutdown();
}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index ad1efe5cb7b..90edc480ede 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -1,53 +1,119 @@
package com.netgrif.application.engine.integrations.plugins.service;
-import com.netgrif.application.engine.integration.plugins.domain.Plugin;
-import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import com.netgrif.application.engine.TestHelper;
+import com.netgrif.application.engine.integration.plugins.utils.PluginUtils;
import com.netgrif.application.engine.integrations.plugins.mock.MockPlugin;
+import com.netgrif.application.engine.startup.ImportHelper;
+import com.netgrif.application.engine.workflow.domain.Case;
+import com.netgrif.application.engine.workflow.domain.QCase;
+import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
import org.springframework.test.context.ActiveProfiles;
+import java.util.List;
+
+import static com.netgrif.application.engine.integration.plugins.utils.PluginUtils.*;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
@SpringBootTest
@ActiveProfiles({"test"})
public class PluginRegistrationServiceTest {
@Autowired
- private PluginRepository repository;
+ private TestHelper testHelper;
+
+ @Autowired
+ private ImportHelper helper;
+
+ @Autowired
+ private IWorkflowService workflowService;
+
+ @Autowired
+ private PluginUtils utils;
+
+ private static final int ELASTIC_WAIT_TIME_IN_MS = 2000;
@BeforeEach
public void before() {
- repository.deleteAll();
+ testHelper.truncateDbs();
+ helper.createNet("engine-processes/plugin/plugin.xml");
+ helper.createNet("engine-processes/plugin/entry_point.xml");
+ helper.createNet("engine-processes/plugin/method.xml");
}
@Test
public void testRegistrationDeactivationAndActivation() {
MockPlugin.registerOrActivatePlugin();
- Plugin foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
- assert foundPlugin != null;
- assert foundPlugin.isActive();
+
+ Page pluginCases = workflowService.search(QCase.case$.processIdentifier.eq("plugin"), Pageable.ofSize(2));
+
+ assert pluginCases.getTotalElements() == 1;
+ Case pluginCase = pluginCases.getContent().get(0);
+ assert pluginCase != null;
+ assert getPluginName(pluginCase).equals(MockPlugin.mockName);
+ assert getPluginIdentifier(pluginCase).equals(MockPlugin.mockIdentifier);
+ assert PluginUtils.isPluginActive(pluginCase);
+ assert pluginCase.getActivePlaces().get("active").equals(1);
+ assert !pluginCase.getActivePlaces().containsKey("inactive");
+
+ List entryPointCases = utils.getPluginEntryPoints(pluginCase);
+ assert entryPointCases.size() == 1;
+ Case entryPointCase = entryPointCases.get(0);
+ assert getEntryPointName(entryPointCase).equals(MockPlugin.mockEntryPointName);
+
+ List methodCases = utils.getEntryPointMethods(entryPointCase);
+ assert methodCases.size() == 1;
+ Case methodCase = methodCases.get(0);
+ assert getMethodName(methodCase).equals(MockPlugin.mockMethodName);
+ List methodArgs = getMethodArguments(methodCase);
+ assert methodArgs.size() == 1;
+ assert methodArgs.get(0).equals(MockPlugin.mockArgumentType.getName());
MockPlugin.deactivatePlugin();
- foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
- assert foundPlugin != null;
- assert !foundPlugin.isActive();
+ pluginCase = workflowService.findOne(pluginCase.getStringId());
+ assert pluginCase != null;
+ assert !PluginUtils.isPluginActive(pluginCase);
+ assert !pluginCase.getActivePlaces().containsKey("active");
+ assert pluginCase.getActivePlaces().get("inactive").equals(1);
MockPlugin.registerOrActivatePlugin();
- foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
- assert foundPlugin != null;
- assert foundPlugin.isActive();
+ pluginCase = workflowService.findOne(pluginCase.getStringId());
+ assert pluginCase != null;
+ assert PluginUtils.isPluginActive(pluginCase);
+ assert pluginCase.getActivePlaces().get("active").equals(1);
+ assert !pluginCase.getActivePlaces().containsKey("inactive");
}
@Test
- public void testUnregister() {
+ public void testUnregister() throws InterruptedException {
MockPlugin.registerOrActivatePlugin();
- Plugin foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
- assert foundPlugin != null;
+ Page pluginCases = workflowService.search(QCase.case$.processIdentifier.eq("plugin"), Pageable.ofSize(2));
+ assert pluginCases.getTotalElements() == 1;
+ Case pluginCase = pluginCases.getContent().get(0);
+ assert pluginCase != null;
+
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+ String pluginCaseId = pluginCase.getStringId();
+ String entryPointCaseId = getPluginEntryPointIds(pluginCase).get(0);
+ String methodCaseid = getEntryPointMethodIds(workflowService.findOne(entryPointCaseId)).get(0);
MockPlugin.unregisterPlugin();
- foundPlugin = repository.findByIdentifier(MockPlugin.mockIdentifier);
- assert foundPlugin == null;
+ assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(pluginCaseId));
+ assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(entryPointCaseId));
+ assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(methodCaseid));
}
+ // register register
+ // register deactivate edit activate
+ // register deactivate unregister
+ // register unregister
+ // unregister missing
+ // register with corrupt request -> check rollback
+ // activate missing plugin
+
}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
index 8c09ba61abb..e5723584df5 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
@@ -1,9 +1,12 @@
package com.netgrif.application.engine.integrations.plugins.service;
-import com.netgrif.application.engine.integration.plugins.domain.Plugin;
-import com.netgrif.application.engine.integration.plugins.repository.PluginRepository;
+import com.netgrif.application.engine.TestHelper;
+import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.integration.plugins.service.IPluginService;
import com.netgrif.application.engine.integrations.plugins.mock.MockExecutionService;
+import com.netgrif.application.engine.startup.ImportHelper;
+import com.netgrif.application.engine.workflow.domain.Case;
+import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import com.netgrif.pluginlibrary.core.ExecutionRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -11,6 +14,7 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
+import static com.netgrif.application.engine.integration.plugins.utils.PluginConstants.*;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
@@ -18,7 +22,16 @@
public class PluginServiceTest {
@Autowired
- private PluginRepository repository;
+ private IWorkflowService workflowService;
+
+ @Autowired
+ private IUserService userService;
+
+ @Autowired
+ private TestHelper testHelper;
+
+ @Autowired
+ private ImportHelper helper;
@Autowired
private IPluginService pluginService;
@@ -27,21 +40,31 @@ public class PluginServiceTest {
private MockExecutionService mockExecutionService;
private static final String pluginIdentifier = "mock_plugin";
+ private static final int ELASTIC_WAIT_TIME_IN_MS = 2000;
@BeforeEach
public void before() {
- repository.deleteAll();
+ testHelper.truncateDbs();
+ helper.createNet("engine-processes/plugin/plugin.xml");
+ }
+
+ private void createMockPluginCase(boolean isActive) {
+ Case pluginCase = workflowService.createCaseByIdentifier("plugin", "", "",
+ userService.getSystem().transformToLoggedUser()).getCase();
+
+ pluginCase.getDataSet().get(PLUGIN_IDENTIFIER_FIELD_ID).setValue(pluginIdentifier);
+ pluginCase.getDataSet().get(PLUGIN_NAME_FIELD_ID).setValue("mockPlugin");
+ pluginCase.getDataSet().get(PLUGIN_URL_FIELD_ID).setValue("localhost");
+ pluginCase.getDataSet().get(PLUGIN_PORT_FIELD_ID).setValue(8090f);
+ pluginCase.getDataSet().get(PLUGIN_ACTIVE_FIELD_ID).setValue(isActive);
+
+ workflowService.save(pluginCase);
}
@Test
- public void testCallRequestAndResponse() {
- Plugin plugin = new Plugin();
- plugin.setIdentifier(pluginIdentifier);
- plugin.setName("mockPlugin");
- plugin.setUrl("localhost");
- plugin.setPort(8090);
- plugin.setActive(true);
- repository.save(plugin);
+ public void testCallRequestAndResponse() throws InterruptedException {
+ createMockPluginCase(true);
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
Object response = pluginService.call(pluginIdentifier, "mockEP", "mockMethod", "mockArg1", "mockArg2");
@@ -60,14 +83,9 @@ public void testCallMissingPlugin() {
}
@Test
- public void testCallDeactivatedPlugin() {
- Plugin plugin = new Plugin();
- plugin.setIdentifier(pluginIdentifier);
- plugin.setName("mockPlugin");
- plugin.setUrl("localhost");
- plugin.setPort(8090);
- plugin.setActive(false);
- repository.save(plugin);
+ public void testCallDeactivatedPlugin() throws InterruptedException {
+ createMockPluginCase(false);
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
assertThrows(IllegalArgumentException.class, () -> pluginService.call(pluginIdentifier, "mockEP", "mockMethod"));
}
From ea899d9dca8e0cf1a3a1ac184b8f7a8190b5fa01 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 13 May 2024 14:50:14 +0200
Subject: [PATCH 23/92] [NAE-1546] Plugin library - update error response in
PluginRegistrationService
---
.../service/PluginRegistrationService.java | 20 +++++++++++++------
.../PluginRegistrationServiceTest.java | 2 +-
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index d46a09273a3..a8fdc753fe0 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -1,6 +1,8 @@
package com.netgrif.application.engine.integration.plugins.service;
import com.netgrif.pluginlibrary.core.*;
+import io.grpc.Status;
+import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -35,8 +37,10 @@ public void register(RegistrationRequest request, StreamObserver check rollback
+ // register with corrupt request -> check rollback and status exception
// activate missing plugin
}
From c3fb3318c4dab46b7e3cb78bf5f389ddaa3a769e Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 14 May 2024 15:08:42 +0200
Subject: [PATCH 24/92] [NAE-1546] Plugin library - add and use custom
exceptions - implement request validation in PluginRegistrationService - fix
error handling in PluginService - fix import in PluginService - update and
add tests in PluginRegistrationServiceTest
---
.../exceptions/InvalidRequestException.java | 12 +
.../PluginIsAlreadyActiveException.java | 12 +
.../service/PluginRegistrationService.java | 49 ++++
.../plugins/service/PluginService.java | 59 +++--
.../integrations/plugins/mock/MockPlugin.java | 42 +++-
.../PluginRegistrationServiceTest.java | 222 ++++++++++++++++--
6 files changed, 355 insertions(+), 41 deletions(-)
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/InvalidRequestException.java
create mode 100644 src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/PluginIsAlreadyActiveException.java
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/InvalidRequestException.java b/src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/InvalidRequestException.java
new file mode 100644
index 00000000000..40e9634757a
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/InvalidRequestException.java
@@ -0,0 +1,12 @@
+package com.netgrif.application.engine.integration.plugins.exceptions;
+
+public class InvalidRequestException extends RuntimeException {
+
+ public InvalidRequestException(String message) {
+ super(message);
+ }
+
+ public InvalidRequestException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/PluginIsAlreadyActiveException.java b/src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/PluginIsAlreadyActiveException.java
new file mode 100644
index 00000000000..f3a12c4a559
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/exceptions/PluginIsAlreadyActiveException.java
@@ -0,0 +1,12 @@
+package com.netgrif.application.engine.integration.plugins.exceptions;
+
+public class PluginIsAlreadyActiveException extends RuntimeException {
+
+ public PluginIsAlreadyActiveException(String message) {
+ super(message);
+ }
+
+ public PluginIsAlreadyActiveException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
index a8fdc753fe0..3bf3beea2f4 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginRegistrationService.java
@@ -1,9 +1,12 @@
package com.netgrif.application.engine.integration.plugins.service;
+import com.netgrif.application.engine.integration.plugins.exceptions.InvalidRequestException;
+import com.netgrif.application.engine.integration.plugins.exceptions.PluginIsAlreadyActiveException;
import com.netgrif.pluginlibrary.core.*;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;
+import joptsimple.internal.Strings;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -32,10 +35,14 @@ public final class PluginRegistrationService extends RegistrationServiceGrpc.Reg
@Override
public void register(RegistrationRequest request, StreamObserver responseObserver) {
try {
+ validateRequest(request);
String responseMsg = pluginService.registerOrActivate(request);
RegistrationResponse response = RegistrationResponse.newBuilder().setMessage(responseMsg).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
+ } catch (PluginIsAlreadyActiveException | InvalidRequestException e) {
+ log.error(e.getMessage(), e);
+ responseObserver.onError(new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage())));
} catch (RuntimeException e) {
String message = String.format("Something went wrong when registering or activating plugin with identifier [%s]",
request.getIdentifier());
@@ -52,10 +59,14 @@ public void register(RegistrationRequest request, StreamObserver responseObserver) {
try {
+ validateRequest(request);
String responseMsg = pluginService.unregister(request.getIdentifier());
UnregistrationResponse response = UnregistrationResponse.newBuilder().setMessage(responseMsg).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
+ } catch (InvalidRequestException e) {
+ log.error(e.getMessage(), e);
+ responseObserver.onError(new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage())));
} catch (RuntimeException e) {
String message = String.format("Something went wrong when unregistering plugin with identifier [%s]",
request.getIdentifier());
@@ -72,10 +83,14 @@ public void unregister(UnregistrationRequest request, StreamObserver responseObserver) {
try {
+ validateRequest(request);
String responseMsg = pluginService.deactivate(request.getIdentifier());
DeactivationResponse response = DeactivationResponse.newBuilder().setMessage(responseMsg).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
+ } catch (InvalidRequestException e) {
+ log.error(e.getMessage(), e);
+ responseObserver.onError(new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage())));
} catch (RuntimeException e) {
String message = String.format("Something went wrong when deactivating plugin with identifier [%s]",
request.getIdentifier());
@@ -83,4 +98,38 @@ public void deactivate(DeactivationRequest request, StreamObserver existingPluginOpt = findByIdentifier(request.getIdentifier());
try {
if (existingPluginOpt.isPresent()) {
@@ -119,13 +120,7 @@ public String unregister(String identifier) {
pluginInjector.uninject(existingPluginOpt.get());
- for (Case entryPointCase : utils.getPluginEntryPoints(existingPluginOpt.get())) {
- for (Case methodCase : utils.getEntryPointMethods(entryPointCase)) {
- workflowService.deleteCase(methodCase);
- }
- workflowService.deleteCase(entryPointCase);
- }
- workflowService.deleteCase(existingPluginOpt.get());
+ removePluginCase(existingPluginOpt.get());
String responseMsg = "Plugin with identifier \"" + identifier + "\" was unregistered.";
log.info(responseMsg);
@@ -154,7 +149,8 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
ManagedChannel channel = ManagedChannelBuilder.forAddress(getPluginUrl(pluginCase), getPluginPort(pluginCase))
.usePlaintext()
.build();
- List argBytes = Arrays.stream(args).map(arg -> ByteString.copyFrom(SerializationUtils.serialize(arg))).collect(Collectors.toList());
+ List argBytes = Arrays.stream(args).map(arg -> ByteString.copyFrom(
+ Objects.requireNonNull(SerializationUtils.serialize(arg)))).collect(Collectors.toList());
ExecutionServiceGrpc.ExecutionServiceBlockingStub stub = ExecutionServiceGrpc.newBlockingStub(channel);
ExecutionResponse responseMessage = stub.execute(ExecutionRequest.newBuilder()
.setEntryPoint(entryPoint)
@@ -232,11 +228,14 @@ private String register(RegistrationRequest request) throws TransitionNotExecuta
return inject(pluginCase, "registered");
}
- private String activate(Case pluginCase, RegistrationRequest request) throws TransitionNotExecutableException {
- pluginCase = createOrUpdatePluginCase(request, Optional.of(pluginCase));
- if (!isPluginActive(pluginCase)) {
- pluginCase = doActivation(pluginCase);
+ private String activate(Case pluginCase, RegistrationRequest request) throws TransitionNotExecutableException,
+ PluginIsAlreadyActiveException {
+ if (isPluginActive(pluginCase)) {
+ throw new PluginIsAlreadyActiveException(String.format("Plugin with identifier [%s] is already active. Plugin must be inactive.",
+ request.getIdentifier()));
}
+ pluginCase = createOrUpdatePluginCase(request, Optional.of(pluginCase));
+ pluginCase = doActivation(pluginCase);
return inject(pluginCase, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
}
@@ -287,7 +286,7 @@ private Case createOrUpdatePluginCase(RegistrationRequest request, Optional ent
CreateOrUpdateOutcome methodOutcome = createOrUpdateMethodCases(entryPoint, loggedUser,
utils.getEntryPointMethods(entryPointCase));
outcome.addAllCreatedCaseId(methodOutcome.getCreatedCaseIds());
- Set epToBeRemovedIds = new HashSet<>(getEntryPointMethodIds(entryPointCase));
- epToBeRemovedIds.removeAll(methodOutcome.getSubjectCaseIds());
+ Set methodToBeRemovedIds = new HashSet<>(getEntryPointMethodIds(entryPointCase));
+ methodToBeRemovedIds.removeAll(methodOutcome.getSubjectCaseIds());
Map> dataToSet = new HashMap<>();
dataToSet.put(ENTRY_POINT_NAME_FIELD_ID, Map.of("value", entryPoint.getName(), "type",
@@ -324,7 +323,7 @@ private CreateOrUpdateOutcome createOrUpdateEntryPointCases(List ent
String taskId = findTaskIdInCase(entryPointCase, ENTRY_POINT_DETAIL_TRANS_ID);
dataService.setData(taskId, ImportHelper.populateDatasetAsObjects(dataToSet));
- removeCases(epToBeRemovedIds);
+ removeCases(methodToBeRemovedIds);
}
return outcome;
@@ -363,7 +362,7 @@ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, L
"type", FieldType.TEXT.getName()));
List argTypesAsString = method.getArgsList().stream()
.map(arg -> {
- Class> clazz = (Class>) org.springframework.util.SerializationUtils.deserialize(arg.toByteArray());
+ Class> clazz = (Class>) SerializationUtils.deserialize(arg.toByteArray());
assert clazz != null;
return clazz.getName();
})
@@ -391,8 +390,26 @@ private GetOrCreateOutcome getOrCreateMethodCase(Method method, LoggedUser logge
return new GetOrCreateOutcome(methodCase, methodCaseOpt.isEmpty());
}
- private void removeCases(Set createdCaseIds) {
- for (String caseId : createdCaseIds) {
+ private void removePluginCase(Case pluginCase) {
+ removeEntryPointCases(utils.getPluginEntryPoints(pluginCase));
+ workflowService.deleteCase(pluginCase);
+ }
+
+ private void removeEntryPointCases(Set entryPointCaseIds) {
+ removeEntryPointCases(entryPointCaseIds.stream().map(workflowService::findOne).collect(Collectors.toList()));
+ }
+
+ private void removeEntryPointCases(List entryPointCases) {
+ for (Case entryPointCase : entryPointCases) {
+ for (Case methodCase : utils.getEntryPointMethods(entryPointCase)) {
+ workflowService.deleteCase(methodCase);
+ }
+ workflowService.deleteCase(entryPointCase);
+ }
+ }
+
+ private void removeCases(Set caseIds) {
+ for (String caseId : caseIds) {
Case caseToRemove = workflowService.findOne(caseId);
if (caseToRemove != null) {
workflowService.deleteCase(caseId);
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
index 070258a2b61..ebd470e8fbd 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
@@ -9,11 +9,12 @@
public class MockPlugin {
public static final String mockIdentifier = "mock_plugin";
- public static final String mockName = "mockPlugin";
- public static final String mockEntryPointName = "mockEntryPoint";
- public static final String mockMethodName = "mockMethodName";
+ public static String mockName = "mockPlugin";
+ public static String mockEntryPointName = "mockEntryPoint";
+ public static String mockMethodName = "mockMethodName";
public static final Class mockArgumentType = String.class;
+ @SuppressWarnings("ResultOfMethodCallIgnored")
public static void registerOrActivatePlugin() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
.usePlaintext()
@@ -36,6 +37,18 @@ public static void registerOrActivatePlugin() {
channel.shutdown();
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ public static void registerWithCustomRequest(RegistrationRequest request) {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
+ .usePlaintext()
+ .build();
+
+ RegistrationServiceGrpc.RegistrationServiceBlockingStub stub = RegistrationServiceGrpc.newBlockingStub(channel);
+ stub.register(request);
+ channel.shutdown();
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
public static void unregisterPlugin() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
.usePlaintext()
@@ -48,6 +61,18 @@ public static void unregisterPlugin() {
channel.shutdown();
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ public static void unregisterPluginWithCustomRequest(UnregistrationRequest request) {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
+ .usePlaintext()
+ .build();
+
+ RegistrationServiceGrpc.RegistrationServiceBlockingStub stub = RegistrationServiceGrpc.newBlockingStub(channel);
+ stub.unregister(request);
+ channel.shutdown();
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
public static void deactivatePlugin() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
.usePlaintext()
@@ -59,4 +84,15 @@ public static void deactivatePlugin() {
.build());
channel.shutdown();
}
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ public static void deactivatePluginWithCustomRequest(DeactivationRequest request) {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
+ .usePlaintext()
+ .build();
+
+ RegistrationServiceGrpc.RegistrationServiceBlockingStub stub = RegistrationServiceGrpc.newBlockingStub(channel);
+ stub.deactivate(request);
+ channel.shutdown();
+ }
}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index 1cb07142a63..fbe1466961a 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -1,12 +1,17 @@
package com.netgrif.application.engine.integrations.plugins.service;
import com.netgrif.application.engine.TestHelper;
+import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.integration.plugins.utils.PluginUtils;
import com.netgrif.application.engine.integrations.plugins.mock.MockPlugin;
+import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
import com.netgrif.application.engine.startup.ImportHelper;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.QCase;
import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
+import com.netgrif.pluginlibrary.core.*;
+import io.grpc.Status;
+import io.grpc.StatusRuntimeException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +38,12 @@ public class PluginRegistrationServiceTest {
@Autowired
private IWorkflowService workflowService;
+ @Autowired
+ private IPetriNetService petriNetService;
+
+ @Autowired
+ private IUserService userService;
+
@Autowired
private PluginUtils utils;
@@ -47,7 +58,7 @@ public void before() {
}
@Test
- public void testRegistrationDeactivationAndActivation() {
+ public void testRegistrationDeactivationAndActivation() throws InterruptedException {
MockPlugin.registerOrActivatePlugin();
Page pluginCases = workflowService.search(QCase.case$.processIdentifier.eq("plugin"), Pageable.ofSize(2));
@@ -74,6 +85,7 @@ public void testRegistrationDeactivationAndActivation() {
assert methodArgs.size() == 1;
assert methodArgs.get(0).equals(MockPlugin.mockArgumentType.getName());
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
MockPlugin.deactivatePlugin();
pluginCase = workflowService.findOne(pluginCase.getStringId());
assert pluginCase != null;
@@ -90,7 +102,7 @@ public void testRegistrationDeactivationAndActivation() {
}
@Test
- public void testUnregister() throws InterruptedException {
+ public void testRegisterAndUnregister() throws InterruptedException {
MockPlugin.registerOrActivatePlugin();
Page pluginCases = workflowService.search(QCase.case$.processIdentifier.eq("plugin"), Pageable.ofSize(2));
assert pluginCases.getTotalElements() == 1;
@@ -99,21 +111,197 @@ public void testUnregister() throws InterruptedException {
Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
- String pluginCaseId = pluginCase.getStringId();
- String entryPointCaseId = getPluginEntryPointIds(pluginCase).get(0);
- String methodCaseid = getEntryPointMethodIds(workflowService.findOne(entryPointCaseId)).get(0);
MockPlugin.unregisterPlugin();
- assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(pluginCaseId));
- assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(entryPointCaseId));
- assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(methodCaseid));
- }
-
- // register register
- // register deactivate edit activate
- // register deactivate unregister
- // register unregister
- // unregister missing
- // register with corrupt request -> check rollback and status exception
- // activate missing plugin
+ assertIfAnyCaseExists();
+ }
+
+ @Test
+ public void testRegisterAndRegister() throws InterruptedException {
+ MockPlugin.registerOrActivatePlugin();
+
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+ assertThrows(StatusRuntimeException.class, MockPlugin::registerOrActivatePlugin);
+ }
+
+ @Test
+ public void testRegisterDeactivateEditAndActivate() throws InterruptedException {
+ MockPlugin.registerOrActivatePlugin();
+
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+ MockPlugin.deactivatePlugin();
+
+ Case pluginCase = workflowService.searchOne(QCase.case$.processIdentifier.eq("plugin"));
+ assert getPluginName(pluginCase).equals(MockPlugin.mockName);
+
+ List epCases = utils.getPluginEntryPoints(pluginCase);
+ assert epCases.size() == 1;
+ assert getEntryPointName(epCases.get(0)).equals(MockPlugin.mockEntryPointName);
+
+ List methodCases = utils.getEntryPointMethods(epCases.get(0));
+ assert methodCases.size() == 1;
+ assert getMethodName(methodCases.get(0)).equals(MockPlugin.mockMethodName);
+
+ String oldEpCaseId = epCases.get(0).getStringId();
+ String oldMethodCaseId = methodCases.get(0).getStringId();
+ MockPlugin.mockName = "pluginNewName";
+ MockPlugin.mockEntryPointName = "entryPointNewName";
+ MockPlugin.mockMethodName = "methodNewName";
+
+ MockPlugin.registerOrActivatePlugin();
+
+ pluginCase = workflowService.findOne(pluginCase.getStringId());
+ assert getPluginName(pluginCase).equals("pluginNewName");
+
+ epCases = utils.getPluginEntryPoints(pluginCase);
+ assert epCases.size() == 1;
+ assert getEntryPointName(epCases.get(0)).equals("entryPointNewName");
+ assert !epCases.get(0).getStringId().equals(oldEpCaseId);
+ assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(oldEpCaseId));
+
+ methodCases = utils.getEntryPointMethods(epCases.get(0));
+ assert methodCases.size() == 1;
+ assert getMethodName(methodCases.get(0)).equals("methodNewName");
+ assert !methodCases.get(0).getStringId().equals(oldMethodCaseId);
+ assertThrows(IllegalArgumentException.class, () -> workflowService.findOne(oldMethodCaseId));
+ }
+
+ @Test
+ public void testRegisterDeactivateAndUnregister() throws InterruptedException {
+ MockPlugin.registerOrActivatePlugin();
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+ MockPlugin.deactivatePlugin();
+
+ assertIfAnyCaseNotExists();
+ MockPlugin.unregisterPlugin();
+ assertIfAnyCaseExists();
+ }
+
+ @Test
+ public void testUnregisterMissing() {
+ assertThrows(StatusRuntimeException.class, MockPlugin::unregisterPlugin);
+ }
+
+ @Test
+ public void testRegistrationWithCorruptIdentifier() {
+ RegistrationRequest corruptReq = RegistrationRequest.newBuilder()
+ .setIdentifier("")
+ .setName("name")
+ .setUrl("url")
+ .setPort(1)
+ .build();
+ assertCorruptRegistrationRequest(corruptReq);
+ }
+
+ @Test
+ public void testRegistrationWithCorruptName() {
+ RegistrationRequest corruptReq = RegistrationRequest.newBuilder()
+ .setIdentifier("identifier")
+ .setName("")
+ .setUrl("url")
+ .setPort(1)
+ .build();
+ assertCorruptRegistrationRequest(corruptReq);
+ }
+
+ @Test
+ public void testRegistrationWithCorruptUrl() {
+ RegistrationRequest corruptReq = RegistrationRequest.newBuilder()
+ .setIdentifier("identifier")
+ .setName("name")
+ .setUrl("")
+ .setPort(1)
+ .build();
+ assertCorruptRegistrationRequest(corruptReq);
+ }
+
+ @Test
+ public void testRegistrationWithCorruptEntryPointName() {
+ RegistrationRequest corruptReq = RegistrationRequest.newBuilder()
+ .setIdentifier("identifier")
+ .setName("name")
+ .setUrl("url")
+ .setPort(1)
+ .addEntryPoints(EntryPoint.newBuilder()
+ .setName("")
+ .build())
+ .build();
+ assertCorruptRegistrationRequest(corruptReq);
+ }
+
+ @Test
+ public void testRegistrationWithCorruptMethodName() {
+ RegistrationRequest corruptReq = RegistrationRequest.newBuilder()
+ .setIdentifier("identifier")
+ .setName("name")
+ .setUrl("url")
+ .setPort(1)
+ .addEntryPoints(EntryPoint.newBuilder()
+ .setName("name")
+ .addMethods(Method.newBuilder()
+ .setName("")
+ .build())
+ .build())
+ .build();
+ assertCorruptRegistrationRequest(corruptReq);
+ }
+
+ private void assertCorruptRegistrationRequest(RegistrationRequest corruptReq) {
+ StatusRuntimeException e = assertThrows(StatusRuntimeException.class, () -> MockPlugin.registerWithCustomRequest(corruptReq));
+ assert e.getStatus().getCode().value() == Status.INVALID_ARGUMENT.getCode().value();
+ assertIfAnyCaseExists();
+ }
+
+ @Test
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ public void testRegistrationSystemFailure() {
+ petriNetService.deletePetriNet(petriNetService.findByImportId("method").get().getStringId(),
+ userService.getSystem().transformToLoggedUser()); // create unexpected situation
+
+ StatusRuntimeException e = assertThrows(StatusRuntimeException.class, MockPlugin::registerOrActivatePlugin);
+ assert e.getStatus().getCode().value() == Status.INTERNAL.getCode().value();
+ assertIfAnyCaseExists();
+ }
+
+ @Test
+ public void testDeactivationWithCorruptRequest() throws InterruptedException {
+ MockPlugin.registerOrActivatePlugin();
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+
+ DeactivationRequest corruptReq = DeactivationRequest.newBuilder()
+ .setIdentifier("")
+ .build();
+ StatusRuntimeException e = assertThrows(StatusRuntimeException.class, () -> MockPlugin.deactivatePluginWithCustomRequest(corruptReq));
+ assert e.getStatus().getCode().value() == Status.INVALID_ARGUMENT.getCode().value();
+
+ Case pluginCase = workflowService.searchOne(QCase.case$.processIdentifier.eq("plugin"));
+ assert isPluginActive(pluginCase);
+ assert pluginCase.getActivePlaces().get("active") == 1;
+ assert !pluginCase.getActivePlaces().containsKey("inactive");
+ }
+
+ @Test
+ public void testUnregistrationWithCorruptRequest() throws InterruptedException {
+ MockPlugin.registerOrActivatePlugin();
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+
+ UnregistrationRequest corruptReq = UnregistrationRequest.newBuilder()
+ .setIdentifier("")
+ .build();
+ StatusRuntimeException e = assertThrows(StatusRuntimeException.class, () -> MockPlugin.unregisterPluginWithCustomRequest(corruptReq));
+ assert e.getStatus().getCode().value() == Status.INVALID_ARGUMENT.getCode().value();
+ assertIfAnyCaseNotExists();
+ }
+
+ private void assertIfAnyCaseExists() {
+ assert workflowService.searchOne(QCase.case$.processIdentifier.eq("plugin")) == null;
+ assert workflowService.searchOne(QCase.case$.processIdentifier.eq("entry_point")) == null;
+ assert workflowService.searchOne(QCase.case$.processIdentifier.eq("method")) == null;
+ }
+
+ private void assertIfAnyCaseNotExists() {
+ assert workflowService.searchOne(QCase.case$.processIdentifier.eq("plugin")) != null;
+ assert workflowService.searchOne(QCase.case$.processIdentifier.eq("entry_point")) != null;
+ assert workflowService.searchOne(QCase.case$.processIdentifier.eq("method")) != null;
+ }
}
From 1f41445fc2b42f3222a0b4454f21643a7008a418 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Wed, 15 May 2024 10:25:06 +0200
Subject: [PATCH 25/92] [NAE-1546] Plugin library - update tests to test
PluginInjector protected methods
---
.../plugin/injector/PluginInjectorTest.java | 6 --
.../PluginRegistrationServiceTest.java | 33 ++++++-
.../petriNets/plugin/test_plugin_injector.xml | 92 +++++++++++++++++++
3 files changed, 123 insertions(+), 8 deletions(-)
delete mode 100644 src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java
create mode 100644 src/test/resources/petriNets/plugin/test_plugin_injector.xml
diff --git a/src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java b/src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java
deleted file mode 100644
index ea436746f0d..00000000000
--- a/src/test/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjectorTest.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.netgrif.application.engine.integration.plugin.injector;
-
-public class PluginInjectorTest {
- // todo implement tests
- // test by action delegate?
-}
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index fbe1466961a..a1cda34f0e9 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -1,13 +1,17 @@
package com.netgrif.application.engine.integrations.plugins.service;
import com.netgrif.application.engine.TestHelper;
+import com.netgrif.application.engine.auth.domain.LoggedUser;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.integration.plugins.utils.PluginUtils;
import com.netgrif.application.engine.integrations.plugins.mock.MockPlugin;
+import com.netgrif.application.engine.petrinet.domain.throwable.TransitionNotExecutableException;
import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
import com.netgrif.application.engine.startup.ImportHelper;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.QCase;
+import com.netgrif.application.engine.workflow.domain.Task;
+import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import com.netgrif.pluginlibrary.core.*;
import io.grpc.Status;
@@ -44,6 +48,9 @@ public class PluginRegistrationServiceTest {
@Autowired
private IUserService userService;
+ @Autowired
+ private ITaskService taskService;
+
@Autowired
private PluginUtils utils;
@@ -55,10 +62,11 @@ public void before() {
helper.createNet("engine-processes/plugin/plugin.xml");
helper.createNet("engine-processes/plugin/entry_point.xml");
helper.createNet("engine-processes/plugin/method.xml");
+ helper.createNet("plugin/test_plugin_injector.xml");
}
@Test
- public void testRegistrationDeactivationAndActivation() throws InterruptedException {
+ public void testRegistrationDeactivationAndActivation() throws InterruptedException, TransitionNotExecutableException {
MockPlugin.registerOrActivatePlugin();
Page pluginCases = workflowService.search(QCase.case$.processIdentifier.eq("plugin"), Pageable.ofSize(2));
@@ -92,6 +100,7 @@ public void testRegistrationDeactivationAndActivation() throws InterruptedExcept
assert !PluginUtils.isPluginActive(pluginCase);
assert !pluginCase.getActivePlaces().containsKey("active");
assert pluginCase.getActivePlaces().get("inactive").equals(1);
+ testIsInjected();
MockPlugin.registerOrActivatePlugin();
pluginCase = workflowService.findOne(pluginCase.getStringId());
@@ -102,17 +111,19 @@ public void testRegistrationDeactivationAndActivation() throws InterruptedExcept
}
@Test
- public void testRegisterAndUnregister() throws InterruptedException {
+ public void testRegisterAndUnregister() throws InterruptedException, TransitionNotExecutableException {
MockPlugin.registerOrActivatePlugin();
Page pluginCases = workflowService.search(QCase.case$.processIdentifier.eq("plugin"), Pageable.ofSize(2));
assert pluginCases.getTotalElements() == 1;
Case pluginCase = pluginCases.getContent().get(0);
assert pluginCase != null;
+ testIsInjected();
Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
MockPlugin.unregisterPlugin();
assertIfAnyCaseExists();
+ testIsNotInjected();
}
@Test
@@ -292,6 +303,24 @@ public void testUnregistrationWithCorruptRequest() throws InterruptedException {
assertIfAnyCaseNotExists();
}
+ private void testIsInjected() throws TransitionNotExecutableException {
+ Case testCase = doTestInjection("injection");
+ assert (Boolean) testCase.getFieldValue("is_injected");
+ }
+
+ private void testIsNotInjected() throws TransitionNotExecutableException {
+ Case testCase = doTestInjection("uninjection");
+ assert !((Boolean) testCase.getFieldValue("is_injected"));
+ }
+
+ private Case doTestInjection(String transitionId) throws TransitionNotExecutableException {
+ LoggedUser loggedUser = userService.getSystem().transformToLoggedUser();
+ Case testCase = workflowService.createCaseByIdentifier("test_plugin_injector", "", "", loggedUser).getCase();
+ String taskId = PluginUtils.findTaskIdInCase(testCase, transitionId);
+ Task injectionTask = taskService.assignTask(taskId).getTask();
+ return taskService.finishTask(injectionTask, loggedUser.transformToUser()).getCase();
+ }
+
private void assertIfAnyCaseExists() {
assert workflowService.searchOne(QCase.case$.processIdentifier.eq("plugin")) == null;
assert workflowService.searchOne(QCase.case$.processIdentifier.eq("entry_point")) == null;
diff --git a/src/test/resources/petriNets/plugin/test_plugin_injector.xml b/src/test/resources/petriNets/plugin/test_plugin_injector.xml
new file mode 100644
index 00000000000..506f84a08ec
--- /dev/null
+++ b/src/test/resources/petriNets/plugin/test_plugin_injector.xml
@@ -0,0 +1,92 @@
+
+ test_plugin_injector
+ 1.0.0
+ TPI
+ test_plugin_injector
+ device_hub
+ true
+ false
+ false
+
+ is_injected
+
+
+
+ uninjection
+ 240
+ 176
+
+
+ 0
+
+
+ is_injected: f.is_injected;
+ try {
+ mockPlugin.mockEntryPoint.mockMethodName("test")
+ } catch (NullPointerException ignore) {
+ change is_injected value { false }
+ }
+
+
+
+
+
+ injection
+ 240
+ 80
+
+
+ 1
+
+
+ is_injected: f.is_injected;
+ try {
+ mockPlugin.mockEntryPoint.mockMethodName("test")
+ change is_injected value { true }
+ } catch (NullPointerException ignore) {
+ change is_injected value { false }
+ } catch (Exception ignore) {
+ // target microservice is not running
+ change is_injected value { true }
+ }
+
+
+
+
+
+ p1
+ 112
+ 112
+
+ 1
+ false
+
+
+ a1
+ regular
+ p1
+ injection
+ 1
+
+
+ a2
+ regular
+ injection
+ p1
+ 1
+
+
+ a3
+ regular
+ p1
+ uninjection
+ 1
+
+
+ a4
+ regular
+ uninjection
+ p1
+ 1
+
+
\ No newline at end of file
From 908eac165975115766d3ce870e134b0c8a8cb1a5 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Wed, 15 May 2024 12:09:24 +0200
Subject: [PATCH 26/92] [NAE-1546] Plugin library - implement
CreateOrUpdateOutcomeTest
---
.../outcomes/CreateOrUpdateOutcomeTest.java | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 src/test/java/com/netgrif/application/engine/integrations/plugins/outcomes/CreateOrUpdateOutcomeTest.java
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/outcomes/CreateOrUpdateOutcomeTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/outcomes/CreateOrUpdateOutcomeTest.java
new file mode 100644
index 00000000000..e843fadb0e1
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/outcomes/CreateOrUpdateOutcomeTest.java
@@ -0,0 +1,21 @@
+package com.netgrif.application.engine.integrations.plugins.outcomes;
+
+import com.netgrif.application.engine.integration.plugins.outcomes.CreateOrUpdateOutcome;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+@SpringBootTest
+@ActiveProfiles({"test"})
+public class CreateOrUpdateOutcomeTest {
+
+ @Test
+ public void testAddCreatedAndSubjectCaseId() {
+ CreateOrUpdateOutcome outcome = new CreateOrUpdateOutcome();
+
+ outcome.addCreatedAndSubjectCaseId("test-case-id");
+
+ assert outcome.getCreatedCaseIds().contains("test-case-id") : "Collection createdCaseIds has missing id";
+ assert outcome.getSubjectCaseIds().contains("test-case-id") : "Collection subjectCaseIds has missing id";
+ }
+}
From 51ce382d4ea87214e318e1b6ab034551f4502c6c Mon Sep 17 00:00:00 2001
From: chvostek
Date: Wed, 15 May 2024 12:29:38 +0200
Subject: [PATCH 27/92] [NAE-1546] Plugin library - add translations into
plugin processes - fix logging in PluginService
---
.../plugins/service/PluginService.java | 4 +--
.../engine-processes/plugin/entry_point.xml | 15 +++++---
.../engine-processes/plugin/method.xml | 17 ++++++---
.../engine-processes/plugin/plugin.xml | 35 ++++++++++++++-----
4 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index c25e9e03518..dde78037d89 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -76,13 +76,13 @@ public void startServer() throws IOException {
.addService(new PluginRegistrationService(this))
.build();
server.start();
- log.info(LOG_PREFIX + " Started on port " + properties.getPort());
+ log.info("{} Started on port {}", LOG_PREFIX, properties.getPort());
}
@PreDestroy
public void stopServer() {
server.shutdown();
- log.info(LOG_PREFIX + " Stopped server on port " + properties.getPort());
+ log.info("{} Stopped server on port {}", LOG_PREFIX, properties.getPort());
}
/**
diff --git a/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml b/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
index 2a35630836b..d2afcdf80c9 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
@@ -9,21 +9,28 @@
falsename
- Name
+ Namemethod_ids
- Table of methods
+ method
-
+
+ Názov
+ Detail
+
+
+ Name
+ Detail
+ detail432144
-
+
detail_04
diff --git a/src/main/resources/petriNets/engine-processes/plugin/method.xml b/src/main/resources/petriNets/engine-processes/plugin/method.xml
index bddcb1d9b00..7d3491907bb 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/method.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/method.xml
@@ -9,18 +9,27 @@
falsename
- Name
+ Namearguments
- Method arguments
+ Method arguments
-
+
+ Názov
+ Argumenty funkcie
+ Detail
+
+
+ Name
+ Methodenargumente
+ Detail
+ detail368112
-
+
detail_04
diff --git a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
index b5ee4993c03..2b727173d7d 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
@@ -13,29 +13,46 @@
name
- Name
+ Nameurl
- Url
+ Urlport
- Port
+ Portactive
- Is active
+ Is activefalseentry_point_ids
- Table of EntryPoints
+ entry_point
-
+
+ Názov
+ Url
+ Port
+ Je aktÃvny
+ Detail
+ Aktivovať
+ Deaktivovať
+
+
+ Name
+ Url
+ Port
+ Ist aktiv
+ Detail
+ Aktivieren
+ Deaktivieren
+ init400
@@ -47,7 +64,7 @@
detail400176
-
+
detail_04
@@ -142,7 +159,7 @@
activate624304
-
+
onFinish_activate
@@ -157,7 +174,7 @@
deactivate624432
-
+
onFinish_deactivate
From 6d6453742f964130a6fb2f7a0ade27d98c5dfaac Mon Sep 17 00:00:00 2001
From: chvostek
Date: Thu, 16 May 2024 10:55:01 +0200
Subject: [PATCH 28/92] [NAE-1546] Plugin library - fix uninjecting outdated
metadata when activating plugin in PluginService - update tests in
PluginRegistrationServiceTest - fix actions in test_plugin_injector.xml
---
.../engine/integration/plugins/service/PluginService.java | 1 +
.../plugins/service/PluginRegistrationServiceTest.java | 8 +++++---
.../resources/petriNets/plugin/test_plugin_injector.xml | 5 ++++-
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index dde78037d89..305800333c6 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -234,6 +234,7 @@ private String activate(Case pluginCase, RegistrationRequest request) throws Tra
throw new PluginIsAlreadyActiveException(String.format("Plugin with identifier [%s] is already active. Plugin must be inactive.",
request.getIdentifier()));
}
+ pluginInjector.uninject(pluginCase); // remove potentially outdated meta classes
pluginCase = createOrUpdatePluginCase(request, Optional.of(pluginCase));
pluginCase = doActivation(pluginCase);
return inject(pluginCase, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index a1cda34f0e9..6a1cf59018a 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -135,7 +135,7 @@ public void testRegisterAndRegister() throws InterruptedException {
}
@Test
- public void testRegisterDeactivateEditAndActivate() throws InterruptedException {
+ public void testRegisterDeactivateEditAndActivate() throws InterruptedException, TransitionNotExecutableException {
MockPlugin.registerOrActivatePlugin();
Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
@@ -160,6 +160,8 @@ public void testRegisterDeactivateEditAndActivate() throws InterruptedException
MockPlugin.registerOrActivatePlugin();
+ testIsNotInjected(); // will not assert if the old meta classes are uninjected
+
pluginCase = workflowService.findOne(pluginCase.getStringId());
assert getPluginName(pluginCase).equals("pluginNewName");
@@ -305,12 +307,12 @@ public void testUnregistrationWithCorruptRequest() throws InterruptedException {
private void testIsInjected() throws TransitionNotExecutableException {
Case testCase = doTestInjection("injection");
- assert (Boolean) testCase.getFieldValue("is_injected");
+ assert (Boolean) testCase.getFieldValue("is_injected"): "Plugin is not injected";
}
private void testIsNotInjected() throws TransitionNotExecutableException {
Case testCase = doTestInjection("uninjection");
- assert !((Boolean) testCase.getFieldValue("is_injected"));
+ assert !((Boolean) testCase.getFieldValue("is_injected")): "Plugin is still injected";
}
private Case doTestInjection(String transitionId) throws TransitionNotExecutableException {
diff --git a/src/test/resources/petriNets/plugin/test_plugin_injector.xml b/src/test/resources/petriNets/plugin/test_plugin_injector.xml
index 506f84a08ec..e64fb765e48 100644
--- a/src/test/resources/petriNets/plugin/test_plugin_injector.xml
+++ b/src/test/resources/petriNets/plugin/test_plugin_injector.xml
@@ -23,8 +23,11 @@
is_injected: f.is_injected;
try {
mockPlugin.mockEntryPoint.mockMethodName("test")
+ change is_injected value { true }
} catch (NullPointerException ignore) {
change is_injected value { false }
+ } catch (io.grpc.StatusRuntimeException ignore) {
+ change is_injected value { true }
}
@@ -46,7 +49,7 @@
} catch (NullPointerException ignore) {
change is_injected value { false }
} catch (Exception ignore) {
- // target microservice is not running
+ // target microservice is not running or is deactivated
change is_injected value { true }
}
From 6f8c9e253cbd6ef2d482a4eeec90d09d84531cf4 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Thu, 16 May 2024 15:44:13 +0200
Subject: [PATCH 29/92] [NAE-1546] Plugin library - add attribute in
GetOrCreateOutcome - fix handling of overlapping methods in request - add
test for overlapping methods in PluginRegistrationServiceTest
---
.../plugins/outcomes/GetOrCreateOutcome.java | 6 +++
.../plugins/service/PluginService.java | 43 ++++++++++-------
.../plugins/utils/PluginConstants.java | 1 +
.../plugins/utils/PluginUtils.java | 37 ++++++++++++++
.../engine-processes/plugin/method.xml | 4 ++
.../integrations/plugins/mock/MockPlugin.java | 2 +-
.../PluginRegistrationServiceTest.java | 48 ++++++++++++++++++-
7 files changed, 120 insertions(+), 21 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java b/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java
index 82532f0d1cc..d4abdf22bc6 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/outcomes/GetOrCreateOutcome.java
@@ -9,4 +9,10 @@
public class GetOrCreateOutcome {
private final Case subjectCase;
private final boolean isNew;
+ private Object additionalData;
+
+ public GetOrCreateOutcome(Case subjectCase, boolean isNew) {
+ this.subjectCase = subjectCase;
+ this.isNew = isNew;
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 305800333c6..33fb43ca40a 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -38,6 +38,7 @@
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.io.Serializable;
+import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;
@@ -100,7 +101,7 @@ public String registerOrActivate(RegistrationRequest request) throws PluginIsAlr
} else {
return register(request);
}
- } catch (TransitionNotExecutableException e) {
+ } catch (TransitionNotExecutableException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
@@ -222,19 +223,19 @@ public Optional findByIdentifier(String identifier) {
return result.hasContent() ? Optional.of(result.getContent().get(0)) : Optional.empty();
}
- private String register(RegistrationRequest request) throws TransitionNotExecutableException {
+ private String register(RegistrationRequest request) throws TransitionNotExecutableException, NoSuchAlgorithmException {
Case pluginCase = createOrUpdatePluginCase(request, Optional.empty());
pluginCase = doActivation(pluginCase);
return inject(pluginCase, "registered");
}
private String activate(Case pluginCase, RegistrationRequest request) throws TransitionNotExecutableException,
- PluginIsAlreadyActiveException {
+ PluginIsAlreadyActiveException, NoSuchAlgorithmException {
if (isPluginActive(pluginCase)) {
throw new PluginIsAlreadyActiveException(String.format("Plugin with identifier [%s] is already active. Plugin must be inactive.",
request.getIdentifier()));
}
- pluginInjector.uninject(pluginCase); // remove potentially outdated meta classes
+ pluginInjector.uninject(pluginCase); // remove potentially outdated meta data
pluginCase = createOrUpdatePluginCase(request, Optional.of(pluginCase));
pluginCase = doActivation(pluginCase);
return inject(pluginCase, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
@@ -255,7 +256,7 @@ private String inject(Case plugin, String state) {
return responseMsg;
}
- private Case createOrUpdatePluginCase(RegistrationRequest request, Optional pluginCaseOpt) {
+ private Case createOrUpdatePluginCase(RegistrationRequest request, Optional pluginCaseOpt) throws NoSuchAlgorithmException {
Set createdCaseIds = new HashSet<>();
LoggedUser loggedUser = userService.getLoggedOrSystem().transformToLoggedUser();
@@ -296,7 +297,8 @@ private Case createOrUpdatePluginCase(RegistrationRequest request, Optional entryPoints, LoggedUser loggedUser, List existingEpCases) {
+ private CreateOrUpdateOutcome createOrUpdateEntryPointCases(List entryPoints, LoggedUser loggedUser,
+ List existingEpCases) throws NoSuchAlgorithmException {
CreateOrUpdateOutcome outcome = new CreateOrUpdateOutcome();
try {
@@ -344,12 +346,19 @@ private GetOrCreateOutcome getOrCreateEntryPointCase(EntryPoint ep, LoggedUser l
}
private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, LoggedUser loggedUser,
- List existingMethodCases) {
+ List existingMethodCases) throws NoSuchAlgorithmException {
CreateOrUpdateOutcome outcome = new CreateOrUpdateOutcome();
try {
for (com.netgrif.pluginlibrary.core.Method method : entryPoint.getMethodsList()) {
- GetOrCreateOutcome methodOutcome = getOrCreateMethodCase(method, loggedUser, existingMethodCases);
+ List argTypesAsString = method.getArgsList().stream()
+ .map(arg -> {
+ Class> clazz = (Class>) SerializationUtils.deserialize(arg.toByteArray());
+ assert clazz != null;
+ return clazz.getName();
+ })
+ .collect(Collectors.toList());
+ GetOrCreateOutcome methodOutcome = getOrCreateMethodCase(method, loggedUser, argTypesAsString, existingMethodCases);
Case methodCase = methodOutcome.getSubjectCase();
if (methodOutcome.isNew()) {
@@ -361,15 +370,10 @@ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, L
Map> dataToSet = new HashMap<>();
dataToSet.put(METHOD_NAME_FIELD_ID, Map.of("value", method.getName(),
"type", FieldType.TEXT.getName()));
- List argTypesAsString = method.getArgsList().stream()
- .map(arg -> {
- Class> clazz = (Class>) SerializationUtils.deserialize(arg.toByteArray());
- assert clazz != null;
- return clazz.getName();
- })
- .collect(Collectors.toList());
dataToSet.put(METHOD_ARGUMENTS_FIELD_ID, Map.of("value", argTypesAsString, "type",
FieldType.STRING_COLLECTION.getName()));
+ dataToSet.put(METHOD_HASHED_SIGNATURE_FIELD_ID, Map.of("value", methodOutcome.getAdditionalData(),
+ "type", FieldType.TEXT.getName()));
String taskId = findTaskIdInCase(methodCase, METHOD_DETAIL_TRANS_ID);
dataService.setData(taskId, ImportHelper.populateDatasetAsObjects(dataToSet));
@@ -382,13 +386,16 @@ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, L
}
}
- private GetOrCreateOutcome getOrCreateMethodCase(Method method, LoggedUser loggedUser, List existingMethodCases) {
+ private GetOrCreateOutcome getOrCreateMethodCase(Method method, LoggedUser loggedUser, List argTypes,
+ List existingMethodCases)
+ throws NoSuchAlgorithmException {
+ String hashedSignature = PluginUtils.hashMethodSignature(method.getName(), argTypes);
Optional methodCaseOpt = existingMethodCases.stream()
- .filter((aCase) -> getMethodName(aCase).equals(method.getName()))
+ .filter((aCase) -> getMethodSignatureHash(aCase).equals(hashedSignature))
.findFirst();
Case methodCase = methodCaseOpt.orElseGet(() -> workflowService.createCaseByIdentifier(METHOD_PROCESS_IDENTIFIER,
method.getName(), "", loggedUser).getCase());
- return new GetOrCreateOutcome(methodCase, methodCaseOpt.isEmpty());
+ return new GetOrCreateOutcome(methodCase, methodCaseOpt.isEmpty(), hashedSignature);
}
private void removePluginCase(Case pluginCase) {
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
index b9d198d3b2d..32a3e5bb688 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
@@ -16,6 +16,7 @@ public class PluginConstants {
public static final String ENTRY_POINT_NAME_FIELD_ID = "name";
public static final String METHOD_NAME_FIELD_ID = "name";
public static final String METHOD_ARGUMENTS_FIELD_ID = "arguments";
+ public static final String METHOD_HASHED_SIGNATURE_FIELD_ID = "hashed_signature";
public static final String PLUGIN_ACTIVATE_TRANS_ID = "activate";
public static final String PLUGIN_DEACTIVATE_TRANS_ID = "deactivate";
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
index 031750742eb..1b08d09f8d5 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
@@ -12,6 +12,9 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -145,6 +148,13 @@ public static List getMethodArguments(Case methodCase) {
return (List) methodCase.getFieldValue(PluginConstants.METHOD_ARGUMENTS_FIELD_ID);
}
+ /**
+ * Finds method signature hash from the dataSet of the provided method case
+ * */
+ public static String getMethodSignatureHash(Case methodCase) {
+ return (String) methodCase.getFieldValue(PluginConstants.METHOD_HASHED_SIGNATURE_FIELD_ID);
+ }
+
/**
* Assigns task by provided task id. If the task is already assigned, it cancels the task and tries again.
*
@@ -165,4 +175,31 @@ public AssignTaskEventOutcome safelyAssignTask(String taskId) throws TransitionN
return taskService.assignTask(aTask, user);
}
}
+
+ /**
+ * Creates SHA-256 hash of method name and list of argument types.
+ *
+ * @param methodName name of the method
+ * @param argTypes list of argument types as string
+ *
+ * @return SHA-256 string hash of the provided input
+ * */
+ public static String hashMethodSignature(String methodName, List argTypes) throws NoSuchAlgorithmException {
+ String original = methodName + argTypes;
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ byte[] encodedHash = digest.digest(original.getBytes(StandardCharsets.UTF_8));
+ return bytesToHex(encodedHash);
+ }
+
+ private static String bytesToHex(byte[] hash) {
+ StringBuilder hexString = new StringBuilder(2 * hash.length);
+ for (byte b : hash) {
+ String hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ return hexString.toString();
+ }
}
diff --git a/src/main/resources/petriNets/engine-processes/plugin/method.xml b/src/main/resources/petriNets/engine-processes/plugin/method.xml
index 7d3491907bb..0dc4212a386 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/method.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/method.xml
@@ -15,6 +15,10 @@
argumentsMethod arguments
+
+ hashed_signature
+
+
NázovArgumenty funkcie
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
index ebd470e8fbd..d04a0aed0e2 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
@@ -38,7 +38,7 @@ public static void registerOrActivatePlugin() {
}
@SuppressWarnings("ResultOfMethodCallIgnored")
- public static void registerWithCustomRequest(RegistrationRequest request) {
+ public static void registerOrActivateWithCustomRequest(RegistrationRequest request) {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8081)
.usePlaintext()
.build();
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index 6a1cf59018a..685c47244ff 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -1,5 +1,6 @@
package com.netgrif.application.engine.integrations.plugins.service;
+import com.google.protobuf.ByteString;
import com.netgrif.application.engine.TestHelper;
import com.netgrif.application.engine.auth.domain.LoggedUser;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
@@ -16,6 +17,7 @@
import com.netgrif.pluginlibrary.core.*;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
+import org.apache.commons.lang3.SerializationUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,6 +27,7 @@
import org.springframework.test.context.ActiveProfiles;
import java.util.List;
+import java.util.Objects;
import static com.netgrif.application.engine.integration.plugins.utils.PluginUtils.*;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -160,7 +163,7 @@ public void testRegisterDeactivateEditAndActivate() throws InterruptedException,
MockPlugin.registerOrActivatePlugin();
- testIsNotInjected(); // will not assert if the old meta classes are uninjected
+ testIsNotInjected(); // will not assert if the old metadata are uninjected
pluginCase = workflowService.findOne(pluginCase.getStringId());
assert getPluginName(pluginCase).equals("pluginNewName");
@@ -194,6 +197,47 @@ public void testUnregisterMissing() {
assertThrows(StatusRuntimeException.class, MockPlugin::unregisterPlugin);
}
+
+ @Test
+ public void testRegistrationWithOverloadingMethods() throws InterruptedException {
+ String pluginIdentifier = "identifier";
+
+ RegistrationRequest req = RegistrationRequest.newBuilder()
+ .setIdentifier(pluginIdentifier)
+ .setName("name")
+ .setUrl("url")
+ .setPort(1)
+ .addEntryPoints(EntryPoint.newBuilder()
+ .setName("name")
+ .addMethods(Method.newBuilder()
+ .setName("method1")
+ .addArgs(ByteString.copyFrom(SerializationUtils.serialize(Integer.class)))
+ .build())
+ .addMethods(Method.newBuilder()
+ .setName("method1")
+ .addArgs(ByteString.copyFrom(SerializationUtils.serialize(Double.class)))
+ .build())
+ .build())
+ .build();
+
+ MockPlugin.registerOrActivateWithCustomRequest(req);
+
+ Case entryPointCase = workflowService.searchOne(QCase.case$.processIdentifier.eq("entry_point"));
+ List methodCases = utils.getEntryPointMethods(entryPointCase);
+ List methodCaseIds = getEntryPointMethodIds(entryPointCase);
+ assert methodCases.size() == 2;
+ assert !Objects.equals(getMethodSignatureHash(methodCases.get(0)), getMethodSignatureHash(methodCases.get(1)));
+
+ Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
+
+ MockPlugin.deactivatePluginWithCustomRequest(DeactivationRequest.newBuilder().setIdentifier(pluginIdentifier).build());
+ MockPlugin.registerOrActivateWithCustomRequest(req);
+ entryPointCase = workflowService.findOne(entryPointCase.getStringId());
+ assert methodCaseIds.equals(getEntryPointMethodIds(entryPointCase));
+ assert utils.getEntryPointMethods(entryPointCase).size() == 2;
+ assert workflowService.searchAll(QCase.case$.processIdentifier.eq("method")).getTotalElements() == 2;
+ }
+
@Test
public void testRegistrationWithCorruptIdentifier() {
RegistrationRequest corruptReq = RegistrationRequest.newBuilder()
@@ -259,7 +303,7 @@ public void testRegistrationWithCorruptMethodName() {
}
private void assertCorruptRegistrationRequest(RegistrationRequest corruptReq) {
- StatusRuntimeException e = assertThrows(StatusRuntimeException.class, () -> MockPlugin.registerWithCustomRequest(corruptReq));
+ StatusRuntimeException e = assertThrows(StatusRuntimeException.class, () -> MockPlugin.registerOrActivateWithCustomRequest(corruptReq));
assert e.getStatus().getCode().value() == Status.INVALID_ARGUMENT.getCode().value();
assertIfAnyCaseExists();
}
From 27c237c851043de3e9a204aa4e2edea90068e3c0 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Fri, 17 May 2024 12:08:37 +0200
Subject: [PATCH 30/92] [NAE-1546] Plugin library - add roles to plugin nets -
fix PluginRegistrationServiceTest
---
.../engine-processes/plugin/entry_point.xml | 56 +++++++++++++++++++
.../engine-processes/plugin/method.xml | 32 +++++++++++
.../engine-processes/plugin/plugin.xml | 50 +++++++++++++++++
.../PluginRegistrationServiceTest.java | 4 +-
4 files changed, 140 insertions(+), 2 deletions(-)
diff --git a/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml b/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
index d2afcdf80c9..71a5e366165 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/entry_point.xml
@@ -7,6 +7,62 @@
truefalsefalse
+
+ system
+
+ true
+ true
+ true
+
+
+
+ admin
+
+ false
+ false
+ true
+
+
+
+ default
+
+ false
+ false
+ true
+
+
+
+ system
+
+ true
+ true
+ true
+
+
+
+ admin
+
+ true
+ true
+ true
+
+
+
+ default
+
+ false
+ false
+ true
+
+
+
+ system
+ System
+
+
+ admin
+ Admin
+ nameName
diff --git a/src/main/resources/petriNets/engine-processes/plugin/method.xml b/src/main/resources/petriNets/engine-processes/plugin/method.xml
index 0dc4212a386..e27d7e40a9b 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/method.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/method.xml
@@ -7,6 +7,38 @@
truefalsefalse
+
+ system
+
+ true
+ true
+ true
+
+
+
+ admin
+
+ false
+ false
+ true
+
+
+
+ default
+
+ false
+ false
+ true
+
+
+
+ system
+ System
+
+
+ admin
+ Admin
+ nameName
diff --git a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
index 2b727173d7d..6d60a688538 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
@@ -7,6 +7,38 @@
truefalsefalse
+
+ system
+
+ true
+ true
+ true
+
+
+
+ admin
+
+ false
+ false
+ true
+
+
+
+ default
+
+ false
+ false
+ true
+
+
+
+ system
+ System
+
+
+ admin
+ Admin
+ identifierIdentifier
@@ -160,6 +192,15 @@
624304
+
+ admin
+
+ true
+ true
+ true
+ true
+
+ onFinish_activate
@@ -175,6 +216,15 @@
624432
+
+ admin
+
+ true
+ true
+ true
+ true
+
+ onFinish_deactivate
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index 685c47244ff..40699a0c612 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -204,11 +204,11 @@ public void testRegistrationWithOverloadingMethods() throws InterruptedException
RegistrationRequest req = RegistrationRequest.newBuilder()
.setIdentifier(pluginIdentifier)
- .setName("name")
+ .setName("pluginName")
.setUrl("url")
.setPort(1)
.addEntryPoints(EntryPoint.newBuilder()
- .setName("name")
+ .setName("epName")
.addMethods(Method.newBuilder()
.setName("method1")
.addArgs(ByteString.copyFrom(SerializationUtils.serialize(Integer.class)))
From 826fca01be8ec6fed5024f767152360fdc3996bc Mon Sep 17 00:00:00 2001
From: chvostek
Date: Fri, 17 May 2024 17:21:32 +0200
Subject: [PATCH 31/92] [NAE-1546] Plugin library - refactor PluginInjector -
add PluginInjector into ActionDelegate - fix PluginRunner - create
serialization method in PluginUtils - update activation/deactivation methods
in plugin.xml - fix arc in plugin.xml - fix and update tests
---
.../plugin/injector/PluginInjector.groovy | 13 ++---
.../logic/action/ActionDelegate.groovy | 4 ++
.../engine/startup/PluginRunner.groovy | 10 +++-
.../plugins/service/IPluginService.java | 2 +-
.../plugins/service/PluginService.java | 35 ++++++------
.../plugins/utils/PluginUtils.java | 26 +++++++++
.../engine-processes/plugin/plugin.xml | 6 ++-
.../plugins/mock/MockExecutionService.java | 2 +-
.../PluginRegistrationServiceTest.java | 4 +-
.../plugins/service/PluginServiceTest.java | 53 +------------------
10 files changed, 73 insertions(+), 82 deletions(-)
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 39e35bdb3b5..484eb6c3d21 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -7,16 +7,12 @@ import com.netgrif.application.engine.integration.plugins.service.PluginService
import com.netgrif.application.engine.integration.plugins.utils.PluginUtils
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate
import com.netgrif.application.engine.workflow.domain.Case
-import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
@Service
class PluginInjector {
- @Autowired
- protected IWorkflowService workflowService
-
@Autowired
protected PluginUtils utils
@@ -43,8 +39,10 @@ class PluginInjector {
MetaClass pluginMetaClass = PluginMeta.metaClass
List entryPointCases = utils.getPluginEntryPoints(pluginCase)
- String pluginIdentifier = PluginUtils.getPluginIdentifier(pluginCase)
+
String pluginName = PluginUtils.getPluginName(pluginCase)
+ String pluginUrl = PluginUtils.getPluginUrl(pluginCase)
+ int pluginPort = PluginUtils.getPluginPort(pluginCase)
entryPointCases.each { epCase ->
MetaClass entryPointMetaClass = EntryPointMeta.metaClass
@@ -53,13 +51,12 @@ class PluginInjector {
methodCases.each { methodCase ->
String methodName = PluginUtils.getMethodName(methodCase)
-
if (isRemoval) {
entryPointMetaClass[methodName] = null
} else {
- entryPointMetaClass[methodName] << { Serializable... args ->
+ entryPointMetaClass[methodName] = { Serializable... args ->
PluginService pluginService = ApplicationContextProvider.getBean("pluginService") as PluginService
- return pluginService.call(pluginIdentifier, epName, methodName, args)
+ return pluginService.call(pluginUrl, pluginPort, epName, methodName, args)
}
}
}
diff --git a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index efc9c44e4ab..11506e899bc 100644
--- a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -20,6 +20,7 @@ import com.netgrif.application.engine.export.service.interfaces.IExportService
import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService
import com.netgrif.application.engine.history.service.IHistoryService
import com.netgrif.application.engine.importer.service.FieldFactory
+import com.netgrif.application.engine.integration.plugin.injector.PluginInjector
import com.netgrif.application.engine.mail.domain.MailDraft
import com.netgrif.application.engine.mail.interfaces.IMailAttemptService
import com.netgrif.application.engine.mail.interfaces.IMailService
@@ -185,6 +186,9 @@ class ActionDelegate {
@Autowired
PublicViewProperties publicViewProperties
+ @Autowired
+ PluginInjector pluginInjector
+
FrontendActionOutcome Frontend
/**
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy b/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
index e80b63e4a2f..3ec21b6f5e4 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/PluginRunner.groovy
@@ -7,6 +7,9 @@ import groovy.util.logging.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
+import static com.netgrif.application.engine.integration.plugins.utils.PluginUtils.getPluginIdentifier
+import static com.netgrif.application.engine.integration.plugins.utils.PluginUtils.isPluginActive
+
@Slf4j
@Component
class PluginRunner extends AbstractOrderedCommandLineRunner {
@@ -34,11 +37,14 @@ class PluginRunner extends AbstractOrderedCommandLineRunner {
importPluginNets()
List plugins = pluginService.findAll()
- plugins.size()
log.info("Re-injecting ${plugins.size()} plugins from database into memory.")
plugins.each { plugin ->
- pluginInjector.inject(plugin)
+ if (isPluginActive(plugin)) {
+ pluginInjector.inject(plugin)
+ } else {
+ log.warn("Plugin with identifier [{}] is disabled and will not be injected.", getPluginIdentifier(plugin))
+ }
}
}
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
index b5b6ab951b3..4c8a216fa9b 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/IPluginService.java
@@ -12,7 +12,7 @@ public interface IPluginService {
String unregister(String identifier) throws IllegalArgumentException;
- Object call(String pluginId, String entryPoint, String method, Serializable... args) throws IllegalArgumentException;
+ Object call(String url, int port, String entryPoint, String method, Serializable... args) throws IllegalArgumentException;
String deactivate(String identifier) throws IllegalArgumentException;
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 33fb43ca40a..0143235080d 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -131,27 +131,19 @@ public String unregister(String identifier) {
/**
* Calls method with arguments of a specified entry point. Plugin must exist and be activated.
*
- * @param pluginId plugin identifier, that contains the method to be executed
+ * @param url URL of the plugin microservice
+ * @param port port of the plugin microservice
* @param entryPoint name of entry point in plugin, that contains the method to be executed
* @param method name of method to be executed
* @param args arguments to send to plugin method. All args should be the exact type of method input arguments type (not superclass, or subclass)
* @return the returned object of the executed plugin method
*/
@Override
- public Object call(String pluginId, String entryPoint, String method, Serializable... args) throws IllegalArgumentException {
- Optional pluginCaseOpt = findByIdentifier(pluginId);
- if (pluginCaseOpt.isEmpty()) {
- throw new IllegalArgumentException("Plugin with identifier \"" + pluginId + "\" cannot be found");
- }
- Case pluginCase = pluginCaseOpt.get();
- if (!isPluginActive(pluginCase)) {
- throw new IllegalArgumentException("Plugin with name \"" + getPluginName(pluginCase) + "\" is deactivated");
- }
- ManagedChannel channel = ManagedChannelBuilder.forAddress(getPluginUrl(pluginCase), getPluginPort(pluginCase))
+ public Object call(String url, int port, String entryPoint, String method, Serializable... args) throws IllegalArgumentException {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(url, port)
.usePlaintext()
.build();
- List argBytes = Arrays.stream(args).map(arg -> ByteString.copyFrom(
- Objects.requireNonNull(SerializationUtils.serialize(arg)))).collect(Collectors.toList());
+ List argBytes = Arrays.stream(args).map(PluginUtils::serializeObject).collect(Collectors.toList());
ExecutionServiceGrpc.ExecutionServiceBlockingStub stub = ExecutionServiceGrpc.newBlockingStub(channel);
ExecutionResponse responseMessage = stub.execute(ExecutionRequest.newBuilder()
.setEntryPoint(entryPoint)
@@ -159,7 +151,7 @@ public Object call(String pluginId, String entryPoint, String method, Serializab
.addAllArgs(argBytes)
.build());
channel.shutdownNow();
- return SerializationUtils.deserialize(responseMessage.getResponse().toByteArray());
+ return deserializeObject(responseMessage.getResponse());
}
/**
@@ -179,6 +171,7 @@ public String deactivate(String identifier) throws IllegalArgumentException {
try {
Task deactivateTask = utils.safelyAssignTask(taskId).getTask();
taskService.finishTask(deactivateTask, user);
+// pluginInjector.uninject(pluginOpt.get());
} catch (TransitionNotExecutableException e) {
throw new RuntimeException(e);
}
@@ -226,7 +219,12 @@ public Optional findByIdentifier(String identifier) {
private String register(RegistrationRequest request) throws TransitionNotExecutableException, NoSuchAlgorithmException {
Case pluginCase = createOrUpdatePluginCase(request, Optional.empty());
pluginCase = doActivation(pluginCase);
- return inject(pluginCase, "registered");
+
+ pluginInjector.inject(pluginCase);
+
+ String responseMsg = String.format("Plugin with identifier \"%s\" was registered", getPluginIdentifier(pluginCase));
+ log.info(responseMsg);
+ return responseMsg;
}
private String activate(Case pluginCase, RegistrationRequest request) throws TransitionNotExecutableException,
@@ -238,7 +236,10 @@ private String activate(Case pluginCase, RegistrationRequest request) throws Tra
pluginInjector.uninject(pluginCase); // remove potentially outdated meta data
pluginCase = createOrUpdatePluginCase(request, Optional.of(pluginCase));
pluginCase = doActivation(pluginCase);
- return inject(pluginCase, "activated"); // we must also re-inject the plugin in case of there is a change of entry points
+
+ String responseMsg = String.format("Plugin with identifier \"%s\" was activated.", getPluginIdentifier(pluginCase));
+ log.info(responseMsg);
+ return responseMsg;
}
private Case doActivation(Case pluginCase) throws TransitionNotExecutableException {
@@ -353,7 +354,7 @@ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, L
for (com.netgrif.pluginlibrary.core.Method method : entryPoint.getMethodsList()) {
List argTypesAsString = method.getArgsList().stream()
.map(arg -> {
- Class> clazz = (Class>) SerializationUtils.deserialize(arg.toByteArray());
+ Class> clazz = (Class>) deserializeObject(arg);
assert clazz != null;
return clazz.getName();
})
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
index 1b08d09f8d5..4834fb3f4e3 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
@@ -1,5 +1,6 @@
package com.netgrif.application.engine.integration.plugins.utils;
+import com.google.protobuf.ByteString;
import com.netgrif.application.engine.auth.domain.IUser;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.petrinet.domain.throwable.TransitionNotExecutableException;
@@ -11,12 +12,15 @@
import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
+import org.springframework.util.SerializationUtils;
+import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
@Component
@@ -176,6 +180,28 @@ public AssignTaskEventOutcome safelyAssignTask(String taskId) throws TransitionN
}
}
+ /**
+ * Serializes provided object into {@link ByteString}
+ *
+ * @param object object to be serialized
+ *
+ * @return serialized object into {@link ByteString}
+ * */
+ public static ByteString serializeObject(Serializable object) {
+ return ByteString.copyFrom(Objects.requireNonNull(SerializationUtils.serialize(object)));
+ }
+
+ /**
+ * Deserializes provided object as {@link ByteString} into {@link Object}
+ *
+ * @param object object to be deserialized
+ *
+ * @return deserialized object into {@link Object}
+ * */
+ public static Object deserializeObject(ByteString object) {
+ return SerializationUtils.deserialize(object.toByteArray());
+ }
+
/**
* Creates SHA-256 hash of method name and list of argument types.
*
diff --git a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
index 6d60a688538..cfdf9e1471a 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/plugin.xml
@@ -206,6 +206,8 @@
active: f.active;
+
+ pluginInjector.inject(useCase)
change active value { true }
@@ -230,6 +232,8 @@
active: f.active;
+
+ pluginInjector.uninject(useCase)
change active value { false }
@@ -334,7 +338,7 @@
a8
- regular
+ readinitializeddetail1
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java
index 713a4d0beb1..7358badaefa 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockExecutionService.java
@@ -17,7 +17,7 @@
@Service
public class MockExecutionService extends ExecutionServiceGrpc.ExecutionServiceImplBase {
- private static final int port = 8090;
+ public static final int port = 8090;
private Server server;
public ExecutionRequest lastExecutionRequest;
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index 40699a0c612..36bbe9b91b0 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -95,6 +95,7 @@ public void testRegistrationDeactivationAndActivation() throws InterruptedExcept
List methodArgs = getMethodArguments(methodCase);
assert methodArgs.size() == 1;
assert methodArgs.get(0).equals(MockPlugin.mockArgumentType.getName());
+ testIsInjected();
Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
MockPlugin.deactivatePlugin();
@@ -103,7 +104,7 @@ public void testRegistrationDeactivationAndActivation() throws InterruptedExcept
assert !PluginUtils.isPluginActive(pluginCase);
assert !pluginCase.getActivePlaces().containsKey("active");
assert pluginCase.getActivePlaces().get("inactive").equals(1);
- testIsInjected();
+ testIsNotInjected();
MockPlugin.registerOrActivatePlugin();
pluginCase = workflowService.findOne(pluginCase.getStringId());
@@ -111,6 +112,7 @@ public void testRegistrationDeactivationAndActivation() throws InterruptedExcept
assert PluginUtils.isPluginActive(pluginCase);
assert pluginCase.getActivePlaces().get("active").equals(1);
assert !pluginCase.getActivePlaces().containsKey("inactive");
+ testIsInjected();
}
@Test
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
index e5723584df5..99b1d400677 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginServiceTest.java
@@ -1,12 +1,8 @@
package com.netgrif.application.engine.integrations.plugins.service;
import com.netgrif.application.engine.TestHelper;
-import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.integration.plugins.service.IPluginService;
import com.netgrif.application.engine.integrations.plugins.mock.MockExecutionService;
-import com.netgrif.application.engine.startup.ImportHelper;
-import com.netgrif.application.engine.workflow.domain.Case;
-import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import com.netgrif.pluginlibrary.core.ExecutionRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -14,59 +10,27 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
-import static com.netgrif.application.engine.integration.plugins.utils.PluginConstants.*;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
@SpringBootTest
@ActiveProfiles({"test"})
public class PluginServiceTest {
- @Autowired
- private IWorkflowService workflowService;
-
- @Autowired
- private IUserService userService;
-
@Autowired
private TestHelper testHelper;
- @Autowired
- private ImportHelper helper;
-
@Autowired
private IPluginService pluginService;
@Autowired
private MockExecutionService mockExecutionService;
- private static final String pluginIdentifier = "mock_plugin";
- private static final int ELASTIC_WAIT_TIME_IN_MS = 2000;
-
@BeforeEach
public void before() {
testHelper.truncateDbs();
- helper.createNet("engine-processes/plugin/plugin.xml");
- }
-
- private void createMockPluginCase(boolean isActive) {
- Case pluginCase = workflowService.createCaseByIdentifier("plugin", "", "",
- userService.getSystem().transformToLoggedUser()).getCase();
-
- pluginCase.getDataSet().get(PLUGIN_IDENTIFIER_FIELD_ID).setValue(pluginIdentifier);
- pluginCase.getDataSet().get(PLUGIN_NAME_FIELD_ID).setValue("mockPlugin");
- pluginCase.getDataSet().get(PLUGIN_URL_FIELD_ID).setValue("localhost");
- pluginCase.getDataSet().get(PLUGIN_PORT_FIELD_ID).setValue(8090f);
- pluginCase.getDataSet().get(PLUGIN_ACTIVE_FIELD_ID).setValue(isActive);
-
- workflowService.save(pluginCase);
}
@Test
- public void testCallRequestAndResponse() throws InterruptedException {
- createMockPluginCase(true);
- Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
-
- Object response = pluginService.call(pluginIdentifier, "mockEP", "mockMethod", "mockArg1", "mockArg2");
+ public void testCallRequestAndResponse() {
+ Object response = pluginService.call("localhost", MockExecutionService.port, "mockEP", "mockMethod", "mockArg1", "mockArg2");
ExecutionRequest request = mockExecutionService.lastExecutionRequest;
@@ -76,17 +40,4 @@ public void testCallRequestAndResponse() throws InterruptedException {
assert response.equals("mockResponse");
}
-
- @Test
- public void testCallMissingPlugin() {
- assertThrows(IllegalArgumentException.class, () -> pluginService.call("missingIdentifier", "missingEP", "missingMethod"));
- }
-
- @Test
- public void testCallDeactivatedPlugin() throws InterruptedException {
- createMockPluginCase(false);
- Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
-
- assertThrows(IllegalArgumentException.class, () -> pluginService.call(pluginIdentifier, "mockEP", "mockMethod"));
- }
}
From 4020b6e14b0b29f27d684995d6e9e9fe6844967c Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 8 Jul 2024 10:02:09 +0200
Subject: [PATCH 32/92] [NAE-1546] Plugin library - add return type to method -
optimize PluginService.createOrUpdateMethodCases - update tests
---
.../plugins/service/PluginService.java | 16 +++++----------
.../plugins/utils/PluginConstants.java | 1 +
.../plugins/utils/PluginUtils.java | 7 +++++++
src/main/proto/RegistrationService.proto | 3 ++-
.../engine-processes/plugin/method.xml | 20 +++++++++++++++++++
.../integrations/plugins/mock/MockPlugin.java | 4 +++-
.../PluginRegistrationServiceTest.java | 7 +++----
7 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 0143235080d..11e44676b42 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -32,7 +32,6 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
-import org.springframework.util.SerializationUtils;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -171,7 +170,7 @@ public String deactivate(String identifier) throws IllegalArgumentException {
try {
Task deactivateTask = utils.safelyAssignTask(taskId).getTask();
taskService.finishTask(deactivateTask, user);
-// pluginInjector.uninject(pluginOpt.get());
+ pluginInjector.uninject(pluginOpt.get());
} catch (TransitionNotExecutableException e) {
throw new RuntimeException(e);
}
@@ -352,14 +351,7 @@ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, L
try {
for (com.netgrif.pluginlibrary.core.Method method : entryPoint.getMethodsList()) {
- List argTypesAsString = method.getArgsList().stream()
- .map(arg -> {
- Class> clazz = (Class>) deserializeObject(arg);
- assert clazz != null;
- return clazz.getName();
- })
- .collect(Collectors.toList());
- GetOrCreateOutcome methodOutcome = getOrCreateMethodCase(method, loggedUser, argTypesAsString, existingMethodCases);
+ GetOrCreateOutcome methodOutcome = getOrCreateMethodCase(method, loggedUser, method.getArgsList(), existingMethodCases);
Case methodCase = methodOutcome.getSubjectCase();
if (methodOutcome.isNew()) {
@@ -371,8 +363,10 @@ private CreateOrUpdateOutcome createOrUpdateMethodCases(EntryPoint entryPoint, L
Map> dataToSet = new HashMap<>();
dataToSet.put(METHOD_NAME_FIELD_ID, Map.of("value", method.getName(),
"type", FieldType.TEXT.getName()));
- dataToSet.put(METHOD_ARGUMENTS_FIELD_ID, Map.of("value", argTypesAsString, "type",
+ dataToSet.put(METHOD_ARGUMENTS_FIELD_ID, Map.of("value", method.getArgsList(), "type",
FieldType.STRING_COLLECTION.getName()));
+ dataToSet.put(METHOD_RETURN_TYPE_FIELD_ID, Map.of("value", method.getReturnType(), "type",
+ FieldType.TEXT.getName()));
dataToSet.put(METHOD_HASHED_SIGNATURE_FIELD_ID, Map.of("value", methodOutcome.getAdditionalData(),
"type", FieldType.TEXT.getName()));
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
index 32a3e5bb688..e0495127370 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginConstants.java
@@ -16,6 +16,7 @@ public class PluginConstants {
public static final String ENTRY_POINT_NAME_FIELD_ID = "name";
public static final String METHOD_NAME_FIELD_ID = "name";
public static final String METHOD_ARGUMENTS_FIELD_ID = "arguments";
+ public static final String METHOD_RETURN_TYPE_FIELD_ID = "return_type";
public static final String METHOD_HASHED_SIGNATURE_FIELD_ID = "hashed_signature";
public static final String PLUGIN_ACTIVATE_TRANS_ID = "activate";
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
index 4834fb3f4e3..06ef60da347 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/utils/PluginUtils.java
@@ -152,6 +152,13 @@ public static List getMethodArguments(Case methodCase) {
return (List) methodCase.getFieldValue(PluginConstants.METHOD_ARGUMENTS_FIELD_ID);
}
+ /**
+ * Finds method arguments from the dataSet of the provided method case
+ * */
+ public static String getMethodReturnType(Case methodCase) {
+ return (String) methodCase.getFieldValue(PluginConstants.METHOD_RETURN_TYPE_FIELD_ID);
+ }
+
/**
* Finds method signature hash from the dataSet of the provided method case
* */
diff --git a/src/main/proto/RegistrationService.proto b/src/main/proto/RegistrationService.proto
index f58badafde8..98817e1efc7 100644
--- a/src/main/proto/RegistrationService.proto
+++ b/src/main/proto/RegistrationService.proto
@@ -5,7 +5,8 @@ package com.netgrif.pluginlibrary.core;
message Method {
string name = 1;
- repeated bytes args = 2;
+ repeated string args = 2;
+ string returnType = 3;
}
message EntryPoint {
diff --git a/src/main/resources/petriNets/engine-processes/plugin/method.xml b/src/main/resources/petriNets/engine-processes/plugin/method.xml
index e27d7e40a9b..0aaf5a2b087 100644
--- a/src/main/resources/petriNets/engine-processes/plugin/method.xml
+++ b/src/main/resources/petriNets/engine-processes/plugin/method.xml
@@ -47,6 +47,10 @@
argumentsMethod arguments
+
+ return_type
+ Output type
+
hashed_signature
@@ -54,11 +58,13 @@
NázovArgumenty funkcie
+ Typ výstupu funkcieDetailNameMethodenargumente
+ Methode AusgabetypDetail
@@ -98,6 +104,20 @@
outline
+
+ return_type
+
+ visible
+
+
+ 0
+ 2
+ 1
+ 4
+ material
+ outline
+
+
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
index d04a0aed0e2..1bdd44a513c 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/mock/MockPlugin.java
@@ -13,6 +13,7 @@ public class MockPlugin {
public static String mockEntryPointName = "mockEntryPoint";
public static String mockMethodName = "mockMethodName";
public static final Class mockArgumentType = String.class;
+ public static final Class mockOutputType = Double.class;
@SuppressWarnings("ResultOfMethodCallIgnored")
public static void registerOrActivatePlugin() {
@@ -30,7 +31,8 @@ public static void registerOrActivatePlugin() {
.setName(mockEntryPointName)
.addMethods(Method.newBuilder()
.setName(mockMethodName)
- .addArgs(ByteString.copyFrom(SerializationUtils.serialize(mockArgumentType)))
+ .addArgs(mockArgumentType.getName())
+ .setReturnType(mockOutputType.getName())
.build())
.build())
.build());
diff --git a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
index 36bbe9b91b0..b5c94cff209 100644
--- a/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/integrations/plugins/service/PluginRegistrationServiceTest.java
@@ -1,6 +1,5 @@
package com.netgrif.application.engine.integrations.plugins.service;
-import com.google.protobuf.ByteString;
import com.netgrif.application.engine.TestHelper;
import com.netgrif.application.engine.auth.domain.LoggedUser;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
@@ -17,7 +16,6 @@
import com.netgrif.pluginlibrary.core.*;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
-import org.apache.commons.lang3.SerializationUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -95,6 +93,7 @@ public void testRegistrationDeactivationAndActivation() throws InterruptedExcept
List methodArgs = getMethodArguments(methodCase);
assert methodArgs.size() == 1;
assert methodArgs.get(0).equals(MockPlugin.mockArgumentType.getName());
+ assert getMethodReturnType(methodCase).equals(MockPlugin.mockOutputType.getName());
testIsInjected();
Thread.sleep(ELASTIC_WAIT_TIME_IN_MS);
@@ -213,11 +212,11 @@ public void testRegistrationWithOverloadingMethods() throws InterruptedException
.setName("epName")
.addMethods(Method.newBuilder()
.setName("method1")
- .addArgs(ByteString.copyFrom(SerializationUtils.serialize(Integer.class)))
+ .addArgs(Integer.class.getName())
.build())
.addMethods(Method.newBuilder()
.setName("method1")
- .addArgs(ByteString.copyFrom(SerializationUtils.serialize(Double.class)))
+ .addArgs(Double.class.getName())
.build())
.build())
.build();
From 60ea2bdfb973b5f79ab4d49a95aa77bf302fd923 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Mon, 8 Jul 2024 13:51:18 +0200
Subject: [PATCH 33/92] [NAE-1546] Plugin library - rework plugin execution
definition - remove unused method in PluginService
---
.../engine/integration/plugin/injector/PluginHolder.java | 7 +++++++
.../integration/plugin/injector/PluginInjector.groovy | 4 ++--
.../domain/dataset/logic/action/ActionDelegate.groovy | 5 +++++
.../engine/integration/plugins/service/PluginService.java | 8 --------
4 files changed, 14 insertions(+), 10 deletions(-)
create mode 100644 src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginHolder.java
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginHolder.java b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginHolder.java
new file mode 100644
index 00000000000..59abff4fa0f
--- /dev/null
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginHolder.java
@@ -0,0 +1,7 @@
+package com.netgrif.application.engine.integration.plugin.injector;
+
+/**
+ * A class where the plugins are injected. The plugins are injected into metaclasses
+ * */
+public class PluginHolder {
+}
diff --git a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
index 484eb6c3d21..f791fe5e998 100644
--- a/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/integration/plugin/injector/PluginInjector.groovy
@@ -35,7 +35,7 @@ class PluginInjector {
}
protected void updateMetaClasses(Case pluginCase, boolean isRemoval) {
- MetaClass actionDelegateMeta = ActionDelegate.metaClass
+ MetaClass keyClassMeta = PluginHolder.metaClass
MetaClass pluginMetaClass = PluginMeta.metaClass
List entryPointCases = utils.getPluginEntryPoints(pluginCase)
@@ -62,6 +62,6 @@ class PluginInjector {
}
pluginMetaClass[epName] = isRemoval ? null : new EntryPointMeta()
}
- actionDelegateMeta[pluginName] = isRemoval ? null : new PluginMeta()
+ keyClassMeta[pluginName] = isRemoval ? null : new PluginMeta()
}
}
diff --git a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index 11506e899bc..eb15d26c87c 100644
--- a/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -60,6 +60,7 @@ import com.netgrif.application.engine.workflow.service.interfaces.*
import com.netgrif.application.engine.workflow.web.responsebodies.MessageResource
import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference
import com.querydsl.core.types.Predicate
+import groovy.time.TimeCategory
import groovy.transform.NamedVariant
import org.bson.types.ObjectId
import org.quartz.Scheduler
@@ -73,6 +74,7 @@ import org.springframework.core.io.FileSystemResource
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
+import com.netgrif.application.engine.integration.plugin.injector.PluginHolder
import java.text.Normalizer
import java.time.ZoneId
@@ -191,6 +193,8 @@ class ActionDelegate {
FrontendActionOutcome Frontend
+ PluginHolder Plugin
+
/**
* Reference of case and task in which current action is taking place.
*/
@@ -212,6 +216,7 @@ class ActionDelegate {
this.initTransitionsMap(action.transitionIds)
this.outcomes = new ArrayList<>()
this.Frontend = new FrontendActionOutcome(this.useCase, this.task, this.outcomes)
+ this.Plugin = new PluginHolder()
}
def initFieldsMap(Map fieldIds) {
diff --git a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
index 11e44676b42..8d13ff395ef 100644
--- a/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
+++ b/src/main/java/com/netgrif/application/engine/integration/plugins/service/PluginService.java
@@ -248,14 +248,6 @@ private Case doActivation(Case pluginCase) throws TransitionNotExecutableExcepti
return taskService.finishTask(activateTask, user).getCase();
}
- private String inject(Case plugin, String state) {
- pluginInjector.inject(plugin);
-
- String responseMsg = String.format("Plugin with identifier \"%s\" was %s.", getPluginIdentifier(plugin), state);
- log.info(responseMsg);
- return responseMsg;
- }
-
private Case createOrUpdatePluginCase(RegistrationRequest request, Optional pluginCaseOpt) throws NoSuchAlgorithmException {
Set createdCaseIds = new HashSet<>();
LoggedUser loggedUser = userService.getLoggedOrSystem().transformToLoggedUser();
From 6ce083d437e0edf5d8e4762f1672a62393440b63 Mon Sep 17 00:00:00 2001
From: Martin Smetanka
Date: Wed, 29 Jan 2025 14:09:58 +0100
Subject: [PATCH 34/92] [NAE-2045] Event log as event system module - Events
now are subclass of EventObject - EventAction is now omitted in registration
of Listener - Added another Elastic cluster for storing EventLogs - Saving
via HistoryService is replaced by listening to events - Added changes to
Events and their corresponding EventLog objects for better Event to EventLog
projection
---
docker-compose.yml | 20 +
.../ElasticsearchConfiguration.java | 39 +-
.../ElasticsearchHistoryConfiguration.java | 20 +
.../event/dispatchers/AuthDispatcher.java | 37 ++
.../event/dispatchers/CaseDispatcher.java | 31 +-
.../event/dispatchers/DataDispatcher.java | 21 +-
.../event/dispatchers/ProcessDispatcher.java | 21 +-
.../event/dispatchers/TaskDispatcher.java | 84 ++-
.../event/dispatchers/UserDispatcher.java | 57 +--
.../common/AbstractDispatcher.java | 136 +++--
.../dispatchers/common/DispatchMethod.java | 6 -
.../common/RegisteredListener.java | 28 +-
.../service/DispatcherService.java | 7 +
.../service/IDispatcherService.java | 4 +
.../engine/event/events/EventAction.java | 4 +-
.../engine/event/events/data/DataEvent.java | 27 +
.../event/events/data/GetDataEvent.java | 8 +-
.../event/events/data/SetDataEvent.java | 9 +-
.../events/petrinet/ProcessDeployEvent.java | 2 +
.../event/events/task/AssignTaskEvent.java | 9 +
.../event/events/task/CancelTaskEvent.java | 6 +
.../event/events/task/CreateTaskEvent.java | 5 +
.../event/events/task/DelegateTaskEvent.java | 15 +
.../event/events/task/FinishTaskEvent.java | 5 +
.../engine/event/events/task/TaskEvent.java | 16 +
.../event/listeners/AuthEventListener.java | 39 +-
.../listeners/ContextEditingListener.java | 18 +-
.../engine/event/listeners/Listener.java | 56 +-
.../EventLogRepositoryConfiguration.java | 9 +
.../history/domain/baseevent/EventLog.java | 14 +-
.../repository/EventLogRepository.java | 5 +-
.../domain/caseevents/CreateCaseEventLog.java | 15 +-
.../domain/caseevents/DeleteCaseEventLog.java | 13 +-
.../CreateCaseEventLogRepository.java | 5 +-
.../DeleteCaseEventLogRepository.java | 5 +-
.../domain/dataevents/GetDataEventLog.java | 7 +-
.../domain/dataevents/SetDataEventLog.java | 8 +-
.../repository/GetDataEventLogRepository.java | 5 +-
.../repository/SetDataEventLogRepository.java | 4 +-
.../DeletePetriNetEventLog.java | 6 +-
.../ImportPetriNetEventLog.java | 7 +
.../DeletePetriNetEventLogRepository.java | 4 +-
.../ImportPetriNetEventLogRepository.java | 4 +-
.../domain/taskevents/AssignTaskEventLog.java | 10 +-
.../domain/taskevents/CancelTaskEventLog.java | 7 +-
.../domain/taskevents/CreateTaskEventLog.java | 22 +
.../taskevents/DelegateTaskEventLog.java | 8 +-
.../domain/taskevents/FinishTaskEventLog.java | 8 +-
.../AssignTaskEventLogRepository.java | 5 +-
.../CancelTaskEventLogRepository.java | 8 +-
.../CreateTaskEventLogRepository.java | 10 +
.../DelegateTaskEventLogRepository.java | 4 +-
.../FinishTaskEventLogRepository.java | 4 +-
.../history/service/HistoryService.java | 484 +++++++++---------
.../service/listener/CaseEventListener.java | 46 ++
.../service/listener/UserEventListener.java | 64 +--
.../engine/workflow/service/DataService.java | 6 +-
.../engine/workflow/service/TaskService.java | 30 +-
58 files changed, 975 insertions(+), 582 deletions(-)
create mode 100644 src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java
create mode 100644 src/main/java/com/netgrif/application/engine/event/dispatchers/AuthDispatcher.java
delete mode 100644 src/main/java/com/netgrif/application/engine/event/dispatchers/common/DispatchMethod.java
create mode 100644 src/main/java/com/netgrif/application/engine/event/dispatchers/service/DispatcherService.java
create mode 100644 src/main/java/com/netgrif/application/engine/event/dispatchers/service/IDispatcherService.java
create mode 100644 src/main/java/com/netgrif/application/engine/event/events/data/DataEvent.java
create mode 100644 src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java
create mode 100644 src/main/java/com/netgrif/application/engine/history/domain/taskevents/CreateTaskEventLog.java
create mode 100644 src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CreateTaskEventLogRepository.java
create mode 100644 src/main/java/com/netgrif/application/engine/history/service/listener/CaseEventListener.java
diff --git a/docker-compose.yml b/docker-compose.yml
index 3e275c95c1a..cf4c1e594e5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -33,6 +33,26 @@ services:
reservations:
cpus: "0.5"
memory: "512M"
+# Zmensit resources
+ docker-elastic-history:
+ image: elasticsearch:8.15.3
+ environment:
+ - cluster.name=elasticsearch
+ - discovery.type=single-node
+ - http.host=0.0.0.0
+ - xpack.security.enabled=false
+ - transport.host=0.0.0.0
+ ports:
+ - "9201:9200"
+ - "9301:9300"
+ deploy:
+ resources:
+ limits:
+ cpus: "2"
+ memory: "2G"
+ reservations:
+ cpus: "0.5"
+ memory: "512M"
docker-redis:
image: redis:7.4.1
diff --git a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java
index 28fd6ce9769..dd6949c37df 100644
--- a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java
+++ b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java
@@ -1,13 +1,27 @@
package com.netgrif.application.engine.configuration;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.ElasticsearchTransport;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.netgrif.application.engine.configuration.properties.UriProperties;
import com.netgrif.application.engine.workflow.service.CaseEventHandler;
+import org.elasticsearch.client.RestClient;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.*;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
+import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
+import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
@Configuration
+@EnableElasticsearchRepositories(excludeFilters = {
+ @ComponentScan.Filter(
+ type = FilterType.REGEX,
+ pattern = "com\\.netgrif\\.application\\.engine\\.history\\.domain\\..*"
+ )
+})
public class ElasticsearchConfiguration extends org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration {
@Value("${spring.data.elasticsearch.url}")
@@ -84,4 +98,25 @@ public ClientConfiguration clientConfiguration() {
.connectedTo(url + ":" + port)
.build();
}
+
+ @Bean
+ @Primary
+ public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter, ElasticsearchClient elasticsearchClient) {
+ return super.elasticsearchOperations(elasticsearchConverter, elasticsearchClient);
+ }
+
+ @Bean
+ @Qualifier("historyCluster")
+ public ElasticsearchOperations elasticsearchHistoryOperations(ElasticsearchConverter elasticsearchConverter) {
+ ElasticsearchHistoryConfiguration elasticsearchConfiguration = new ElasticsearchHistoryConfiguration();
+ ClientConfiguration clientConfiguration = elasticsearchConfiguration.clientConfiguration();
+ RestClient restClient = elasticsearchConfiguration.elasticsearchRestClient(clientConfiguration);
+ ElasticsearchTransport transport = new RestClientTransport(
+ restClient,
+ new JacksonJsonpMapper()
+ );
+ ElasticsearchClient elasticsearchClient = elasticsearchClient(transport);
+
+ return elasticsearchConfiguration.elasticsearchOperations(elasticsearchConverter, elasticsearchClient);
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java
new file mode 100644
index 00000000000..6c6e5950786
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java
@@ -0,0 +1,20 @@
+package com.netgrif.application.engine.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.elasticsearch.client.ClientConfiguration;
+
+public class ElasticsearchHistoryConfiguration extends org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration {
+
+ @Value("${spring.data.elasticsearch.history.url}")
+ private String url;
+
+ @Value("${spring.data.elasticsearch.history.searchport}")
+ private int port;
+
+ @Override
+ public ClientConfiguration clientConfiguration() {
+ return ClientConfiguration.builder()
+ .connectedTo(url + ":" + port)
+ .build();
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/AuthDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/AuthDispatcher.java
new file mode 100644
index 00000000000..5197ade539c
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/AuthDispatcher.java
@@ -0,0 +1,37 @@
+package com.netgrif.application.engine.event.dispatchers;
+
+import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
+import org.springframework.context.event.EventListener;
+import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
+import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+
+@Component
+public class AuthDispatcher extends AbstractDispatcher {
+ protected AuthDispatcher() {
+ super(Set.of(AuthenticationSuccessEvent.class, AuthenticationFailureBadCredentialsEvent.class));
+ }
+
+ @EventListener
+ public void handleAuthSuccessEvent(AuthenticationSuccessEvent event) {
+ dispatch(event);
+ }
+
+ @EventListener
+ public void handleAsyncAuthSuccessEvent(AuthenticationSuccessEvent event) {
+ dispatchAsync(event);
+ }
+
+ @EventListener
+ public void handleAuthFailBadCredentialsEvent(AuthenticationFailureBadCredentialsEvent event) {
+ dispatch(event);
+ }
+
+
+ @EventListener
+ public void handleAsyncAuthFailBadCredentialsEvent(AuthenticationFailureBadCredentialsEvent event) {
+ dispatchAsync(event);
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/CaseDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/CaseDispatcher.java
index ee024ef6d54..fd803b1cc74 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/CaseDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/CaseDispatcher.java
@@ -1,9 +1,6 @@
package com.netgrif.application.engine.event.dispatchers;
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
-import com.netgrif.application.engine.event.dispatchers.common.DispatchMethod;
-import com.netgrif.application.engine.event.dispatchers.common.RegisteredListener;
-import com.netgrif.application.engine.event.events.EventAction;
import com.netgrif.application.engine.event.events.workflow.CreateCaseEvent;
import com.netgrif.application.engine.event.events.workflow.DeleteCaseEvent;
import com.netgrif.application.engine.event.events.workflow.IndexCaseEvent;
@@ -15,50 +12,38 @@
@Component
public class CaseDispatcher extends AbstractDispatcher {
- public CaseDispatcher() {
- super(Set.of(EventAction.CASE_CREATE, EventAction.CASE_DELETE, EventAction.CASE_INDEXED));
+ protected CaseDispatcher() {
+ super(Set.of(DeleteCaseEvent.class, CreateCaseEvent.class, IndexCaseEvent.class));
}
@EventListener
public void handleCreateCaseEvent(CreateCaseEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.CASE_CREATE
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncCreateCaseEvent(CreateCaseEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.CASE_CREATE
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleDeleteCaseEvent(DeleteCaseEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.CASE_DELETE
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleAsyncDeleteCaseEvent(DeleteCaseEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.CASE_DELETE
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleIndexCaseEvent(IndexCaseEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.CASE_INDEXED
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncIndexCaseEvent(IndexCaseEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.CASE_INDEXED
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/DataDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/DataDispatcher.java
index ce0f15a0427..91db189a41e 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/DataDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/DataDispatcher.java
@@ -1,9 +1,6 @@
package com.netgrif.application.engine.event.dispatchers;
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
-import com.netgrif.application.engine.event.dispatchers.common.DispatchMethod;
-import com.netgrif.application.engine.event.dispatchers.common.RegisteredListener;
-import com.netgrif.application.engine.event.events.EventAction;
import com.netgrif.application.engine.event.events.data.GetDataEvent;
import com.netgrif.application.engine.event.events.data.SetDataEvent;
import org.springframework.context.event.EventListener;
@@ -15,35 +12,27 @@
public class DataDispatcher extends AbstractDispatcher {
public DataDispatcher() {
- super(Set.of(EventAction.DATA_GET, EventAction.DATA_SET));
+ super(Set.of(GetDataEvent.class, SetDataEvent.class));
}
@EventListener
public void handleGetDataEvent(GetDataEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.DATA_GET
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncGetDataEvent(GetDataEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.DATA_GET
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleSetDataEvent(SetDataEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.DATA_SET
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncSetDataEvent(SetDataEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.DATA_SET
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/ProcessDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/ProcessDispatcher.java
index 4b08bf0647f..686757997f3 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/ProcessDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/ProcessDispatcher.java
@@ -1,9 +1,6 @@
package com.netgrif.application.engine.event.dispatchers;
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
-import com.netgrif.application.engine.event.dispatchers.common.DispatchMethod;
-import com.netgrif.application.engine.event.dispatchers.common.RegisteredListener;
-import com.netgrif.application.engine.event.events.EventAction;
import com.netgrif.application.engine.event.events.petrinet.ProcessDeleteEvent;
import com.netgrif.application.engine.event.events.petrinet.ProcessDeployEvent;
import org.springframework.context.event.EventListener;
@@ -15,34 +12,26 @@
public class ProcessDispatcher extends AbstractDispatcher {
public ProcessDispatcher() {
- super(Set.of(EventAction.PROCESS_DELETE, EventAction.PROCESS_DEPLOY));
+ super(Set.of(ProcessDeployEvent.class, ProcessDeleteEvent.class));
}
@EventListener
public void handleProcessDeployEvent(ProcessDeployEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.PROCESS_DEPLOY
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncProcessDeployEvent(ProcessDeployEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.PROCESS_DEPLOY
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleProcessDeleteEvent(ProcessDeleteEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.PROCESS_DELETE
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncProcessDeleteEvent(ProcessDeleteEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.PROCESS_DELETE
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/TaskDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/TaskDispatcher.java
index effd79ddf91..7316b557db1 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/TaskDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/TaskDispatcher.java
@@ -1,9 +1,6 @@
package com.netgrif.application.engine.event.dispatchers;
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
-import com.netgrif.application.engine.event.dispatchers.common.DispatchMethod;
-import com.netgrif.application.engine.event.dispatchers.common.RegisteredListener;
-import com.netgrif.application.engine.event.events.EventAction;
import com.netgrif.application.engine.event.events.task.*;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@@ -14,97 +11,74 @@
public class TaskDispatcher extends AbstractDispatcher {
public TaskDispatcher() {
- super(Set.of(EventAction.TASK_ASSIGN,
- EventAction.TASK_DELEGATE,
- EventAction.TASK_CREATE,
- EventAction.TASK_FINISH,
- EventAction.TASK_CANCEL,
- EventAction.TASK_INDEXED
+ super(Set.of(AssignTaskEvent.class,
+ CancelTaskEvent.class,
+ CreateTaskEvent.class,
+ DelegateTaskEvent.class,
+ FinishTaskEvent.class,
+ IndexTaskEvent.class
));
}
@EventListener
public void handleAssignTaskEvent(AssignTaskEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_ASSIGN
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncAssignTaskEvent(AssignTaskEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_ASSIGN
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
- public void handleDelegateTaskEvent(DelegateTaskEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_DELEGATE
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ public void handleCancelTaskEvent(CancelTaskEvent event) {
+ dispatch(event);
}
@EventListener
- public void handleAsyncDelegateTaskEvent(DelegateTaskEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_DELEGATE
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ public void handleAsyncCancelTaskEvent(CancelTaskEvent event) {
+ dispatchAsync(event);
}
+
@EventListener
- public void handleFinishTaskEvent(FinishTaskEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_FINISH
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ public void handleCreateTaskEvent(CreateTaskEvent event) {
+ dispatch(event);
}
@EventListener
- public void handleAsyncFinishTaskEvent(FinishTaskEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_FINISH
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ public void handleAsyncCreateTaskEvent(CreateTaskEvent event) {
+ dispatchAsync(event);
}
@EventListener
- public void handleCancelTaskEvent(CancelTaskEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_CANCEL
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ public void handleDelegateTaskEvent(DelegateTaskEvent event) {
+ dispatch(event);
}
@EventListener
- public void handleAsyncCancelTaskEvent(CancelTaskEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_CANCEL
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ public void handleAsyncDelegateTaskEvent(DelegateTaskEvent event) {
+ dispatchAsync(event);
}
@EventListener
- public void handleIndexedTaskEvent(IndexTaskEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_INDEXED
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ public void handleFinishTaskEvent(FinishTaskEvent event) {
+ dispatch(event);
}
@EventListener
- public void handleAsyncIndexedTaskEvent(IndexTaskEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_INDEXED
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ public void handleAsyncFinishTaskEvent(FinishTaskEvent event) {
+ dispatchAsync(event);
}
@EventListener
- public void handleCreateTaskEvent(CreateTaskEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_CREATE
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ public void handleIndexedTaskEvent(IndexTaskEvent event) {
+ dispatch(event);
}
@EventListener
- public void handleAsyncCreateTaskEvent(CreateTaskEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.TASK_CREATE
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ public void handleAsyncIndexedTaskEvent(IndexTaskEvent event) {
+ dispatchAsync(event);
}
}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java
index 145e3ebf3a5..5890267d8b7 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java
@@ -1,13 +1,7 @@
package com.netgrif.application.engine.event.dispatchers;
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
-import com.netgrif.application.engine.event.dispatchers.common.DispatchMethod;
-import com.netgrif.application.engine.event.dispatchers.common.RegisteredListener;
-import com.netgrif.application.engine.event.events.EventAction;
-import com.netgrif.application.engine.event.events.user.UserLoginEvent;
-import com.netgrif.application.engine.event.events.user.UserLogoutEvent;
-import com.netgrif.application.engine.event.events.user.UserRegistrationEvent;
-import com.netgrif.application.engine.event.events.user.UserRoleChangeEvent;
+import com.netgrif.application.engine.event.events.user.*;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@@ -17,62 +11,61 @@
public class UserDispatcher extends AbstractDispatcher {
public UserDispatcher() {
- super(Set.of(EventAction.USER_LOGIN, EventAction.USER_LOGOUT, EventAction.USER_REGISTER, EventAction.USER_ROLE_CHANGE));
+ super(Set.of(UserLoginEvent.class,
+ UserLogoutEvent.class,
+ UserRegistrationEvent.class,
+ UserRoleChangeEvent.class,
+ AdminActionEvent.class
+ ));
}
@EventListener
public void handleUserLoginEvent(UserLoginEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_LOGIN
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncUserLoginEvent(UserLoginEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_LOGIN
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleUserLogoutEvent(UserLogoutEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_LOGOUT
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncUserLogoutEvent(UserLogoutEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_LOGOUT
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleUserRegisterEvent(UserRegistrationEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_REGISTER
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncUserRegisterEvent(UserRegistrationEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_REGISTER
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
}
@EventListener
public void handleUserRoleChangeEvent(UserRoleChangeEvent event) {
- dispatch(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_ROLE_CHANGE
- && registeredListener.dispatchMethod() == DispatchMethod.SYNC);
+ dispatch(event);
}
@EventListener
public void handleAsyncUseRoleChangeEvent(UserRoleChangeEvent event) {
- dispatchAsync(event, this, (RegisteredListener registeredListener) ->
- registeredListener.eventAction() == EventAction.USER_ROLE_CHANGE
- && registeredListener.dispatchMethod() == DispatchMethod.ASYNC);
+ dispatchAsync(event);
+ }
+
+ @EventListener
+ public void handleUserRoleChangeEvent(AdminActionEvent event) {
+ dispatch(event);
+ }
+
+ @EventListener
+ public void handleAsyncUseRoleChangeEvent(AdminActionEvent event) {
+ dispatchAsync(event);
}
}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/common/AbstractDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/common/AbstractDispatcher.java
index 6124314ed75..b64b32a1219 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/common/AbstractDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/common/AbstractDispatcher.java
@@ -1,52 +1,55 @@
package com.netgrif.application.engine.event.dispatchers.common;
import com.netgrif.application.engine.event.events.Event;
-import com.netgrif.application.engine.event.events.EventAction;
-import com.netgrif.application.engine.event.events.task.TaskEvent;
import com.netgrif.application.engine.event.listeners.ContextEditingListener;
import com.netgrif.application.engine.event.listeners.Listener;
-import com.netgrif.application.engine.workflow.domain.Task;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
-import java.util.stream.Collectors;
-import static java.util.stream.Collectors.groupingBy;
@Slf4j
public abstract class AbstractDispatcher {
//TODO: Configure custom executor
+ //TODO: Register event
private final Set registeredListeners;
@Getter
- private final Set allowedActions;
+ private final Set> allowedEvents;
- protected AbstractDispatcher(Set allowedActions) {
- this.allowedActions = allowedActions;
+ protected AbstractDispatcher(Set> allowedEvents) {
+ this.allowedEvents = allowedEvents;
this.registeredListeners = new HashSet<>();
}
- /***
+ public enum DispatchMethod {
+ SYNC,
+ ASYNC
+ }
+
+ /**
*
Registration of a new {@link Listener}. The Listener will listen for events based on the value
- * of {@link EventAction} and {@link DispatchMethod}. Throws an {@link IllegalArgumentException}
- * if the listener is already registered or if the dispatcher has no {@link EventAction} value in the allowed events.
- * @param listener {@link Listener} that will listen to {@link Event} with the onEvent/onAsyncEvent method
- * @param eventAction {@link EventAction} that the listener will subscribe to
+ * of event class and {@link DispatchMethod}. Throws an {@link IllegalArgumentException}
+ * if the listener is already registered or if the dispatcher has no provided class in the allowed events.
+ *
+ * @param listener {@link Listener} that will listen to {@link Event} with the onEvent/onAsyncEvent method
+ * @param eventClass Class or subclass of EventObject that the listener is subscribed to
* @param dispatchMethod {@link DispatchMethod} The method by which the dispatcher will send the Event
+ * @param Type of event, must be subclass of {@link EventObject}
*/
- public void registerListener(Listener listener, EventAction eventAction, DispatchMethod dispatchMethod) {
- RegisteredListener registeredListener = new RegisteredListener(listener, eventAction, dispatchMethod);
+ public void registerListener(Listener listener, Class eventClass, DispatchMethod dispatchMethod) {
+ RegisteredListener registeredListener = RegisteredListener.fromClassInstance(listener, eventClass, dispatchMethod);
if (!isRegistrationAllowed(registeredListener)) {
throw new IllegalArgumentException(
"Cannot register Listener " + listener.getName()
+ " for Dispatcher " + this.getName()
- + ": Event " + eventAction
+ + ": Event " + eventClass.getName()
+ " is not supported in Dispatcher: " + this.getName()
- + "\n Allowed Events: " + this.allowedActions
+ + "\n Allowed Events: " + this.allowedEvents
);
} else if (isListenerRegistered(registeredListener)) {
throw new IllegalArgumentException(
@@ -60,16 +63,18 @@ public void registerListener(Listener listener, EventAction eventAction, Dispatc
}
- /***
+ /**
*
Unregister already registered {@link Listener}. The Listener
- * will be unregister only for event based on the value of {@link EventAction} and {@link DispatchMethod}.
+ * will be unregister only for event based on the value of event class and {@link DispatchMethod}.
* Throws an {@link IllegalArgumentException} if the listener is not registered.
- * @param listener {@link Listener} that listen to {@link Event} with the onEvent/onAsyncEvent method
- * @param eventAction {@link EventAction} that the listener is subscribed to
+ *
+ * @param listener {@link Listener} that listen to {@link Event} with the onEvent/onAsyncEvent method
+ * @param eventClass Class or subclass of EventObject that the listener is subscribed to
* @param dispatchMethod {@link DispatchMethod} The method by which the dispatcher is sending the Event
+ * @param Type of event, must be subclass of {@link EventObject}
*/
- public void unregisterListener(Listener listener, EventAction eventAction, DispatchMethod dispatchMethod) {
- RegisteredListener registeredListener = new RegisteredListener(listener, eventAction, dispatchMethod);
+ public void unregisterListener(Listener listener, Class eventClass, DispatchMethod dispatchMethod) {
+ RegisteredListener registeredListener = RegisteredListener.fromClassInstance(listener, eventClass, dispatchMethod);
if (!isListenerRegistered(registeredListener)) {
throw new IllegalArgumentException(
"Cannot unregister Listener " + listener.getName()
@@ -80,70 +85,109 @@ public void unregisterListener(Listener listener, EventAction eventAction, Dispa
registeredListeners.remove(registeredListener);
}
- /***
+ /**
*
Check if {@link Listener} is registered to Dispatcher.
- * @param listener {@link Listener} that listen to {@link Event} with the onEvent/onAsyncEvent method
- * @param eventAction {@link EventAction} that the listener is subscribed to
+ *
+ * @param listener {@link Listener} that listen to {@link Event} with the onEvent/onAsyncEvent method
+ * @param eventClass Class or subclass of EventObject that the listener is subscribed to
* @param dispatchMethod {@link DispatchMethod} The method by which the dispatcher is sending the Event
- * @return true if dispatcher holds record of {@link Listener} to {@link EventAction} with {@link DispatchMethod} else false
+ * @param Type of event, must be subclass of {@link EventObject}
+ * @return true if dispatcher holds record of {@link Listener} to event class with {@link DispatchMethod} else false
*/
- public boolean isListenerRegistered(Listener listener, EventAction eventAction, DispatchMethod dispatchMethod) {
- return isListenerRegistered(new RegisteredListener(listener, eventAction, dispatchMethod));
+ public boolean isListenerRegistered(Listener listener, Class eventClass, DispatchMethod dispatchMethod) {
+ return isListenerRegistered(RegisteredListener.fromClassInstance(listener, eventClass, dispatchMethod));
}
- /***
+ /**
*
Check if {@link Listener} is registered to Dispatcher.
+ *
* @param registeredListener {@link RegisteredListener} that holds listening content
- * @return true if dispatcher holds record of {@link RegisteredListener} else false
+ * @return true if dispatcher holds record of {@link RegisteredListener} else false
*/
public boolean isListenerRegistered(RegisteredListener registeredListener) {
return registeredListeners.stream().anyMatch(l -> l.equals(registeredListener));
}
- /***
+ /**
+ *
Send event object to registered {@link Listener}. This function sends events asynchronously,
+ * but wait until all listeners have finished executing the onEvent method. This is wrapper method,
+ * where decision function foo as input is omitted. Decision is made by lambda function,
+ * which checks if registerListener contains provided event with sync dispatching method
+ *
+ * @param event Event that the listener is subscribed to
+ * @param Type of event, must be child of {@link EventObject}
+ * @see AbstractDispatcher#dispatch(EventObject, Function)
+ * @see RegisteredListener
+ */
+ protected void dispatch(E event) {
+ dispatch(event, (RegisteredListener registeredListener) ->
+ registeredListener.contains(event)
+ && registeredListener.contains(DispatchMethod.SYNC));
+ }
+
+ /**
+ *
Send event object to registered {@link Listener}.This function dispatches events asynchronously
+ * and does not wait for the execution of the onAsyncEvent method to complete. This is wrapper method,
+ * where decision function foo as input is omitted. Decision is made by lambda function,
+ * which checks if registerListener contains provided event with async dispatching method
+ *
+ * @param event Event that the listener is subscribed to
+ * @param Type of event, must be child of {@link EventObject}
+ * @see Listener#onAsyncEvent
+ * @see RegisteredListener
+ */
+ protected void dispatchAsync(E event) {
+ dispatchAsync(event, (RegisteredListener registeredListener) ->
+ registeredListener.contains(event)
+ && registeredListener.contains(DispatchMethod.ASYNC));
+ }
+
+ /**
*
Send event object to registered {@link Listener}. This function sends events asynchronously,
* but wait until all listeners have finished executing the onEvent method.
* See {@link Listener#onEvent}.
+ *
* @param event Event that the listener is subscribed to
- * @param dispatcher Dispatcher object that sends the events
- * @param foo Function to decide to which listener the event should be sent
+ * @param foo Function to decide to which listener the event should be sent
+ * @param Type of event, must be child of {@link EventObject}
*/
- protected void dispatch(Event event, AbstractDispatcher dispatcher, Function foo) {
+ protected void dispatch(E event, Function foo) {
List> futures = new ArrayList<>();
List simpleListeners = registeredListeners.stream().filter(l -> !(l.listener() instanceof ContextEditingListener>)).toList();
List contextEditingListeners = registeredListeners.stream().filter(l -> l.listener() instanceof ContextEditingListener>).toList();
for (RegisteredListener registeredListener : simpleListeners) {
CompletableFuture future = CompletableFuture.runAsync(() -> {
if (foo.apply(registeredListener)) {
- log.trace("Sending event with message {} synchronously", event.getMessage());
- registeredListener.listener().onEvent(event, dispatcher);
+ log.trace("Sending event {} synchronously", event.getClass().getSimpleName());
+ registeredListener.listener().onEvent(event, this);
}
});
futures.add(future);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
- Event updatedEvent = event;
+ E updatedEvent = event;
for (RegisteredListener registeredListener : contextEditingListeners) {
if (foo.apply(registeredListener)) {
- updatedEvent = ((ContextEditingListener) registeredListener.listener()).onContextEditingEvent(updatedEvent, dispatcher);
+ updatedEvent = ((ContextEditingListener) registeredListener.listener()).onContextEditingEvent(updatedEvent, this);
}
}
}
- /***
+ /**
*
Send event object to registered {@link Listener}.This function dispatches events asynchronously
* and does not wait for the execution of the onAsyncEvent method to complete.
* See {@link Listener#onAsyncEvent}.
Abstract method for handling synchronous events with return. This method will be invoked by Dispatcher if the Listener is registered.
- * See {@link AbstractDispatcher#registerListener(Listener, EventAction, DispatchMethod)}
- * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
+ *
+ * @param event {@link EventObject} object, final type of the object is determined based on event class
* @param dispatcher {@link AbstractDispatcher} from which the event was dispatched
+ * @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
*/
- public abstract T onContextEditingEvent(Event event, AbstractDispatcher dispatcher);
+ public abstract T onContextEditingEvent(EventObject event, AbstractDispatcher dispatcher);
}
diff --git a/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java b/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java
index 9b9617105b3..64043027be6 100644
--- a/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java
+++ b/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java
@@ -2,39 +2,65 @@
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
-import com.netgrif.application.engine.event.dispatchers.common.DispatchMethod;
import com.netgrif.application.engine.event.events.Event;
import com.netgrif.application.engine.event.events.EventAction;
+import lombok.Getter;
-import java.util.function.Function;
+import java.util.EventListener;
+import java.util.EventObject;
+import java.util.Set;
-
-public abstract class Listener {
+@Getter
+public abstract class Listener implements EventListener {
public Listener() {
+
+ }
+ //todo: register global
+
+ /**
+ * Register this listener to dispatcher.
+ *
+ * @param dispatcher Dispatcher, to listen Events
+ * @param event Clas of event, which this Listener will be subscribed to
+ * @param dispatchMethod synchronous or asynchronous
+ * @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
+ */
+ public void register(AbstractDispatcher dispatcher, Class extends EventObject> event, AbstractDispatcher.DispatchMethod dispatchMethod) {
+ dispatcher.registerListener(this, event, dispatchMethod);
+ }
+
+ public void registerAll(AbstractDispatcher dispatcher, Set> events, AbstractDispatcher.DispatchMethod dispatchMethod) {
+ events.forEach(event -> dispatcher.registerListener(this, event, dispatchMethod));
+ }
+
+ public void unregister(AbstractDispatcher dispatcher, Class extends EventObject> event, AbstractDispatcher.DispatchMethod dispatchMethod) {
+ dispatcher.unregisterListener(this, event, dispatchMethod);
}
- public Listener(AbstractDispatcher dispatcher, EventAction eventAction, DispatchMethod method) {
- dispatcher.registerListener(this, eventAction, method);
+ public void unregisterAll(AbstractDispatcher dispatcher, Set> events, AbstractDispatcher.DispatchMethod dispatchMethod) {
+ events.forEach(event -> dispatcher.unregisterListener(this, event, dispatchMethod));
}
- /***
+ /**
*
Abstract method for handling synchronous events. This method will be invoked by Dispatcher if the Listener is registered.
- * See {@link AbstractDispatcher#registerListener(Listener, EventAction, DispatchMethod)}
- * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
+ *
+ * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
* @param dispatcher {@link AbstractDispatcher} from which the event was dispatched
+ * @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
*/
- public abstract void onEvent(Event event, AbstractDispatcher dispatcher);
+ public abstract void onEvent(final EventObject event, AbstractDispatcher dispatcher);
- /***
+ /**
*
Abstract method for handling asynchronous events. This method will be invoked by Dispatcher if the Listener is registered.
- * See {@link AbstractDispatcher#registerListener(Listener, EventAction, DispatchMethod)}
- * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
+ *
+ * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
* @param dispatcher {@link AbstractDispatcher} from which the event was dispatched
+ * @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
*/
- public abstract void onAsyncEvent(Event event, AbstractDispatcher dispatcher);
+ public abstract void onAsyncEvent(final EventObject event, AbstractDispatcher dispatcher);
- public String getName(){
+ public String getName() {
return this.getClass().getSimpleName();
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java b/src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java
new file mode 100644
index 00000000000..d68fb38d6b3
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java
@@ -0,0 +1,9 @@
+package com.netgrif.application.engine.history.domain;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
+
+@Configuration
+@EnableElasticsearchRepositories(elasticsearchTemplateRef = "historyCluster")
+public class EventLogRepositoryConfiguration {
+}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/baseevent/EventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/baseevent/EventLog.java
index d0ae6adf96d..ba9100683bb 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/baseevent/EventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/baseevent/EventLog.java
@@ -1,17 +1,25 @@
package com.netgrif.application.engine.history.domain.baseevent;
+import com.netgrif.application.engine.event.events.Event;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.ProcessResourceId;
import lombok.Getter;
import lombok.Setter;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
-import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.elasticsearch.annotations.Document;
+
+import java.io.Serial;
+import java.io.Serializable;
import java.util.List;
-@Document(collection = "eventLogs")
-public abstract class EventLog {
+//TODO
+@Document(indexName = "#{@eventLogIndex}")
+public abstract class EventLog implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 7650412902302046885L;
@Id
@Getter
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/baseevent/repository/EventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/baseevent/repository/EventLogRepository.java
index eca3b6526f0..61faf400ad9 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/baseevent/repository/EventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/baseevent/repository/EventLogRepository.java
@@ -2,13 +2,14 @@
import com.netgrif.application.engine.history.domain.baseevent.EventLog;
import org.bson.types.ObjectId;
-import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-public interface EventLogRepository extends MongoRepository {
+public interface EventLogRepository extends ElasticsearchRepository {
List findAllById(List eventIds);
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/CreateCaseEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/CreateCaseEventLog.java
index 36ae6fc9298..0ce91f95ae9 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/CreateCaseEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/CreateCaseEventLog.java
@@ -1,19 +1,22 @@
package com.netgrif.application.engine.history.domain.caseevents;
+import com.netgrif.application.engine.event.events.workflow.CreateCaseEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.DataField;
import lombok.EqualsAndHashCode;
-import org.springframework.data.mongodb.core.mapping.Document;
-import org.springframework.data.mongodb.core.mapping.Field;
+import java.io.Serial;
import java.util.Map;
-@Document(collection = "eventLogs")
+//todo
@EqualsAndHashCode(callSuper = true)
public class CreateCaseEventLog extends CaseEventLog {
- @Field("dataSetValues")
+
+ @Serial
+ private static final long serialVersionUID = -7202365131803028246L;
+
private Map dataSetValues;
public CreateCaseEventLog() {
@@ -32,4 +35,8 @@ public Map getDataSetValues() {
public void setDataSetValues(Map values) {
this.dataSetValues = values;
}
+
+ public static CreateCaseEventLog fromEvent(CreateCaseEvent event) {
+ return new CreateCaseEventLog(event.getCaseEventOutcome().getCase(), event.getEventPhase());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/DeleteCaseEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/DeleteCaseEventLog.java
index 9f7c9fd9489..f5814d2c25c 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/DeleteCaseEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/DeleteCaseEventLog.java
@@ -1,14 +1,21 @@
package com.netgrif.application.engine.history.domain.caseevents;
+import com.netgrif.application.engine.event.events.workflow.CreateCaseEvent;
+import com.netgrif.application.engine.event.events.workflow.DeleteCaseEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import lombok.EqualsAndHashCode;
import org.springframework.data.mongodb.core.mapping.Document;
-@Document(collection = "eventLogs")
+import java.io.Serial;
+
+
@EqualsAndHashCode(callSuper = true)
public class DeleteCaseEventLog extends CaseEventLog {
+ @Serial
+ private static final long serialVersionUID = 2263046649744238557L;
+
public DeleteCaseEventLog() {
super();
}
@@ -16,4 +23,8 @@ public DeleteCaseEventLog() {
public DeleteCaseEventLog(Case useCase, EventPhase eventPhase) {
super(useCase, eventPhase);
}
+
+ public static DeleteCaseEventLog fromEvent(DeleteCaseEvent event) {
+ return new DeleteCaseEventLog(event.getCaseEventOutcome().getCase(), event.getEventPhase());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/CreateCaseEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/CreateCaseEventLogRepository.java
index 811478fd69c..7e2c4415fa3 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/CreateCaseEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/CreateCaseEventLogRepository.java
@@ -2,14 +2,13 @@
import com.netgrif.application.engine.history.domain.caseevents.CreateCaseEventLog;
import org.bson.types.ObjectId;
-import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface CreateCaseEventLogRepository extends MongoRepository {
+public interface CreateCaseEventLogRepository extends ElasticsearchRepository {
List findAllByCaseId(ObjectId caseId);
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/DeleteCaseEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/DeleteCaseEventLogRepository.java
index 418097f9c5d..e21dc722e6b 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/DeleteCaseEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/caseevents/repository/DeleteCaseEventLogRepository.java
@@ -2,14 +2,13 @@
import com.netgrif.application.engine.history.domain.caseevents.DeleteCaseEventLog;
import org.bson.types.ObjectId;
-import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface DeleteCaseEventLogRepository extends MongoRepository {
+public interface DeleteCaseEventLogRepository extends ElasticsearchRepository {
List findAllByCaseId(ObjectId caseId);
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/dataevents/GetDataEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/dataevents/GetDataEventLog.java
index ee92bcbe968..bad86823c70 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/dataevents/GetDataEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/dataevents/GetDataEventLog.java
@@ -1,6 +1,7 @@
package com.netgrif.application.engine.history.domain.dataevents;
import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.data.GetDataEvent;
import com.netgrif.application.engine.history.domain.taskevents.TaskEventLog;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
@@ -8,7 +9,7 @@
import lombok.EqualsAndHashCode;
import org.springframework.data.mongodb.core.mapping.Document;
-@Document(collection = "eventLogs")
+
@EqualsAndHashCode(callSuper = true)
public class GetDataEventLog extends TaskEventLog {
@@ -19,4 +20,8 @@ public GetDataEventLog() {
public GetDataEventLog(Task task, Case useCase, EventPhase eventPhase, IUser user) {
super(task, useCase, eventPhase, user.getStringId(), user.isImpersonating() ? user.getImpersonated().getStringId() : null);
}
+
+ public static GetDataEventLog fromEvent(GetDataEvent event) {
+ return new GetDataEventLog(event.getEventOutcome().getTask(), event.getEventOutcome().getCase(), event.getEventPhase(), event.getUser());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/dataevents/SetDataEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/dataevents/SetDataEventLog.java
index b19440b9cda..ab953c096f1 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/dataevents/SetDataEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/dataevents/SetDataEventLog.java
@@ -1,6 +1,7 @@
package com.netgrif.application.engine.history.domain.dataevents;
import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.data.SetDataEvent;
import com.netgrif.application.engine.history.domain.taskevents.TaskEventLog;
import com.netgrif.application.engine.petrinet.domain.dataset.logic.ChangedField;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
@@ -9,12 +10,11 @@
import com.querydsl.core.annotations.QueryExclude;
import lombok.EqualsAndHashCode;
import lombok.Getter;
-import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Map;
@QueryExclude
-@Document(collection = "eventLogs")
+//TODO
@EqualsAndHashCode(callSuper = true)
public class SetDataEventLog extends TaskEventLog {
@@ -29,4 +29,8 @@ public SetDataEventLog(Task task, Case useCase, EventPhase eventPhase, Map {
+public interface GetDataEventLogRepository extends ElasticsearchRepository {
List findAllByCaseId(ObjectId caseId);
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/dataevents/repository/SetDataEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/dataevents/repository/SetDataEventLogRepository.java
index d77230d5b1a..2fefa858291 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/dataevents/repository/SetDataEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/dataevents/repository/SetDataEventLogRepository.java
@@ -2,14 +2,14 @@
import com.netgrif.application.engine.history.domain.dataevents.SetDataEventLog;
import org.bson.types.ObjectId;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface SetDataEventLogRepository extends MongoRepository {
+public interface SetDataEventLogRepository extends ElasticsearchRepository {
List findAllByCaseId(ObjectId caseId);
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/DeletePetriNetEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/DeletePetriNetEventLog.java
index 7c5ea12c1fe..34a200c92aa 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/DeletePetriNetEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/DeletePetriNetEventLog.java
@@ -1,16 +1,20 @@
package com.netgrif.application.engine.history.domain.petrinetevents;
+import com.netgrif.application.engine.event.events.petrinet.ProcessDeleteEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.ProcessResourceId;
import lombok.EqualsAndHashCode;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.Document;
-@Document(collection = "eventLogs")
@EqualsAndHashCode(callSuper = true)
public class DeletePetriNetEventLog extends PetriNetEventLog {
public DeletePetriNetEventLog(ProcessResourceId triggerId, EventPhase eventPhase, ObjectId netId) {
super(triggerId, eventPhase, netId);
}
+
+ public static DeletePetriNetEventLog fromEvent(ProcessDeleteEvent event) {
+ return new DeletePetriNetEventLog(null, event.getEventPhase(), event.getPetriNet().getObjectId());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/ImportPetriNetEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/ImportPetriNetEventLog.java
index 246cfd99620..2d3cab462f9 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/ImportPetriNetEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/ImportPetriNetEventLog.java
@@ -1,5 +1,7 @@
package com.netgrif.application.engine.history.domain.petrinetevents;
+import com.netgrif.application.engine.event.events.petrinet.ProcessDeleteEvent;
+import com.netgrif.application.engine.event.events.petrinet.ProcessDeployEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.ProcessResourceId;
import lombok.EqualsAndHashCode;
@@ -13,4 +15,9 @@ public class ImportPetriNetEventLog extends PetriNetEventLog {
public ImportPetriNetEventLog(ProcessResourceId triggerId, EventPhase eventPhase, ObjectId netId) {
super(triggerId, eventPhase, netId);
}
+
+
+ public static ImportPetriNetEventLog fromEvent(ProcessDeployEvent event) {
+ return new ImportPetriNetEventLog(null, event.getEventPhase(), event.getEventOutcome().getNet().getObjectId());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/DeletePetriNetEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/DeletePetriNetEventLogRepository.java
index e7b46dcbdab..56e7f9f086d 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/DeletePetriNetEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/DeletePetriNetEventLogRepository.java
@@ -2,14 +2,14 @@
import com.netgrif.application.engine.history.domain.petrinetevents.DeletePetriNetEventLog;
import org.bson.types.ObjectId;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface DeletePetriNetEventLogRepository extends MongoRepository {
+public interface DeletePetriNetEventLogRepository extends ElasticsearchRepository {
List findAllByNetId(ObjectId netId);
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/ImportPetriNetEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/ImportPetriNetEventLogRepository.java
index 0ae1d0e225f..e293ba4ae65 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/ImportPetriNetEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/petrinetevents/repository/ImportPetriNetEventLogRepository.java
@@ -2,14 +2,14 @@
import com.netgrif.application.engine.history.domain.petrinetevents.ImportPetriNetEventLog;
import org.bson.types.ObjectId;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface ImportPetriNetEventLogRepository extends MongoRepository {
+public interface ImportPetriNetEventLogRepository extends ElasticsearchRepository {
List findAllByNetId(ObjectId netId);
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/AssignTaskEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/AssignTaskEventLog.java
index 6c2e3600e73..90ec53f84c9 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/AssignTaskEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/AssignTaskEventLog.java
@@ -1,13 +1,17 @@
package com.netgrif.application.engine.history.domain.taskevents;
import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.data.GetDataEvent;
+import com.netgrif.application.engine.event.events.petrinet.ProcessDeleteEvent;
+import com.netgrif.application.engine.event.events.task.AssignTaskEvent;
+import com.netgrif.application.engine.history.domain.dataevents.GetDataEventLog;
+import com.netgrif.application.engine.history.domain.petrinetevents.DeletePetriNetEventLog;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.Task;
import lombok.EqualsAndHashCode;
import org.springframework.data.mongodb.core.mapping.Document;
-@Document(collection = "eventLogs")
@EqualsAndHashCode(callSuper = true)
public class AssignTaskEventLog extends TaskEventLog {
@@ -19,4 +23,8 @@ public AssignTaskEventLog() {
public AssignTaskEventLog(Task task, Case useCase, EventPhase eventPhase, IUser user) {
super(task, useCase, eventPhase, user.getStringId(), user.isImpersonating() ? user.getImpersonated().getStringId() : null);
}
+
+ public static AssignTaskEventLog fromEvent(AssignTaskEvent event) {
+ return new AssignTaskEventLog(event.getTaskEventOutcome().getTask(), event.getTaskEventOutcome().getCase(), event.getEventPhase(), event.getUser());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java
index d68555ab8ad..25e0eb9f0e8 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java
@@ -1,6 +1,8 @@
package com.netgrif.application.engine.history.domain.taskevents;
import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.task.AssignTaskEvent;
+import com.netgrif.application.engine.event.events.task.CancelTaskEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.Task;
@@ -8,7 +10,6 @@
import org.springframework.data.mongodb.core.mapping.Document;
@EqualsAndHashCode(callSuper = true)
-@Document(collection = "eventLogs")
public class CancelTaskEventLog extends TaskEventLog {
public CancelTaskEventLog() {
@@ -18,4 +19,8 @@ public CancelTaskEventLog() {
public CancelTaskEventLog(Task task, Case useCase, EventPhase eventPhase, IUser user) {
super(task, useCase, eventPhase, user.getStringId(), user.isImpersonating() ? user.getImpersonated().getStringId() : null);
}
+
+ public static CancelTaskEventLog fromEvent(CancelTaskEvent event) {
+ return new CancelTaskEventLog(event.getTaskEventOutcome().getTask(), event.getTaskEventOutcome().getCase(), event.getEventPhase(), event.getUser());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CreateTaskEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CreateTaskEventLog.java
new file mode 100644
index 00000000000..831c710ab49
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CreateTaskEventLog.java
@@ -0,0 +1,22 @@
+package com.netgrif.application.engine.history.domain.taskevents;
+
+import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.task.CreateTaskEvent;
+import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
+import com.netgrif.application.engine.workflow.domain.Case;
+import com.netgrif.application.engine.workflow.domain.Task;
+
+public class CreateTaskEventLog extends TaskEventLog {
+
+ public CreateTaskEventLog() {
+ super();
+ }
+
+ public CreateTaskEventLog(Task task, Case useCase, EventPhase eventPhase, IUser user) {
+ super(task, useCase, eventPhase, user.getStringId(), user.isImpersonating() ? user.getImpersonated().getStringId() : null);
+ }
+
+ public static CreateTaskEventLog fromEvent(CreateTaskEvent event) {
+ return new CreateTaskEventLog(event.getTaskEventOutcome().getTask(), event.getTaskEventOutcome().getCase(), event.getEventPhase(), event.getUser());
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/DelegateTaskEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/DelegateTaskEventLog.java
index 1d3f1411d9d..536714a3b14 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/DelegateTaskEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/DelegateTaskEventLog.java
@@ -1,6 +1,8 @@
package com.netgrif.application.engine.history.domain.taskevents;
import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.task.CancelTaskEvent;
+import com.netgrif.application.engine.event.events.task.DelegateTaskEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.Task;
@@ -8,7 +10,6 @@
import lombok.Getter;
import org.springframework.data.mongodb.core.mapping.Document;
-@Document(collection = "eventLogs")
@EqualsAndHashCode(callSuper = true)
public class DelegateTaskEventLog extends TaskEventLog {
@@ -27,4 +28,9 @@ public DelegateTaskEventLog(Task task, Case useCase, EventPhase eventPhase, IUse
this.delegator = getUserId();
this.delegate = delegate;
}
+
+
+ public static DelegateTaskEventLog fromEvent(DelegateTaskEvent event) {
+ return new DelegateTaskEventLog(event.getTaskEventOutcome().getTask(), event.getTaskEventOutcome().getCase(), event.getEventPhase(), event.getUser(), event.getDelegate());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/FinishTaskEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/FinishTaskEventLog.java
index 11e3daa6a1b..b360ec0e13a 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/FinishTaskEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/FinishTaskEventLog.java
@@ -1,13 +1,15 @@
package com.netgrif.application.engine.history.domain.taskevents;
import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.event.events.task.CreateTaskEvent;
+import com.netgrif.application.engine.event.events.task.FinishTaskEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.Task;
import lombok.EqualsAndHashCode;
import org.springframework.data.mongodb.core.mapping.Document;
-@Document(collection = "eventLogs")
+
@EqualsAndHashCode(callSuper = true)
public class FinishTaskEventLog extends TaskEventLog {
@@ -18,4 +20,8 @@ public FinishTaskEventLog() {
public FinishTaskEventLog(Task task, Case useCase, EventPhase eventPhase, IUser user) {
super(task, useCase, eventPhase, user.getStringId(), user.isImpersonating() ? user.getImpersonated().getStringId() : null);
}
+
+ public static FinishTaskEventLog fromEvent(FinishTaskEvent event) {
+ return new FinishTaskEventLog(event.getTaskEventOutcome().getTask(), event.getTaskEventOutcome().getCase(), event.getEventPhase(), event.getUser());
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/AssignTaskEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/AssignTaskEventLogRepository.java
index e53e683fcbc..0eefa53fd5e 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/AssignTaskEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/AssignTaskEventLogRepository.java
@@ -2,14 +2,13 @@
import com.netgrif.application.engine.history.domain.taskevents.AssignTaskEventLog;
import org.bson.types.ObjectId;
-import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface AssignTaskEventLogRepository extends MongoRepository {
+public interface AssignTaskEventLogRepository extends ElasticsearchRepository {
List findAllByTaskId(ObjectId taskId);
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CancelTaskEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CancelTaskEventLogRepository.java
index d5ff580a7a6..085cfb3effa 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CancelTaskEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CancelTaskEventLogRepository.java
@@ -1,15 +1,15 @@
package com.netgrif.application.engine.history.domain.taskevents.repository;
-import com.netgrif.application.engine.history.domain.taskevents.CancelTaskEventLog;
+
import org.bson.types.ObjectId;
-import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+import com.netgrif.application.engine.history.domain.taskevents.CancelTaskEventLog;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface CancelTaskEventLogRepository extends MongoRepository {
+public interface CancelTaskEventLogRepository extends ElasticsearchRepository {
List findAllByTaskId(ObjectId taskId);
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CreateTaskEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CreateTaskEventLogRepository.java
new file mode 100644
index 00000000000..0aa126d1726
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/CreateTaskEventLogRepository.java
@@ -0,0 +1,10 @@
+package com.netgrif.application.engine.history.domain.taskevents.repository;
+
+import com.netgrif.application.engine.history.domain.taskevents.CreateTaskEventLog;
+import org.bson.types.ObjectId;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CreateTaskEventLogRepository extends ElasticsearchRepository {
+}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/DelegateTaskEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/DelegateTaskEventLogRepository.java
index 0d5244e0fcb..e2d48c231fd 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/DelegateTaskEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/DelegateTaskEventLogRepository.java
@@ -2,14 +2,14 @@
import com.netgrif.application.engine.history.domain.taskevents.DelegateTaskEventLog;
import org.bson.types.ObjectId;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface DelegateTaskEventLogRepository extends MongoRepository {
+public interface DelegateTaskEventLogRepository extends ElasticsearchRepository {
List findAllByTaskId(ObjectId taskId);
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/FinishTaskEventLogRepository.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/FinishTaskEventLogRepository.java
index 4864e2cc991..89bb7220447 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/FinishTaskEventLogRepository.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/repository/FinishTaskEventLogRepository.java
@@ -2,14 +2,14 @@
import com.netgrif.application.engine.history.domain.taskevents.FinishTaskEventLog;
import org.bson.types.ObjectId;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
-@Deprecated(since = "6.3.0")
-public interface FinishTaskEventLogRepository extends MongoRepository {
+public interface FinishTaskEventLogRepository extends ElasticsearchRepository {
List findAllByTaskId(ObjectId taskId);
diff --git a/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java b/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java
index 40d6f6b9033..2be237dcb12 100644
--- a/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java
+++ b/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java
@@ -1,260 +1,236 @@
package com.netgrif.application.engine.history.service;
-import com.netgrif.application.engine.history.domain.baseevent.EventLog;
-import com.netgrif.application.engine.history.domain.baseevent.repository.EventLogRepository;
-import com.netgrif.application.engine.history.domain.caseevents.CreateCaseEventLog;
-import com.netgrif.application.engine.history.domain.caseevents.DeleteCaseEventLog;
-import com.netgrif.application.engine.history.domain.dataevents.GetDataEventLog;
-import com.netgrif.application.engine.history.domain.dataevents.SetDataEventLog;
-import com.netgrif.application.engine.history.domain.petrinetevents.DeletePetriNetEventLog;
-import com.netgrif.application.engine.history.domain.petrinetevents.ImportPetriNetEventLog;
-import com.netgrif.application.engine.history.domain.taskevents.AssignTaskEventLog;
-import com.netgrif.application.engine.history.domain.taskevents.CancelTaskEventLog;
-import com.netgrif.application.engine.history.domain.taskevents.FinishTaskEventLog;
-import org.bson.types.ObjectId;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.query.BasicQuery;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
-@Service
-public class HistoryService implements IHistoryService {
- protected String clazz = "', _class: '";
-
- @Autowired
- private EventLogRepository eventLogRepository;
-
- @Autowired
- private MongoTemplate mongoTemplate;
-
- @Override
- @Async
- public void save(EventLog eventLog) {
- eventLogRepository.save(eventLog);
- }
-
- @Override
- public List findAllByIds(List eventIds) {
- return eventLogRepository.findAllById(eventIds);
- }
-
- @Override
- public List findAllCreateCaseEventLogsByCaseId(ObjectId caseId) {
- return findAllByCaseId(caseId.toString(), CreateCaseEventLog.class);
- }
-
- @Override
- public List findAllDeleteCaseEventLogsByCaseId(ObjectId caseId) {
- return findAllByCaseId(caseId.toString(), DeleteCaseEventLog.class);
- }
-
- @Override
- public List findAllCreateCaseEventLogsByCaseId(String caseId) {
- return findAllByCaseId(caseId, CreateCaseEventLog.class);
- }
-
- @Override
- public List findAllDeleteCaseEventLogsByCaseId(String caseId) {
- return findAllByCaseId(caseId, DeleteCaseEventLog.class);
- }
-
- @Override
- public List findAllGetDataEventLogsByCaseId(ObjectId caseId) {
- return findAllByCaseId(caseId.toString(), GetDataEventLog.class);
- }
-
- @Override
- public List findAllGetDataEventLogsByTaskId(ObjectId taskId) {
- return findAllByTaskId(taskId.toString(), GetDataEventLog.class);
- }
-
- @Override
- public List findAllGetDataEventLogsByCaseId(String caseId) {
- return findAllByCaseId(caseId, GetDataEventLog.class);
- }
-
- @Override
- public List findAllGetDataEventLogsByTaskId(String taskId) {
- return findAllByTaskId(taskId, GetDataEventLog.class);
- }
-
- @Override
- public List findAllSetDataEventLogsByCaseId(ObjectId caseId) {
- return findAllByCaseId(caseId.toString(), SetDataEventLog.class);
- }
-
- @Override
- public List findAllSetDataEventLogsByCaseId(String caseId) {
- return findAllByCaseId(caseId, SetDataEventLog.class);
- }
-
- @Override
- public List findAllSetDataEventLogsByTaskId(ObjectId taskId) {
- return findAllByTaskId(taskId.toString(), SetDataEventLog.class);
- }
-
- @Override
- public List findAllDeletePetriNetEventLogsByNetId(ObjectId netId) {
- return findAllByNetId(netId, DeletePetriNetEventLog.class);
- }
-
- @Override
- public List findAllSetDataEventLogsByTaskId(String taskId) {
- return findAllByTaskId(taskId, SetDataEventLog.class);
- }
-
- @Override
- public List findAllImportPetriNetEventLogsByNetId(ObjectId netId) {
- return findAllByNetId(netId, ImportPetriNetEventLog.class);
- }
-
- @Override
- public List findAllAssignTaskEventLogsByTaskId(ObjectId taskId) {
- return findAllByTaskId(taskId.toString(), AssignTaskEventLog.class);
- }
-
- @Override
- public List findAllAssignTaskEventLogsByTaskId(String taskId) {
- return findAllByTaskId(taskId, AssignTaskEventLog.class);
- }
-
-
- @Override
- public List findAllAssignTaskEventLogsByUserId(String userId) {
- return findAllByUserId(userId, AssignTaskEventLog.class);
- }
-
- @Override
- public List findAllAssignTaskEventLogsByCaseId(String caseId) {
- return findAllByCaseId(caseId, AssignTaskEventLog.class);
- }
-
- @Override
- public List findAllCancelTaskEventLogsByTaskId(String taskId) {
- return findAllByTaskId(taskId, CancelTaskEventLog.class);
- }
-
- @Override
- public List findAllCancelTaskEventLogsByTaskId(ObjectId taskId) {
- return findAllByTaskId(taskId.toString(), CancelTaskEventLog.class);
- }
-
- @Override
- public List findAllCancelTaskEventLogsByUserId(String userId) {
- return findAllByUserId(userId, CancelTaskEventLog.class);
- }
-
-
- @Override
- public List findAllFinishTaskEventLogsByTaskId(String taskId) {
- return findAllByTaskId(taskId, FinishTaskEventLog.class);
- }
-
- @Override
- public List findAllFinishTaskEventLogsByTaskId(ObjectId taskId) {
- return findAllByTaskId(taskId.toString(), FinishTaskEventLog.class);
- }
-
- @Override
- public List findAllFinishTaskEventLogsByUserId(String userId) {
- return findAllByUserId(userId, FinishTaskEventLog.class);
- }
-
- @Override
- public List findAllFinishTaskEventLogsByCaseId(String caseId) {
- return findAllByCaseId(caseId, FinishTaskEventLog.class);
- }
-
- @Override
- public Page findByUserId(String id, Class clazz, Pageable pageable) {
- String queryString = "{userId: '" + id + this.clazz + clazz.getName() + "'}";
- return findByQuery(queryString, clazz, pageable);
- }
-
- @Override
- public List findAllByUserId(String id, Class clazz) {
- String queryString = "{userId: '" + id + this.clazz + clazz.getName() + "'}";
- Query query = new BasicQuery(queryString);
- return findAllByQuery(query, clazz);
- }
-
- @Override
- public Page findByNetId(String id, Class clazz, Pageable pageable) {
- return findByNetId(new ObjectId(id), clazz, pageable);
- }
-
- @Override
- public List findAllByNetId(String id, Class clazz) {
- return findAllByNetId(new ObjectId(id), clazz);
- }
-
- @Override
- public Page findByNetId(ObjectId id, Class clazz, Pageable pageable) {
- String queryString = "{netId: '" + id + this.clazz + clazz.getName() + "'}";
- return findByQuery(queryString, clazz, pageable);
- }
-
- @Override
- public List findAllByNetId(ObjectId id, Class clazz) {
- String queryString = "{netId: '" + id + this.clazz + clazz.getName() + "'}";
- Query query = new BasicQuery(queryString);
- return findAllByQuery(query, clazz);
- }
-
- @Override
- public Page findByTaskId(String id, Class clazz) {
- return null;
- }
-
- @Override
- public Page findByTaskId(String id, Class clazz, Pageable pageable) {
- String queryString = "{taskId: '" + id + this.clazz + clazz.getName() + "'}";
- return findByQuery(queryString, clazz, pageable);
- }
-
- @Override
- public List findAllByTaskId(String id, Class clazz) {
- String queryString = "{taskId: '" + id + this.clazz + clazz.getName() + "'}";
- Query query = new BasicQuery(queryString);
- return findAllByQuery(query, clazz);
- }
-
- @Override
- public Page findByCaseId(String id, Class clazz, Pageable pageable) {
- String queryString = "{caseId: '" + id + this.clazz + clazz.getName() + "'}";
- return findByQuery(queryString, clazz, pageable);
- }
-
- @Override
- public List findAllByCaseId(String id, Class clazz) {
- String queryString = "{caseId: '" + id + this.clazz + clazz.getName() + "'}";
- Query query = new BasicQuery(queryString);
- return findAllByQuery(query, clazz);
- }
-
- @Override
- public Page findByQuery(Query query, Class clazz, Pageable pageable) {
- return null;
- }
-
- @Override
- public Page findByQuery(String queryString, Class clazz, Pageable pageable) {
- Query query = new BasicQuery(queryString).with(pageable);
- return new PageImpl<>(mongoTemplate.find(query, clazz),
- pageable,
- mongoTemplate.count(new BasicQuery(queryString, "{_id:1}"), clazz));
- }
-
- @Override
- public List findAllByQuery(Query query, Class clazz) {
- return mongoTemplate.find(query, clazz);
- }
-
-}
+//@Service
+//public class HistoryService implements IHistoryService {
+// protected String clazz = "', _class: '";
+//
+// @Autowired
+// private EventLogRepository eventLogRepository;
+//
+// @Autowired
+// private MongoTemplate mongoTemplate;
+//
+// @Override
+// @Async
+// public void save(EventLog eventLog) {
+// eventLogRepository.save(eventLog);
+// }
+//
+// @Override
+// public List findAllByIds(List eventIds) {
+// return eventLogRepository.findAllById(eventIds);
+// }
+//
+// @Override
+// public List findAllCreateCaseEventLogsByCaseId(ObjectId caseId) {
+// return findAllByCaseId(caseId.toString(), CreateCaseEventLog.class);
+// }
+//
+// @Override
+// public List findAllDeleteCaseEventLogsByCaseId(ObjectId caseId) {
+// return findAllByCaseId(caseId.toString(), DeleteCaseEventLog.class);
+// }
+//
+// @Override
+// public List findAllCreateCaseEventLogsByCaseId(String caseId) {
+// return findAllByCaseId(caseId, CreateCaseEventLog.class);
+// }
+//
+// @Override
+// public List findAllDeleteCaseEventLogsByCaseId(String caseId) {
+// return findAllByCaseId(caseId, DeleteCaseEventLog.class);
+// }
+//
+// @Override
+// public List findAllGetDataEventLogsByCaseId(ObjectId caseId) {
+// return findAllByCaseId(caseId.toString(), GetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllGetDataEventLogsByTaskId(ObjectId taskId) {
+// return findAllByTaskId(taskId.toString(), GetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllGetDataEventLogsByCaseId(String caseId) {
+// return findAllByCaseId(caseId, GetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllGetDataEventLogsByTaskId(String taskId) {
+// return findAllByTaskId(taskId, GetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllSetDataEventLogsByCaseId(ObjectId caseId) {
+// return findAllByCaseId(caseId.toString(), SetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllSetDataEventLogsByCaseId(String caseId) {
+// return findAllByCaseId(caseId, SetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllSetDataEventLogsByTaskId(ObjectId taskId) {
+// return findAllByTaskId(taskId.toString(), SetDataEventLog.class);
+// }
+//
+//
+// @Override
+// public List findAllSetDataEventLogsByTaskId(String taskId) {
+// return findAllByTaskId(taskId, SetDataEventLog.class);
+// }
+//
+// @Override
+// public List findAllImportPetriNetEventLogsByNetId(ObjectId netId) {
+// return findAllByNetId(netId, ImportPetriNetEventLog.class);
+// }
+//
+// @Override
+// public List findAllAssignTaskEventLogsByTaskId(ObjectId taskId) {
+// return findAllByTaskId(taskId.toString(), AssignTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllAssignTaskEventLogsByTaskId(String taskId) {
+// return findAllByTaskId(taskId, AssignTaskEventLog.class);
+// }
+//
+//
+// @Override
+// public List findAllAssignTaskEventLogsByUserId(String userId) {
+// return findAllByUserId(userId, AssignTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllAssignTaskEventLogsByCaseId(String caseId) {
+// return findAllByCaseId(caseId, AssignTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllCancelTaskEventLogsByTaskId(String taskId) {
+// return findAllByTaskId(taskId, CancelTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllCancelTaskEventLogsByTaskId(ObjectId taskId) {
+// return findAllByTaskId(taskId.toString(), CancelTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllCancelTaskEventLogsByUserId(String userId) {
+// return findAllByUserId(userId, CancelTaskEventLog.class);
+// }
+//
+//
+// @Override
+// public List findAllFinishTaskEventLogsByTaskId(String taskId) {
+// return findAllByTaskId(taskId, FinishTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllFinishTaskEventLogsByTaskId(ObjectId taskId) {
+// return findAllByTaskId(taskId.toString(), FinishTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllFinishTaskEventLogsByUserId(String userId) {
+// return findAllByUserId(userId, FinishTaskEventLog.class);
+// }
+//
+// @Override
+// public List findAllFinishTaskEventLogsByCaseId(String caseId) {
+// return findAllByCaseId(caseId, FinishTaskEventLog.class);
+// }
+//
+// @Override
+// public Page findByUserId(String id, Class clazz, Pageable pageable) {
+// String queryString = "{userId: '" + id + this.clazz + clazz.getName() + "'}";
+// return findByQuery(queryString, clazz, pageable);
+// }
+//
+// @Override
+// public List findAllByUserId(String id, Class clazz) {
+// String queryString = "{userId: '" + id + this.clazz + clazz.getName() + "'}";
+// Query query = new BasicQuery(queryString);
+// return findAllByQuery(query, clazz);
+// }
+//
+// @Override
+// public Page findByNetId(String id, Class clazz, Pageable pageable) {
+// return findByNetId(new ObjectId(id), clazz, pageable);
+// }
+//
+// @Override
+// public List findAllByNetId(String id, Class clazz) {
+// return findAllByNetId(new ObjectId(id), clazz);
+// }
+//
+// @Override
+// public Page findByNetId(ObjectId id, Class clazz, Pageable pageable) {
+// String queryString = "{netId: '" + id + this.clazz + clazz.getName() + "'}";
+// return findByQuery(queryString, clazz, pageable);
+// }
+//
+// @Override
+// public List findAllByNetId(ObjectId id, Class clazz) {
+// String queryString = "{netId: '" + id + this.clazz + clazz.getName() + "'}";
+// Query query = new BasicQuery(queryString);
+// return findAllByQuery(query, clazz);
+// }
+//
+// @Override
+// public Page findByTaskId(String id, Class clazz) {
+// return null;
+// }
+//
+// @Override
+// public Page findByTaskId(String id, Class clazz, Pageable pageable) {
+// String queryString = "{taskId: '" + id + this.clazz + clazz.getName() + "'}";
+// return findByQuery(queryString, clazz, pageable);
+// }
+//
+// @Override
+// public List findAllByTaskId(String id, Class clazz) {
+// String queryString = "{taskId: '" + id + this.clazz + clazz.getName() + "'}";
+// Query query = new BasicQuery(queryString);
+// return findAllByQuery(query, clazz);
+// }
+//
+// @Override
+// public Page findByCaseId(String id, Class clazz, Pageable pageable) {
+// String queryString = "{caseId: '" + id + this.clazz + clazz.getName() + "'}";
+// return findByQuery(queryString, clazz, pageable);
+// }
+//
+// @Override
+// public List findAllByCaseId(String id, Class clazz) {
+// String queryString = "{caseId: '" + id + this.clazz + clazz.getName() + "'}";
+// Query query = new BasicQuery(queryString);
+// return findAllByQuery(query, clazz);
+// }
+//
+// @Override
+// public Page findByQuery(Query query, Class clazz, Pageable pageable) {
+// return null;
+// }
+//
+// @Override
+// public Page findByQuery(String queryString, Class clazz, Pageable pageable) {
+// Query query = new BasicQuery(queryString).with(pageable);
+// return new PageImpl<>(mongoTemplate.find(query, clazz),
+// pageable,
+// mongoTemplate.count(new BasicQuery(queryString, "{_id:1}"), clazz));
+// }
+//
+// @Override
+// public List findAllByQuery(Query query, Class clazz) {
+// return mongoTemplate.find(query, clazz);
+// }
+
+//}
diff --git a/src/main/java/com/netgrif/application/engine/history/service/listener/CaseEventListener.java b/src/main/java/com/netgrif/application/engine/history/service/listener/CaseEventListener.java
new file mode 100644
index 00000000000..06e939a4b64
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/history/service/listener/CaseEventListener.java
@@ -0,0 +1,46 @@
+package com.netgrif.application.engine.history.service.listener;
+
+import com.netgrif.application.engine.event.dispatchers.CaseDispatcher;
+import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
+import com.netgrif.application.engine.event.events.workflow.CreateCaseEvent;
+import com.netgrif.application.engine.event.events.workflow.DeleteCaseEvent;
+import com.netgrif.application.engine.event.listeners.Listener;
+import com.netgrif.application.engine.history.domain.caseevents.CreateCaseEventLog;
+import com.netgrif.application.engine.history.domain.caseevents.DeleteCaseEventLog;
+import com.netgrif.application.engine.history.domain.caseevents.repository.CreateCaseEventLogRepository;
+import com.netgrif.application.engine.history.domain.caseevents.repository.DeleteCaseEventLogRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.EventObject;
+import java.util.Set;
+
+@Component
+public class CaseEventListener extends Listener {
+ private final CreateCaseEventLogRepository createCaseEventLogRepository;
+ private final DeleteCaseEventLogRepository deleteCaseEventLogRepository;
+
+ public CaseEventListener(CaseDispatcher dispatcher,
+ CreateCaseEventLogRepository createCaseEventLogRepository,
+ DeleteCaseEventLogRepository deleteCaseEventLogRepository) {
+ this.createCaseEventLogRepository = createCaseEventLogRepository;
+ this.deleteCaseEventLogRepository = deleteCaseEventLogRepository;
+ this.registerAll(dispatcher,
+ Set.of(CreateCaseEvent.class,
+ DeleteCaseEvent.class),
+ AbstractDispatcher.DispatchMethod.ASYNC);
+ }
+
+ @Override
+ public void onAsyncEvent(EventObject event, AbstractDispatcher dispatcher) {
+ if (event instanceof CreateCaseEvent) {
+ createCaseEventLogRepository.save(CreateCaseEventLog.fromEvent((CreateCaseEvent) event));
+ } else if (event instanceof DeleteCaseEvent) {
+ deleteCaseEventLogRepository.save(DeleteCaseEventLog.fromEvent((DeleteCaseEvent) event));
+ }
+ }
+
+ @Override
+ public void onEvent(EventObject event, AbstractDispatcher dispatcher) {
+ //do nothing
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/history/service/listener/UserEventListener.java b/src/main/java/com/netgrif/application/engine/history/service/listener/UserEventListener.java
index ba56de40fd5..5a90ed0a752 100644
--- a/src/main/java/com/netgrif/application/engine/history/service/listener/UserEventListener.java
+++ b/src/main/java/com/netgrif/application/engine/history/service/listener/UserEventListener.java
@@ -1,44 +1,46 @@
package com.netgrif.application.engine.history.service.listener;
+import com.netgrif.application.engine.event.dispatchers.UserDispatcher;
+import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
import com.netgrif.application.engine.event.events.user.*;
-import com.netgrif.application.engine.history.domain.baseevent.repository.EventLogRepository;
-import com.netgrif.application.engine.history.domain.userevents.AdminActionEventLog;
-import com.netgrif.application.engine.history.domain.userevents.UserEventLog;
-import com.netgrif.application.engine.history.domain.userevents.UserRoleEventLog;
-import org.springframework.context.event.EventListener;
+import com.netgrif.application.engine.event.listeners.Listener;
import org.springframework.stereotype.Component;
-@Component
-public class UserEventListener {
-
- private final EventLogRepository repository;
-
- public UserEventListener(EventLogRepository repository) {
- this.repository = repository;
- }
+import java.util.EventObject;
+import java.util.Set;
- @EventListener
- public void onUserLoginEvent(UserLoginEvent event) {
- repository.save(new UserEventLog(event.getUser().getUsername()));
- }
-
- @EventListener
- public void onUserLogoutEvent(UserLogoutEvent event) {
- repository.save(new UserEventLog(event.getUser().getUsername()));
+@Component
+public class UserEventListener extends Listener {
+
+ public UserEventListener(UserDispatcher dispatcher) {
+ this.registerAll(dispatcher,
+ Set.of(UserLoginEvent.class,
+ UserLogoutEvent.class,
+ UserRoleChangeEvent.class,
+ UserRegistrationEvent.class,
+ AdminActionEvent.class),
+ AbstractDispatcher.DispatchMethod.ASYNC);
}
- @EventListener
- public void onUserRegistrationEvent(UserRegistrationEvent event) {
- repository.save(new UserEventLog(event.getUser().getUsername()));
- }
+ @Override
+ public void onEvent(EventObject event, AbstractDispatcher dispatcher) {
- @EventListener
- public void onUserRoleChangeEvent(UserRoleChangeEvent event) {
- repository.save(new UserRoleEventLog(event.getUser().getUsername(), event.getRoles()));
+ //do nothing
}
- @EventListener
- public void onAdminActionEvent(AdminActionEvent event) {
- repository.save(new AdminActionEventLog(event));
+ @Override
+ public void onAsyncEvent(EventObject event, AbstractDispatcher dispatcher) {
+ //todo
+ if (event instanceof UserLoginEvent) {
+ // repository.save()
+ } else if (event instanceof UserLogoutEvent) {
+ // repository.save()
+ } else if (event instanceof UserRoleChangeEvent) {
+ // repository.save()
+ } else if (event instanceof UserRegistrationEvent) {
+
+ } else if (event instanceof AdminActionEvent) {
+ // ??
+ }
}
}
diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java
index 95f940e7ed9..5be556f14f7 100644
--- a/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java
+++ b/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java
@@ -144,7 +144,7 @@ public GetDataEventOutcome getData(Task task, Case useCase, Map
return;
Field field = useCase.getPetriNet().getField(fieldId).get();
outcome.addOutcomes(resolveDataEvents(field, DataEventType.GET, EventPhase.PRE, useCase, task, params));
- historyService.save(new GetDataEventLog(task, useCase, EventPhase.PRE, user));
+// historyService.save(new GetDataEventLog(task, useCase, EventPhase.PRE, user));
if (outcome.getMessage() == null) {
Map dataSet = useCase.getPetriNet().getTransition(task.getTransitionId()).getDataSet();
@@ -177,7 +177,7 @@ public GetDataEventOutcome getData(Task task, Case useCase, Map
}
}
outcome.addOutcomes(resolveDataEvents(field, DataEventType.GET, EventPhase.POST, useCase, task, params));
- historyService.save(new GetDataEventLog(task, useCase, EventPhase.POST, user));
+// historyService.save(new GetDataEventLog(task, useCase, EventPhase.POST, user));
});
workflowService.save(useCase);
@@ -192,7 +192,7 @@ public GetDataEventOutcome getData(Task task, Case useCase, Map
LongStream.range(0L, dataSetFields.size())
.forEach(index -> dataSetFields.get((int) index).setOrder(index));
outcome.setData(dataSetFields);
- publisher.publishEvent(new GetDataEvent(outcome));
+ publisher.publishEvent(new GetDataEvent(outcome, user));
return outcome;
}
diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
index 8a125be5a37..60ea8f79a82 100644
--- a/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
+++ b/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
@@ -7,9 +7,6 @@
import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskMappingService;
import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService;
import com.netgrif.application.engine.event.events.task.*;
-import com.netgrif.application.engine.history.domain.taskevents.AssignTaskEventLog;
-import com.netgrif.application.engine.history.domain.taskevents.CancelTaskEventLog;
-import com.netgrif.application.engine.history.domain.taskevents.DelegateTaskEventLog;
import com.netgrif.application.engine.history.domain.taskevents.FinishTaskEventLog;
import com.netgrif.application.engine.history.service.IHistoryService;
import com.netgrif.application.engine.petrinet.domain.*;
@@ -24,7 +21,6 @@
import com.netgrif.application.engine.petrinet.domain.roles.ProcessRole;
import com.netgrif.application.engine.petrinet.domain.throwable.TransitionNotExecutableException;
import com.netgrif.application.engine.petrinet.service.interfaces.IProcessRoleService;
-
import com.netgrif.application.engine.utils.DateUtils;
import com.netgrif.application.engine.utils.FullPageRequest;
import com.netgrif.application.engine.validation.service.interfaces.IValidationService;
@@ -172,14 +168,14 @@ public AssignTaskEventOutcome assignTask(Task task, IUser user, Map
Date: Sun, 2 Feb 2025 16:33:13 +0100
Subject: [PATCH 35/92] [NAE-2045] Event log as event system module - Events
now are subclass of EventObject - Added new Event ImpersonationEvent -
Reverted back changes for second Elasticsearch connection - Annotated
HistoryService as deprecated, replaced by AuditLog module - Added javadocs
for new Event registration
---
docker-compose.yml | 20 -
.../ElasticsearchConfiguration.java | 16 +-
.../ElasticsearchHistoryConfiguration.java | 20 -
.../event/dispatchers/UserDispatcher.java | 13 +-
.../engine/event/evaluators/Evaluator.java | 4 +-
.../engine/event/events/Event.java | 4 +-
.../event/events/user/ImpersonationEvent.java | 23 +
.../event/events/user/ImpersonationPhase.java | 6 +
.../event/listeners/AuthEventListener.java | 1 -
.../engine/event/listeners/Listener.java | 28 +-
.../event/publishers/NaeEventPublisher.java | 2 +-
.../EventLogRepositoryConfiguration.java | 9 -
.../domain/taskevents/CancelTaskEventLog.java | 2 -
.../userevents/AdminActionEventLog.java | 3 +-
.../history/service/HistoryService.java | 485 +++++++++---------
.../history/service/IHistoryService.java | 1 +
.../service/listener/DataEventListener.java | 46 ++
.../service/listener/ModelEventListener.java | 0
.../service/ImpersonationService.java | 25 +-
.../petrinet/service/PetriNetService.java | 1 +
20 files changed, 392 insertions(+), 317 deletions(-)
delete mode 100644 src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java
create mode 100644 src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationEvent.java
create mode 100644 src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationPhase.java
delete mode 100644 src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java
create mode 100644 src/main/java/com/netgrif/application/engine/history/service/listener/DataEventListener.java
delete mode 100644 src/main/java/com/netgrif/application/engine/history/service/listener/ModelEventListener.java
diff --git a/docker-compose.yml b/docker-compose.yml
index cf4c1e594e5..3e275c95c1a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -33,26 +33,6 @@ services:
reservations:
cpus: "0.5"
memory: "512M"
-# Zmensit resources
- docker-elastic-history:
- image: elasticsearch:8.15.3
- environment:
- - cluster.name=elasticsearch
- - discovery.type=single-node
- - http.host=0.0.0.0
- - xpack.security.enabled=false
- - transport.host=0.0.0.0
- ports:
- - "9201:9200"
- - "9301:9300"
- deploy:
- resources:
- limits:
- cpus: "2"
- memory: "2G"
- reservations:
- cpus: "0.5"
- memory: "512M"
docker-redis:
image: redis:7.4.1
diff --git a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java
index dd6949c37df..ed26689b92d 100644
--- a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java
+++ b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchConfiguration.java
@@ -19,7 +19,7 @@
@EnableElasticsearchRepositories(excludeFilters = {
@ComponentScan.Filter(
type = FilterType.REGEX,
- pattern = "com\\.netgrif\\.application\\.engine\\.history\\.domain\\..*"
+ pattern = "com\\.netgrif\\.application\\.engine\\.module\\..*"
)
})
public class ElasticsearchConfiguration extends org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration {
@@ -105,18 +105,4 @@ public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter el
return super.elasticsearchOperations(elasticsearchConverter, elasticsearchClient);
}
- @Bean
- @Qualifier("historyCluster")
- public ElasticsearchOperations elasticsearchHistoryOperations(ElasticsearchConverter elasticsearchConverter) {
- ElasticsearchHistoryConfiguration elasticsearchConfiguration = new ElasticsearchHistoryConfiguration();
- ClientConfiguration clientConfiguration = elasticsearchConfiguration.clientConfiguration();
- RestClient restClient = elasticsearchConfiguration.elasticsearchRestClient(clientConfiguration);
- ElasticsearchTransport transport = new RestClientTransport(
- restClient,
- new JacksonJsonpMapper()
- );
- ElasticsearchClient elasticsearchClient = elasticsearchClient(transport);
-
- return elasticsearchConfiguration.elasticsearchOperations(elasticsearchConverter, elasticsearchClient);
- }
}
diff --git a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java b/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java
deleted file mode 100644
index 6c6e5950786..00000000000
--- a/src/main/java/com/netgrif/application/engine/configuration/ElasticsearchHistoryConfiguration.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.netgrif.application.engine.configuration;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.elasticsearch.client.ClientConfiguration;
-
-public class ElasticsearchHistoryConfiguration extends org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration {
-
- @Value("${spring.data.elasticsearch.history.url}")
- private String url;
-
- @Value("${spring.data.elasticsearch.history.searchport}")
- private int port;
-
- @Override
- public ClientConfiguration clientConfiguration() {
- return ClientConfiguration.builder()
- .connectedTo(url + ":" + port)
- .build();
- }
-}
diff --git a/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java b/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java
index 5890267d8b7..6727555523e 100644
--- a/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java
+++ b/src/main/java/com/netgrif/application/engine/event/dispatchers/UserDispatcher.java
@@ -15,7 +15,8 @@ public UserDispatcher() {
UserLogoutEvent.class,
UserRegistrationEvent.class,
UserRoleChangeEvent.class,
- AdminActionEvent.class
+ AdminActionEvent.class,
+ ImpersonationEvent.class
));
}
@@ -68,4 +69,14 @@ public void handleUserRoleChangeEvent(AdminActionEvent event) {
public void handleAsyncUseRoleChangeEvent(AdminActionEvent event) {
dispatchAsync(event);
}
+
+ @EventListener
+ public void handleUserImpersonationEvent(ImpersonationEvent event) {
+ dispatch(event);
+ }
+
+ @EventListener
+ public void handleAsyncUserImpersonationEvent(ImpersonationEvent event) {
+ dispatchAsync(event);
+ }
}
diff --git a/src/main/java/com/netgrif/application/engine/event/evaluators/Evaluator.java b/src/main/java/com/netgrif/application/engine/event/evaluators/Evaluator.java
index 256a39fd5e4..6da0c834b25 100644
--- a/src/main/java/com/netgrif/application/engine/event/evaluators/Evaluator.java
+++ b/src/main/java/com/netgrif/application/engine/event/evaluators/Evaluator.java
@@ -1,11 +1,11 @@
package com.netgrif.application.engine.event.evaluators;
import lombok.Getter;
-import org.springframework.context.ApplicationEvent;
+import java.util.EventObject;
import java.util.function.Function;
-public class Evaluator {
+public class Evaluator {
@Getter
private final String type;
private final Function evaluationFunction;
diff --git a/src/main/java/com/netgrif/application/engine/event/events/Event.java b/src/main/java/com/netgrif/application/engine/event/events/Event.java
index bebdd6357e6..ed6803afaf6 100644
--- a/src/main/java/com/netgrif/application/engine/event/events/Event.java
+++ b/src/main/java/com/netgrif/application/engine/event/events/Event.java
@@ -2,12 +2,12 @@
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import lombok.Getter;
-import org.springframework.context.ApplicationEvent;
import java.io.Serial;
import java.time.LocalDateTime;
+import java.util.EventObject;
-public abstract class Event extends ApplicationEvent {
+public abstract class Event extends EventObject {
@Serial
private static final long serialVersionUID = -9102232475981679124L;
@Getter
diff --git a/src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationEvent.java b/src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationEvent.java
new file mode 100644
index 00000000000..158ef652df1
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationEvent.java
@@ -0,0 +1,23 @@
+package com.netgrif.application.engine.event.events.user;
+
+import com.netgrif.application.engine.auth.domain.LoggedUser;
+import lombok.Getter;
+
+public class ImpersonationEvent extends UserEvent {
+
+ @Getter
+ private LoggedUser impersonated;
+
+ private final ImpersonationPhase impersonationPhase;
+
+ public ImpersonationEvent(LoggedUser user, LoggedUser impersonated, ImpersonationPhase impersonationPhase) {
+ super(user);
+ this.impersonated = impersonated;
+ this.impersonationPhase = impersonationPhase;
+ }
+
+ @Override
+ public String getMessage() {
+ return "User " + user.getUsername() + " is impersonating: " + impersonated.getUsername() + " phase: " + impersonationPhase;
+ }
+}
diff --git a/src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationPhase.java b/src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationPhase.java
new file mode 100644
index 00000000000..4a37b352f36
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/event/events/user/ImpersonationPhase.java
@@ -0,0 +1,6 @@
+package com.netgrif.application.engine.event.events.user;
+
+public enum ImpersonationPhase {
+ START,
+ STOP
+}
diff --git a/src/main/java/com/netgrif/application/engine/event/listeners/AuthEventListener.java b/src/main/java/com/netgrif/application/engine/event/listeners/AuthEventListener.java
index 63807bfa294..91569a7bcbf 100644
--- a/src/main/java/com/netgrif/application/engine/event/listeners/AuthEventListener.java
+++ b/src/main/java/com/netgrif/application/engine/event/listeners/AuthEventListener.java
@@ -52,6 +52,5 @@ public void onEvent(EventObject event, AbstractDispatcher dispatcher) {
// do nothing
}
-
}
diff --git a/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java b/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java
index 64043027be6..6e92a6398ac 100644
--- a/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java
+++ b/src/main/java/com/netgrif/application/engine/event/listeners/Listener.java
@@ -3,7 +3,6 @@
import com.netgrif.application.engine.event.dispatchers.common.AbstractDispatcher;
import com.netgrif.application.engine.event.events.Event;
-import com.netgrif.application.engine.event.events.EventAction;
import lombok.Getter;
import java.util.EventListener;
@@ -30,14 +29,37 @@ public void register(AbstractDispatcher dispatcher, Class extends EventObject>
dispatcher.registerListener(this, event, dispatchMethod);
}
+ /**
+ * Register this listener to dispatcher.
+ *
+ * @param dispatcher Dispatcher, to listen Events
+ * @param events Set of Events that the listener will listen to
+ * @param dispatchMethod synchronous or asynchronous
+ */
public void registerAll(AbstractDispatcher dispatcher, Set> events, AbstractDispatcher.DispatchMethod dispatchMethod) {
events.forEach(event -> dispatcher.registerListener(this, event, dispatchMethod));
}
+ /**
+ * Unregister this listener to dispatcher.
+ *
+ * @param dispatcher Dispatcher, from which listener will be unsubscribed
+ * @param event Clas of event, from which this Listener will be unsubscribed
+ * @param dispatchMethod synchronous or asynchronous
+ * @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
+ */
public void unregister(AbstractDispatcher dispatcher, Class extends EventObject> event, AbstractDispatcher.DispatchMethod dispatchMethod) {
dispatcher.unregisterListener(this, event, dispatchMethod);
}
+ /**
+ * Unregister this listener to dispatcher.
+ *
+ * @param dispatcher Dispatcher, from which listener will be unsubscribed
+ * @param events Set of Events from which this Listener will be unsubscribed
+ * @param dispatchMethod synchronous or asynchronous
+ * @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
+ */
public void unregisterAll(AbstractDispatcher dispatcher, Set> events, AbstractDispatcher.DispatchMethod dispatchMethod) {
events.forEach(event -> dispatcher.unregisterListener(this, event, dispatchMethod));
}
@@ -45,7 +67,7 @@ public void unregisterAll(AbstractDispatcher dispatcher, SetAbstract method for handling synchronous events. This method will be invoked by Dispatcher if the Listener is registered.
*
- * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
+ * @param event {@link Event} object, final type of the object is determined based on registered events
* @param dispatcher {@link AbstractDispatcher} from which the event was dispatched
* @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
*/
@@ -54,7 +76,7 @@ public void unregisterAll(AbstractDispatcher dispatcher, SetAbstract method for handling asynchronous events. This method will be invoked by Dispatcher if the Listener is registered.
*
- * @param event {@link Event} object, final type of the object is determined based on {@link EventAction}
+ * @param event {@link Event} object, final type of the object is determined based on registered events
* @param dispatcher {@link AbstractDispatcher} from which the event was dispatched
* @see AbstractDispatcher#registerListener(Listener, Class, AbstractDispatcher.DispatchMethod)
*/
diff --git a/src/main/java/com/netgrif/application/engine/event/publishers/NaeEventPublisher.java b/src/main/java/com/netgrif/application/engine/event/publishers/NaeEventPublisher.java
index de88755e8ef..82ea7731873 100644
--- a/src/main/java/com/netgrif/application/engine/event/publishers/NaeEventPublisher.java
+++ b/src/main/java/com/netgrif/application/engine/event/publishers/NaeEventPublisher.java
@@ -28,7 +28,7 @@ protected NaeEventPublisher(ApplicationEventPublisher applicationEventPublisher)
* @param event - the NaeEvent instance (can be extended class), that contains the source object;
* */
public void publish(Event event) {
- log.info("Publishing event " + event.getTimestamp());
+ log.info("Publishing event {}", event.getTime());
this.applicationEventPublisher.publishEvent(event);
}
}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java b/src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java
deleted file mode 100644
index d68fb38d6b3..00000000000
--- a/src/main/java/com/netgrif/application/engine/history/domain/EventLogRepositoryConfiguration.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.netgrif.application.engine.history.domain;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
-
-@Configuration
-@EnableElasticsearchRepositories(elasticsearchTemplateRef = "historyCluster")
-public class EventLogRepositoryConfiguration {
-}
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java
index 25e0eb9f0e8..45ada771599 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/taskevents/CancelTaskEventLog.java
@@ -1,13 +1,11 @@
package com.netgrif.application.engine.history.domain.taskevents;
import com.netgrif.application.engine.auth.domain.IUser;
-import com.netgrif.application.engine.event.events.task.AssignTaskEvent;
import com.netgrif.application.engine.event.events.task.CancelTaskEvent;
import com.netgrif.application.engine.petrinet.domain.events.EventPhase;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.Task;
import lombok.EqualsAndHashCode;
-import org.springframework.data.mongodb.core.mapping.Document;
@EqualsAndHashCode(callSuper = true)
public class CancelTaskEventLog extends TaskEventLog {
diff --git a/src/main/java/com/netgrif/application/engine/history/domain/userevents/AdminActionEventLog.java b/src/main/java/com/netgrif/application/engine/history/domain/userevents/AdminActionEventLog.java
index 5704e29156f..1c9045abcd7 100644
--- a/src/main/java/com/netgrif/application/engine/history/domain/userevents/AdminActionEventLog.java
+++ b/src/main/java/com/netgrif/application/engine/history/domain/userevents/AdminActionEventLog.java
@@ -5,8 +5,7 @@
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.mongodb.core.mapping.Document;
-@TypeAlias("adminActionEventLog")
-@Document(collection = "eventLogs")
+
public class AdminActionEventLog extends UserEventLog {
@Getter
diff --git a/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java b/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java
index 2be237dcb12..2e877575eea 100644
--- a/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java
+++ b/src/main/java/com/netgrif/application/engine/history/service/HistoryService.java
@@ -1,236 +1,261 @@
package com.netgrif.application.engine.history.service;
+import com.netgrif.application.engine.history.domain.baseevent.EventLog;
+import com.netgrif.application.engine.history.domain.baseevent.repository.EventLogRepository;
+import com.netgrif.application.engine.history.domain.caseevents.CreateCaseEventLog;
+import com.netgrif.application.engine.history.domain.caseevents.DeleteCaseEventLog;
+import com.netgrif.application.engine.history.domain.dataevents.GetDataEventLog;
+import com.netgrif.application.engine.history.domain.dataevents.SetDataEventLog;
+import com.netgrif.application.engine.history.domain.petrinetevents.DeletePetriNetEventLog;
+import com.netgrif.application.engine.history.domain.petrinetevents.ImportPetriNetEventLog;
+import com.netgrif.application.engine.history.domain.taskevents.AssignTaskEventLog;
+import com.netgrif.application.engine.history.domain.taskevents.CancelTaskEventLog;
+import com.netgrif.application.engine.history.domain.taskevents.FinishTaskEventLog;
+import org.bson.types.ObjectId;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.BasicQuery;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
-//@Service
-//public class HistoryService implements IHistoryService {
-// protected String clazz = "', _class: '";
-//
-// @Autowired
-// private EventLogRepository eventLogRepository;
-//
-// @Autowired
-// private MongoTemplate mongoTemplate;
-//
-// @Override
-// @Async
-// public void save(EventLog eventLog) {
-// eventLogRepository.save(eventLog);
-// }
-//
-// @Override
-// public List findAllByIds(List eventIds) {
-// return eventLogRepository.findAllById(eventIds);
-// }
-//
-// @Override
-// public List findAllCreateCaseEventLogsByCaseId(ObjectId caseId) {
-// return findAllByCaseId(caseId.toString(), CreateCaseEventLog.class);
-// }
-//
-// @Override
-// public List findAllDeleteCaseEventLogsByCaseId(ObjectId caseId) {
-// return findAllByCaseId(caseId.toString(), DeleteCaseEventLog.class);
-// }
-//
-// @Override
-// public List findAllCreateCaseEventLogsByCaseId(String caseId) {
-// return findAllByCaseId(caseId, CreateCaseEventLog.class);
-// }
-//
-// @Override
-// public List findAllDeleteCaseEventLogsByCaseId(String caseId) {
-// return findAllByCaseId(caseId, DeleteCaseEventLog.class);
-// }
-//
-// @Override
-// public List findAllGetDataEventLogsByCaseId(ObjectId caseId) {
-// return findAllByCaseId(caseId.toString(), GetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllGetDataEventLogsByTaskId(ObjectId taskId) {
-// return findAllByTaskId(taskId.toString(), GetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllGetDataEventLogsByCaseId(String caseId) {
-// return findAllByCaseId(caseId, GetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllGetDataEventLogsByTaskId(String taskId) {
-// return findAllByTaskId(taskId, GetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllSetDataEventLogsByCaseId(ObjectId caseId) {
-// return findAllByCaseId(caseId.toString(), SetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllSetDataEventLogsByCaseId(String caseId) {
-// return findAllByCaseId(caseId, SetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllSetDataEventLogsByTaskId(ObjectId taskId) {
-// return findAllByTaskId(taskId.toString(), SetDataEventLog.class);
-// }
-//
-//
-// @Override
-// public List findAllSetDataEventLogsByTaskId(String taskId) {
-// return findAllByTaskId(taskId, SetDataEventLog.class);
-// }
-//
-// @Override
-// public List findAllImportPetriNetEventLogsByNetId(ObjectId netId) {
-// return findAllByNetId(netId, ImportPetriNetEventLog.class);
-// }
-//
-// @Override
-// public List findAllAssignTaskEventLogsByTaskId(ObjectId taskId) {
-// return findAllByTaskId(taskId.toString(), AssignTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllAssignTaskEventLogsByTaskId(String taskId) {
-// return findAllByTaskId(taskId, AssignTaskEventLog.class);
-// }
-//
-//
-// @Override
-// public List findAllAssignTaskEventLogsByUserId(String userId) {
-// return findAllByUserId(userId, AssignTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllAssignTaskEventLogsByCaseId(String caseId) {
-// return findAllByCaseId(caseId, AssignTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllCancelTaskEventLogsByTaskId(String taskId) {
-// return findAllByTaskId(taskId, CancelTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllCancelTaskEventLogsByTaskId(ObjectId taskId) {
-// return findAllByTaskId(taskId.toString(), CancelTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllCancelTaskEventLogsByUserId(String userId) {
-// return findAllByUserId(userId, CancelTaskEventLog.class);
-// }
-//
-//
-// @Override
-// public List findAllFinishTaskEventLogsByTaskId(String taskId) {
-// return findAllByTaskId(taskId, FinishTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllFinishTaskEventLogsByTaskId(ObjectId taskId) {
-// return findAllByTaskId(taskId.toString(), FinishTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllFinishTaskEventLogsByUserId(String userId) {
-// return findAllByUserId(userId, FinishTaskEventLog.class);
-// }
-//
-// @Override
-// public List findAllFinishTaskEventLogsByCaseId(String caseId) {
-// return findAllByCaseId(caseId, FinishTaskEventLog.class);
-// }
-//
-// @Override
-// public Page findByUserId(String id, Class clazz, Pageable pageable) {
-// String queryString = "{userId: '" + id + this.clazz + clazz.getName() + "'}";
-// return findByQuery(queryString, clazz, pageable);
-// }
-//
-// @Override
-// public List findAllByUserId(String id, Class clazz) {
-// String queryString = "{userId: '" + id + this.clazz + clazz.getName() + "'}";
-// Query query = new BasicQuery(queryString);
-// return findAllByQuery(query, clazz);
-// }
-//
-// @Override
-// public Page findByNetId(String id, Class clazz, Pageable pageable) {
-// return findByNetId(new ObjectId(id), clazz, pageable);
-// }
-//
-// @Override
-// public List findAllByNetId(String id, Class clazz) {
-// return findAllByNetId(new ObjectId(id), clazz);
-// }
-//
-// @Override
-// public