diff --git a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/pom.xml b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/pom.xml
index 6ba6d03fff..50cf77d824 100644
--- a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/pom.xml
+++ b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/pom.xml
@@ -28,6 +28,10 @@
org.jbpm
jbpm-executor
+
+ org.jbpm
+ jbpm-runtime-manager
+
org.jboss.spec.javax.ejb
jboss-ejb-api_3.2_spec
@@ -58,6 +62,11 @@
infinispan-core
provided
+
+ org.infinispan
+ infinispan-clustered-lock
+ provided
+
javax.annotation
diff --git a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/EJBCacheInitializer.java b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/EJBCacheBean.java
similarity index 86%
rename from kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/EJBCacheInitializer.java
rename to kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/EJBCacheBean.java
index 3eb99298f9..e995198ccf 100644
--- a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/EJBCacheInitializer.java
+++ b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/EJBCacheBean.java
@@ -32,7 +32,7 @@
@Singleton
@Startup
-public class EJBCacheInitializer {
+public class EJBCacheBean {
public static final String CACHE_NAME_LOOKUP = "java:jboss/infinispan/container/jbpm";
@@ -41,6 +41,10 @@ public class EJBCacheInitializer {
public static final String CACHE_JOBS_NAME_LOOKUP = "java:jboss/infinispan/cache/jbpm/jobs";
// this enforce the cache initializer
+ public static final String CACHE_LOCKS_NAME_LOOKUP = "java:jboss/infinispan/cache/jbpm";
+
+ @Resource(lookup = CACHE_LOCKS_NAME_LOOKUP)
+ private EmbeddedCacheManager cacheContainer;
@Resource(lookup = CACHE_NAME_LOOKUP)
private EmbeddedCacheManager cacheManager;
@@ -57,4 +61,9 @@ public void init() {
((InfinispanClusterAwareService) clusterService).init(cacheManager);
}
+
+ public EmbeddedCacheManager getCacheContainer() {
+ return cacheContainer;
+ }
+
}
diff --git a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/lock/ClusteredRuntimeManagerLock.java b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/lock/ClusteredRuntimeManagerLock.java
new file mode 100644
index 0000000000..1976afb14a
--- /dev/null
+++ b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/lock/ClusteredRuntimeManagerLock.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2021 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.kie.server.services.jbpm.cluster.lock;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.lock.api.ClusteredLockManager;
+import org.jbpm.runtime.manager.spi.RuntimeManagerLock;
+import org.jgroups.util.UUID;
+
+
+public class ClusteredRuntimeManagerLock implements RuntimeManagerLock {
+
+ private String clusteredLockId;
+
+ private ClusteredLockManager clusteredLockManager;
+
+ public ClusteredRuntimeManagerLock(ClusteredLockManager clusteredLockManager) {
+ this.clusteredLockManager = clusteredLockManager;
+ clusteredLockId = UUID.randomUUID().toString();
+ this.clusteredLockManager.defineLock(clusteredLockId);
+ }
+
+ @Override
+ public void lock() {
+ clusteredLockManager.get(clusteredLockId).lock();
+ }
+
+ @Override
+ public boolean tryLock(long units, TimeUnit milliseconds) throws InterruptedException {
+ try {
+ return clusteredLockManager.get(clusteredLockId).tryLock(units, milliseconds).get();
+ } catch(ExecutionException e) {
+ if(e.getCause() instanceof InterruptedException) {
+ throw (InterruptedException) e.getCause();
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void lockInterruptible() throws InterruptedException {
+ throw new UnsupportedOperationException("this lock does not support interruptible lock");
+ }
+
+ @Override
+ public void forceUnlock() {
+ try {
+ clusteredLockManager.forceRelease(clusteredLockId).get();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void unlock() {
+ try {
+ clusteredLockManager.get(clusteredLockId).unlock().get();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean hasQueuedThreads() {
+ try {
+ return clusteredLockManager.get(clusteredLockId).isLocked().get();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean isHeldByCurrentThread() {
+ try {
+ return clusteredLockManager.get(clusteredLockId).isLockedByMe().get();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int getQueueLength() {
+ try {
+ return clusteredLockManager.get(clusteredLockId).isLocked().get() ? 0 : 1;
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/lock/ClusteredRuntimeManagerLockFactory.java b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/lock/ClusteredRuntimeManagerLockFactory.java
new file mode 100644
index 0000000000..d908c98b74
--- /dev/null
+++ b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/java/org/kie/server/services/jbpm/cluster/lock/ClusteredRuntimeManagerLockFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.kie.server.services.jbpm.cluster.lock;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.infinispan.lock.EmbeddedClusteredLockManagerFactory;
+import org.infinispan.lock.api.ClusteredLockManager;
+import org.jbpm.runtime.manager.spi.RuntimeManagerLock;
+import org.jbpm.runtime.manager.spi.RuntimeManagerLockFactory;
+import org.kie.server.services.jbpm.cluster.EJBCacheBean;
+
+public class ClusteredRuntimeManagerLockFactory implements RuntimeManagerLockFactory {
+
+ private EJBCacheBean mbean;
+
+ private ClusteredLockManager clusterecLockManager;
+
+ public ClusteredRuntimeManagerLockFactory() {
+ try {
+ Context context = new InitialContext();
+ mbean = (EJBCacheBean) context.lookup("java:global/EJBCacheBean");
+ clusterecLockManager = EmbeddedClusteredLockManagerFactory.from(mbean.getCacheContainer());
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public RuntimeManagerLock newRuntimeManagerLock() {
+ return new ClusteredRuntimeManagerLock(clusterecLockManager);
+ }
+
+}
diff --git a/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/resources/META-INF/services/org.jbpm.runtime.manager.spi.RuntimeManagerLockFactory b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/resources/META-INF/services/org.jbpm.runtime.manager.spi.RuntimeManagerLockFactory
new file mode 100644
index 0000000000..deb81f88d8
--- /dev/null
+++ b/kie-server-parent/kie-server-services/kie-server-services-jbpm-cluster/src/main/resources/META-INF/services/org.jbpm.runtime.manager.spi.RuntimeManagerLockFactory
@@ -0,0 +1 @@
+org.kie.server.services.jbpm.cluster.lock.ClusteredRuntimeManagerLockFactory
\ No newline at end of file
diff --git a/process-migration-service/frontend/package-lock.json b/process-migration-service/frontend/package-lock.json
index 4f3733b33f..0cacffdd43 100644
--- a/process-migration-service/frontend/package-lock.json
+++ b/process-migration-service/frontend/package-lock.json
@@ -7263,9 +7263,9 @@
}
},
"lock-treatment-tool": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/lock-treatment-tool/-/lock-treatment-tool-0.4.1.tgz",
- "integrity": "sha512-Ge5Eds0tSxG9Lt1xmqSZm/tBPGCIx/CY72ncBp7Dxkp1HQWy2mLoMJ5NlVJ4T9A0cQ35XkLZqZBFNF8NV6FO4A==",
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/lock-treatment-tool/-/lock-treatment-tool-0.4.2.tgz",
+ "integrity": "sha512-+2SOnldKBY346zD7kIFm0GdlJCZ77SbbA6/ND0eArrTtSnZo9mvB2Ry5d9Hm47lOAq6Ws++8Ot+2a0a36cNkaw==",
"dev": true,
"requires": {
"line-reader": "^0.3.0",
@@ -7327,9 +7327,9 @@
}
},
"yargs": {
- "version": "14.2.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz",
- "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==",
+ "version": "14.2.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz",
+ "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==",
"dev": true,
"requires": {
"cliui": "^5.0.0",
@@ -7342,13 +7342,13 @@
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
- "yargs-parser": "^15.0.0"
+ "yargs-parser": "^15.0.1"
}
},
"yargs-parser": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz",
- "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==",
+ "version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz",
+ "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
diff --git a/process-migration-service/frontend/package.json b/process-migration-service/frontend/package.json
index dcf3e8e112..2a3ff8b04c 100644
--- a/process-migration-service/frontend/package.json
+++ b/process-migration-service/frontend/package.json
@@ -47,7 +47,7 @@
"jest-fetch-mock": "^2.1.2",
"jest-junit": "^6.4.0",
"lint-staged": "^8.2.1",
- "lock-treatment-tool": "^0.4.1",
+ "lock-treatment-tool": "^0.4.2",
"moment": "^2.24.0",
"patternfly-react": "^2.36.2",
"prettier": "^1.18.2",