You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2018/11/19 15:17:54 UTC
[syncope] branch master updated: Resolving concurrent update /
delete issues under high load
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new 4eceb6d Resolving concurrent update / delete issues under high load
4eceb6d is described below
commit 4eceb6d775de9b4b3804b4622455987f63fd6621
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Mon Nov 19 16:17:35 2018 +0100
Resolving concurrent update / delete issues under high load
---
.../core/persistence/jpa/dao/JPAAnyObjectDAO.java | 7 +-
.../core/persistence/jpa/dao/JPAGroupDAO.java | 143 +++++++++++++--------
.../core/persistence/jpa/dao/JPARoleDAO.java | 51 +++++---
.../core/persistence/jpa/dao/JPAUserDAO.java | 14 +-
4 files changed, 130 insertions(+), 85 deletions(-)
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index f4aacd2..8035812 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -268,11 +268,10 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
query.getResultList().stream().map(resultKey -> resultKey instanceof Object[]
? (String) ((Object[]) resultKey)[0]
: ((String) resultKey)).
- forEachOrdered(actualKey -> {
- Group group = groupDAO.find(actualKey.toString());
+ forEach(groupKey -> {
+ Group group = groupDAO.find(groupKey.toString());
if (group == null) {
- LOG.error("Could not find group with id {}, even though returned by the native query",
- actualKey);
+ LOG.error("Could not find group {}, even though returned by the native query", groupKey);
} else if (!result.contains(group)) {
result.add(group);
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index a343ebc..5700453 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -288,7 +288,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
}
}
clearADynMembers(merged);
- merged.getADynMemberships().stream().forEach(memb -> {
+ merged.getADynMemberships().forEach(memb -> {
SearchCond cond = buildDynMembershipCond(memb.getFIQLCond(), merged.getRealm());
int count = searchDAO.count(
Collections.<String>singleton(merged.getRealm().getFullPath()), cond, AnyTypeKind.ANY_OBJECT);
@@ -327,12 +327,12 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
AnyObject leftEnd = membership.getLeftEnd();
leftEnd.remove(membership);
membership.setRightEnd(null);
- leftEnd.getPlainAttrs(membership).stream().map(attr -> {
+ leftEnd.getPlainAttrs(membership).forEach(attr -> {
leftEnd.remove(attr);
attr.setOwner(null);
attr.setMembership(null);
- return attr;
- }).forEachOrdered(attr -> plainAttrDAO.delete(attr));
+ plainAttrDAO.delete(attr);
+ });
anyObjectDAO.save(leftEnd);
publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, leftEnd, AuthContextUtils.getDomain()));
@@ -342,12 +342,13 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
User leftEnd = membership.getLeftEnd();
leftEnd.remove(membership);
membership.setRightEnd(null);
- leftEnd.getPlainAttrs(membership).stream().map(attr -> {
+ leftEnd.getPlainAttrs(membership).forEach(attr -> {
leftEnd.remove(attr);
attr.setOwner(null);
attr.setMembership(null);
- return attr;
- }).forEachOrdered(attr -> plainAttrDAO.delete(attr));
+
+ plainAttrDAO.delete(attr);
+ });
userDAO.save(leftEnd);
publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, leftEnd, AuthContextUtils.getDomain()));
@@ -375,17 +376,20 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
@SuppressWarnings("unchecked")
public List<String> findADynMembers(final Group group) {
List<String> result = new ArrayList<>();
- group.getADynMemberships().stream().map(memb -> {
+
+ group.getADynMemberships().forEach(memb -> {
Query query = entityManager().createNativeQuery(
"SELECT any_id FROM " + ADYNMEMB_TABLE + " WHERE group_id=? AND anyType_id=?");
query.setParameter(1, group.getKey());
query.setParameter(2, memb.getAnyType().getKey());
- return query;
- }).forEachOrdered((query) -> {
+
query.getResultList().stream().map(key -> key instanceof Object[]
? (String) ((Object[]) key)[0]
: ((String) key)).
- forEachOrdered(actualKey -> result.add(actualKey.toString()));
+ filter(anyObject -> !result.contains((String) anyObject)).
+ forEach(anyObject -> {
+ result.add((String) anyObject);
+ });
});
return result;
@@ -448,35 +452,47 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
@Transactional
@Override
+ @SuppressWarnings("unchecked")
public Pair<Set<String>, Set<String>> refreshDynMemberships(final AnyObject anyObject) {
+ Query query = entityManager().createNativeQuery(
+ "SELECT group_id FROM " + JPAGroupDAO.ADYNMEMB_TABLE + " WHERE any_id=?");
+ query.setParameter(1, anyObject.getKey());
+
Set<String> before = new HashSet<>();
+ query.getResultList().stream().
+ map(resultKey -> resultKey instanceof Object[]
+ ? (String) ((Object[]) resultKey)[0]
+ : ((String) resultKey)).
+ forEach(group -> before.add((String) group));
+
Set<String> after = new HashSet<>();
- findWithADynMemberships(anyObject.getType()).stream().map(memb -> {
+ findWithADynMemberships(anyObject.getType()).stream().
+ filter(membCond -> jpaAnySearchDAO().matches(
+ anyObject,
+ buildDynMembershipCond(membCond.getFIQLCond(), membCond.getGroup().getRealm()))).
+ forEach(membCond -> {
+ if (!before.contains(membCond.getGroup().getKey())) {
+ Query insert = entityManager().createNativeQuery(
+ "INSERT INTO " + ADYNMEMB_TABLE + " VALUES(?, ?, ?)");
+ insert.setParameter(1, anyObject.getType().getKey());
+ insert.setParameter(2, anyObject.getKey());
+ insert.setParameter(3, membCond.getGroup().getKey());
+ insert.executeUpdate();
+ }
+
+ after.add(membCond.getGroup().getKey());
+
+ publisher.publishEvent(
+ new AnyCreatedUpdatedEvent<>(this, membCond.getGroup(), AuthContextUtils.getDomain()));
+ });
+
+ before.stream().filter(group -> !after.contains(group)).forEach(group -> {
Query delete = entityManager().createNativeQuery(
"DELETE FROM " + ADYNMEMB_TABLE + " WHERE group_id=? AND any_id=?");
- delete.setParameter(1, memb.getGroup().getKey());
+ delete.setParameter(1, group);
delete.setParameter(2, anyObject.getKey());
-
- if (delete.executeUpdate() > 0) {
- before.add(memb.getGroup().getKey());
- }
-
- if (jpaAnySearchDAO().matches(
- anyObject,
- buildDynMembershipCond(memb.getFIQLCond(), memb.getGroup().getRealm()))) {
-
- Query insert = entityManager().createNativeQuery(
- "INSERT INTO " + ADYNMEMB_TABLE + " VALUES(?, ?, ?)");
- insert.setParameter(1, anyObject.getType().getKey());
- insert.setParameter(2, anyObject.getKey());
- insert.setParameter(3, memb.getGroup().getKey());
- insert.executeUpdate();
-
- after.add(memb.getGroup().getKey());
- }
- return memb;
- }).forEachOrdered(memb -> publisher.publishEvent(
- new AnyCreatedUpdatedEvent<>(this, memb.getGroup(), AuthContextUtils.getDomain())));
+ delete.executeUpdate();
+ });
return Pair.of(before, after);
}
@@ -513,7 +529,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
List<String> result = new ArrayList<>();
query.getResultList().stream().map(key -> key instanceof Object[]
? (String) ((Object[]) key)[0]
- : ((String) key)).forEachOrdered(actualKey -> result.add(actualKey.toString()));
+ : ((String) key)).
+ forEach(user -> result.add((String) user));
return result;
}
@@ -534,34 +551,46 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
@Transactional
@Override
+ @SuppressWarnings("unchecked")
public Pair<Set<String>, Set<String>> refreshDynMemberships(final User user) {
+ Query query = entityManager().createNativeQuery(
+ "SELECT group_id FROM " + JPAGroupDAO.UDYNMEMB_TABLE + " WHERE any_id=?");
+ query.setParameter(1, user.getKey());
+
Set<String> before = new HashSet<>();
+ query.getResultList().stream().
+ map(resultKey -> resultKey instanceof Object[]
+ ? (String) ((Object[]) resultKey)[0]
+ : ((String) resultKey)).
+ forEach(group -> before.add((String) group));
+
Set<String> after = new HashSet<>();
- findWithUDynMemberships().stream().map(memb -> {
+ findWithUDynMemberships().stream().
+ filter(membCond -> jpaAnySearchDAO().matches(
+ user,
+ buildDynMembershipCond(membCond.getFIQLCond(), membCond.getGroup().getRealm()))).
+ forEach(membCond -> {
+ if (!before.contains(membCond.getGroup().getKey())) {
+ Query insert = entityManager().createNativeQuery(
+ "INSERT INTO " + UDYNMEMB_TABLE + " VALUES(?, ?)");
+ insert.setParameter(1, user.getKey());
+ insert.setParameter(2, membCond.getGroup().getKey());
+ insert.executeUpdate();
+ }
+
+ after.add(membCond.getGroup().getKey());
+
+ publisher.publishEvent(
+ new AnyCreatedUpdatedEvent<>(this, membCond.getGroup(), AuthContextUtils.getDomain()));
+ });
+
+ before.stream().filter(group -> !after.contains(group)).forEach(group -> {
Query delete = entityManager().createNativeQuery(
"DELETE FROM " + UDYNMEMB_TABLE + " WHERE group_id=? AND any_id=?");
- delete.setParameter(1, memb.getGroup().getKey());
+ delete.setParameter(1, group);
delete.setParameter(2, user.getKey());
-
- if (delete.executeUpdate() > 0) {
- before.add(memb.getGroup().getKey());
- }
-
- if (jpaAnySearchDAO().matches(
- user,
- buildDynMembershipCond(memb.getFIQLCond(), memb.getGroup().getRealm()))) {
-
- Query insert = entityManager().createNativeQuery(
- "INSERT INTO " + UDYNMEMB_TABLE + " VALUES(?, ?)");
- insert.setParameter(1, user.getKey());
- insert.setParameter(2, memb.getGroup().getKey());
- insert.executeUpdate();
-
- after.add(memb.getGroup().getKey());
- }
- return memb;
- }).forEachOrdered(memb -> publisher.publishEvent(
- new AnyCreatedUpdatedEvent<>(this, memb.getGroup(), AuthContextUtils.getDomain())));
+ delete.executeUpdate();
+ });
return Pair.of(before, after);
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 4e8295d..1cbf9ba 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -20,7 +20,9 @@ package org.apache.syncope.core.persistence.jpa.dao;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -142,6 +144,7 @@ public class JPARoleDAO extends AbstractDAO<Role> implements RoleDAO {
}
@Override
+ @SuppressWarnings("unchecked")
public List<String> findDynMembers(final Role role) {
if (role.getDynMembership() == null) {
return Collections.emptyList();
@@ -151,13 +154,10 @@ public class JPARoleDAO extends AbstractDAO<Role> implements RoleDAO {
query.setParameter(1, role.getKey());
List<String> result = new ArrayList<>();
- for (Object key : query.getResultList()) {
- String actualKey = key instanceof Object[]
- ? (String) ((Object[]) key)[0]
- : ((String) key);
-
- result.add(actualKey);
- }
+ query.getResultList().stream().map(key -> key instanceof Object[]
+ ? (String) ((Object[]) key)[0]
+ : ((String) key)).
+ forEach(user -> result.add((String) user));
return result;
}
@@ -170,20 +170,39 @@ public class JPARoleDAO extends AbstractDAO<Role> implements RoleDAO {
@Transactional
@Override
+ @SuppressWarnings("unchecked")
public void refreshDynMemberships(final User user) {
- findAll().stream().filter(role -> role.getDynMembership() != null).forEach(role -> {
+ Query query = entityManager().createNativeQuery(
+ "SELECT role_id FROM " + DYNMEMB_TABLE + " WHERE any_id=?");
+ query.setParameter(1, user.getKey());
+
+ Set<String> before = new HashSet<>();
+ query.getResultList().stream().
+ map(resultKey -> resultKey instanceof Object[]
+ ? (String) ((Object[]) resultKey)[0]
+ : ((String) resultKey)).
+ forEach(role -> before.add((String) role));
+
+ Set<String> after = new HashSet<>();
+ findAll().stream().
+ filter(role -> role.getDynMembership() != null
+ && searchDAO.matches(user, SearchCondConverter.convert(role.getDynMembership().getFIQLCond()))
+ && !before.contains(role.getKey())).
+ forEach(role -> {
+ Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
+ insert.setParameter(1, user.getKey());
+ insert.setParameter(2, role.getKey());
+ insert.executeUpdate();
+
+ after.add(role.getKey());
+ });
+
+ before.stream().filter(role -> !after.contains(role)).forEach(role -> {
Query delete = entityManager().createNativeQuery(
"DELETE FROM " + DYNMEMB_TABLE + " WHERE role_id=? AND any_id=?");
- delete.setParameter(1, role.getKey());
+ delete.setParameter(1, role);
delete.setParameter(2, user.getKey());
delete.executeUpdate();
-
- if (searchDAO.matches(user, SearchCondConverter.convert(role.getDynMembership().getFIQLCond()))) {
- Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
- insert.setParameter(1, user.getKey());
- insert.setParameter(2, role.getKey());
- insert.executeUpdate();
- }
});
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index e86905f..01e90c7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -448,11 +448,10 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
query.getResultList().stream().map(resultKey -> resultKey instanceof Object[]
? (String) ((Object[]) resultKey)[0]
: ((String) resultKey)).
- forEachOrdered(actualKey -> {
- Role role = roleDAO.find(actualKey.toString());
+ forEachOrdered(roleKey -> {
+ Role role = roleDAO.find(roleKey.toString());
if (role == null) {
- LOG.error("Could not find role with id {}, even though returned by the native query",
- actualKey);
+ LOG.error("Could not find role {}, even though returned by the native query", roleKey);
} else if (!result.contains(role)) {
result.add(role);
}
@@ -472,11 +471,10 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
query.getResultList().stream().map(resultKey -> resultKey instanceof Object[]
? (String) ((Object[]) resultKey)[0]
: ((String) resultKey)).
- forEachOrdered(actualKey -> {
- Group group = groupDAO.find(actualKey.toString());
+ forEach(groupKey -> {
+ Group group = groupDAO.find(groupKey.toString());
if (group == null) {
- LOG.error("Could not find group with id {}, even though returned by the native query",
- actualKey);
+ LOG.error("Could not find group {}, even though returned by the native query", groupKey);
} else if (!result.contains(group)) {
result.add(group);
}