Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYNCOPE-1787] RealmDAO for Elasticsearch and OpenSearch #544

Merged
merged 3 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public interface RealmDAO extends DAO<Realm> {

List<Realm> findDescendants(String base, String keyword, int page, int itemsPerPage);

List<String> findDescendants(String base, String prefix);

<T extends Policy> List<Realm> findByPolicy(T policy);

List<Realm> findByLogicActions(Implementation logicActions);
Expand All @@ -53,6 +55,10 @@ public interface RealmDAO extends DAO<Realm> {

List<Realm> findChildren(Realm realm);

int count();

List<String> findAllKeys(int page, int itemsPerPage);

Realm save(Realm realm);

void delete(Realm realm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,8 @@ public PolicyDAO policyDAO(

@ConditionalOnMissingBean
@Bean
public RealmDAO realmDAO(final @Lazy RoleDAO roleDAO) {
return new JPARealmDAO(roleDAO);
public RealmDAO realmDAO(final @Lazy RoleDAO roleDAO, final ApplicationEventPublisher publisher) {
return new JPARealmDAO(roleDAO, publisher);
}

@ConditionalOnMissingBean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public OffsetDateTime findLastChange(final String key) {
@Override
public Map<AnyType, Integer> countByType() {
Query query = entityManager().createQuery(
"SELECT e.type, COUNT(e) AS countByType FROM " + anyUtils().anyClass().getSimpleName() + " e "
"SELECT e.type, COUNT(e) AS countByType FROM " + anyUtils().anyClass().getSimpleName() + " e "
+ "GROUP BY e.type ORDER BY countByType DESC");
@SuppressWarnings("unchecked")
List<Object[]> results = query.getResultList();
Expand All @@ -161,7 +161,7 @@ public Map<AnyType, Integer> countByType() {
@Override
public Map<String, Integer> countByRealm(final AnyType anyType) {
Query query = entityManager().createQuery(
"SELECT e.realm, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e "
"SELECT e.realm, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e "
+ "WHERE e.type=:type GROUP BY e.realm");
query.setParameter("type", anyType);

Expand Down Expand Up @@ -240,14 +240,14 @@ public List<Relationship<Any<?>, AnyObject>> findAllRelationships(final AnyObjec
@Override
public int count() {
Query query = entityManager().createQuery(
"SELECT COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e");
"SELECT COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e");
return ((Number) query.getSingleResult()).intValue();
}

@Override
public List<AnyObject> findAll(final int page, final int itemsPerPage) {
TypedQuery<AnyObject> query = entityManager().createQuery(
"SELECT e FROM " + anyUtils().anyClass().getSimpleName() + " e ORDER BY e.id", AnyObject.class);
"SELECT e FROM " + anyUtils().anyClass().getSimpleName() + " e ORDER BY e.id", AnyObject.class);
query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
query.setMaxResults(itemsPerPage);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ protected Triple<String, Set<String>, Set<String>> getAdminRealmsFilter(
return noRealm;
});

realmKeys.addAll(
realmDAO.findDescendants(realm.getFullPath(), null, -1, -1).stream().
filter(r -> r.getFullPath().startsWith(base.getFullPath())).
map(Realm::getKey).collect(Collectors.toSet()));
realmKeys.addAll(realmDAO.findDescendants(realm.getFullPath(), base.getFullPath()));
} else {
DynRealm dynRealm = dynRealmDAO.find(realmPath);
if (dynRealm == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
import org.apache.syncope.core.persistence.jpa.entity.JPADynRealm;
import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
import org.apache.syncope.core.provisioning.api.event.EntityLifecycleEvent;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.identityconnectors.framework.common.objects.SyncDeltaType;
import org.springframework.context.ApplicationEventPublisher;
Expand Down Expand Up @@ -122,7 +122,7 @@ protected void notifyDynMembershipRemoval(final List<String> anyKeys) {
}
if (any != null) {
publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
}
});
}
Expand All @@ -144,7 +144,7 @@ public DynRealm saveAndRefreshDynMemberships(final DynRealm dynRealm) {
insert.executeUpdate();

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
cleared.remove(any.getKey());
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
import org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
import org.apache.syncope.core.provisioning.api.event.EntityLifecycleEvent;
import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
Expand Down Expand Up @@ -147,14 +147,14 @@ public OffsetDateTime findLastChange(final String key) {
@Override
public int count() {
Query query = entityManager().createQuery(
"SELECT COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e");
"SELECT COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e");
return ((Number) query.getSingleResult()).intValue();
}

@Override
public Map<String, Integer> countByRealm() {
Query query = entityManager().createQuery(
"SELECT e.realm, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e GROUP BY e.realm");
"SELECT e.realm, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e GROUP BY e.realm");

@SuppressWarnings("unchecked")
List<Object[]> results = query.getResultList();
Expand Down Expand Up @@ -277,7 +277,7 @@ public List<UMembership> findUMemberships(final Group group) {
@Override
public List<Group> findAll(final int page, final int itemsPerPage) {
TypedQuery<Group> query = entityManager().createQuery(
"SELECT e FROM " + anyUtils().anyClass().getSimpleName() + " e ORDER BY e.id", Group.class);
"SELECT e FROM " + anyUtils().anyClass().getSimpleName() + " e ORDER BY e.id", Group.class);
query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
query.setMaxResults(itemsPerPage);

Expand Down Expand Up @@ -321,7 +321,7 @@ public Group saveAndRefreshDynMemberships(final Group group) {
insert.executeUpdate();

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
});
}
}
Expand Down Expand Up @@ -350,7 +350,7 @@ public Group saveAndRefreshDynMemberships(final Group group) {
insert.executeUpdate();

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
});
}
});
Expand All @@ -377,7 +377,7 @@ public void delete(final Group group) {

anyObjectDAO.save(leftEnd);
publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, leftEnd, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, leftEnd, AuthContextUtils.getDomain()));
});

findUMemberships(group).forEach(membership -> {
Expand All @@ -394,7 +394,7 @@ public void delete(final Group group) {

userDAO.save(leftEnd);
publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, leftEnd, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, leftEnd, AuthContextUtils.getDomain()));
});

clearUDynMembers(group);
Expand Down Expand Up @@ -582,8 +582,8 @@ public Pair<Set<String>, Set<String>> refreshDynMemberships(final AnyObject anyO
delete.executeUpdate();
}

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, memb.getGroup(), AuthContextUtils.getDomain()));
publisher.publishEvent(new EntityLifecycleEvent<>(
this, SyncDeltaType.UPDATE, memb.getGroup(), AuthContextUtils.getDomain()));
});

return Pair.of(before, after);
Expand All @@ -601,8 +601,8 @@ public Set<String> removeDynMemberships(final AnyObject anyObject) {
dynGroups.forEach(group -> {
before.add(group.getKey());

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, group, AuthContextUtils.getDomain()));
publisher.publishEvent(new EntityLifecycleEvent<>(
this, SyncDeltaType.UPDATE, group, AuthContextUtils.getDomain()));
});

return before;
Expand Down Expand Up @@ -680,8 +680,8 @@ public Pair<Set<String>, Set<String>> refreshDynMemberships(final User user) {
delete.executeUpdate();
}

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, memb.getGroup(), AuthContextUtils.getDomain()));
publisher.publishEvent(new EntityLifecycleEvent<>(
this, SyncDeltaType.UPDATE, memb.getGroup(), AuthContextUtils.getDomain()));
});

return Pair.of(before, after);
Expand All @@ -699,8 +699,8 @@ public Set<String> removeDynMemberships(final User user) {
dynGroups.forEach(group -> {
before.add(group.getKey());

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, group, AuthContextUtils.getDomain()));
publisher.publishEvent(new EntityLifecycleEvent<>(
this, SyncDeltaType.UPDATE, group, AuthContextUtils.getDomain()));
});

return before;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
Expand All @@ -41,14 +42,21 @@
import org.apache.syncope.core.persistence.api.entity.policy.ProvisioningPolicy;
import org.apache.syncope.core.persistence.api.entity.policy.TicketExpirationPolicy;
import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
import org.apache.syncope.core.provisioning.api.event.EntityLifecycleEvent;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.identityconnectors.framework.common.objects.SyncDeltaType;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;

public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {

protected final RoleDAO roleDAO;

public JPARealmDAO(final RoleDAO roleDAO) {
protected final ApplicationEventPublisher publisher;

public JPARealmDAO(final RoleDAO roleDAO, final ApplicationEventPublisher publisher) {
this.roleDAO = roleDAO;
this.publisher = publisher;
}

@Override
Expand Down Expand Up @@ -183,6 +191,27 @@ public List<Realm> findDescendants(
return query.getResultList();
}

@Override
public List<String> findDescendants(final String base, final String prefix) {
List<Object> parameters = new ArrayList<>();

StringBuilder queryString = buildDescendantQuery(base, null, parameters);
TypedQuery<Realm> query = entityManager().createQuery(queryString.
append(" AND (e.fullPath=?").
append(setParameter(parameters, prefix)).
append(" OR e.fullPath LIKE ?").
append(setParameter(parameters, SyncopeConstants.ROOT_REALM.equals(prefix) ? "/%" : prefix + "/%")).
append(')').
append(" ORDER BY e.fullPath").toString(),
Realm.class);

for (int i = 1; i <= parameters.size(); i++) {
query.setParameter(i, parameters.get(i - 1));
}

return query.getResultList().stream().map(Realm::getKey).collect(Collectors.toList());
}

protected <T extends Policy> List<Realm> findSamePolicyChildren(final Realm realm, final T policy) {
List<Realm> result = new ArrayList<>();

Expand Down Expand Up @@ -284,6 +313,30 @@ protected String buildFullPath(final Realm realm) {
: StringUtils.appendIfMissing(realm.getParent().getFullPath(), "/") + realm.getName();
}

@Override
public int count() {
Query query = entityManager().createNativeQuery(
"SELECT COUNT(id) FROM " + JPARealm.TABLE);
return ((Number) query.getSingleResult()).intValue();
}

@Override
public List<String> findAllKeys(final int page, final int itemsPerPage) {
Query query = entityManager().createNativeQuery("SELECT id FROM " + JPARealm.TABLE + " ORDER BY fullPath");

query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));

if (itemsPerPage > 0) {
query.setMaxResults(itemsPerPage);
}

@SuppressWarnings("unchecked")
List<Object> raw = query.getResultList();
return raw.stream().map(key -> key instanceof Object[]
? (String) ((Object[]) key)[0]
: ((String) key)).collect(Collectors.toList());
}

@Override
public Realm save(final Realm realm) {
String fullPathBefore = realm.getFullPath();
Expand All @@ -298,6 +351,9 @@ public Realm save(final Realm realm) {
findChildren(realm).forEach(this::save);
}

publisher.publishEvent(
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, merged, AuthContextUtils.getDomain()));

return merged;
}

Expand All @@ -313,6 +369,9 @@ public void delete(final Realm realm) {
toBeDeleted.setParent(null);

entityManager().remove(toBeDeleted);

publisher.publishEvent(
new EntityLifecycleEvent<>(this, SyncDeltaType.DELETE, toBeDeleted, AuthContextUtils.getDomain()));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
import org.apache.syncope.core.persistence.jpa.entity.JPARole;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
import org.apache.syncope.core.provisioning.api.event.EntityLifecycleEvent;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.identityconnectors.framework.common.objects.SyncDeltaType;
import org.springframework.context.ApplicationEventPublisher;
Expand Down Expand Up @@ -129,7 +129,7 @@ public Role saveAndRefreshDynMemberships(final Role role) {
insert.executeUpdate();

publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
});
}

Expand All @@ -145,7 +145,7 @@ public void delete(final Role role) {
query.getResultList().forEach(user -> {
user.getRoles().remove(role);
publisher.publishEvent(
new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
new EntityLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
});

clearDynMembers(role);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ public Optional<String> findUsername(final String key) {
@Override
public int count() {
Query query = entityManager().createQuery(
"SELECT COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e");
"SELECT COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e");
return ((Number) query.getSingleResult()).intValue();
}

@Override
public Map<String, Integer> countByRealm() {
Query query = entityManager().createQuery(
"SELECT e.realm, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e GROUP BY e.realm");
"SELECT e.realm, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e GROUP BY e.realm");

@SuppressWarnings("unchecked")
List<Object[]> results = query.getResultList();
Expand All @@ -166,7 +166,7 @@ public Map<String, Integer> countByRealm() {
@Override
public Map<String, Integer> countByStatus() {
Query query = entityManager().createQuery(
"SELECT e.status, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e GROUP BY e.status");
"SELECT e.status, COUNT(e) FROM " + anyUtils().anyClass().getSimpleName() + " e GROUP BY e.status");

@SuppressWarnings("unchecked")
List<Object[]> results = query.getResultList();
Expand Down Expand Up @@ -270,7 +270,7 @@ public UMembership findMembership(final String key) {
@Override
public List<User> findAll(final int page, final int itemsPerPage) {
TypedQuery<User> query = entityManager().createQuery(
"SELECT e FROM " + anyUtils().anyClass().getSimpleName() + " e ORDER BY e.id", User.class);
"SELECT e FROM " + anyUtils().anyClass().getSimpleName() + " e ORDER BY e.id", User.class);
query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
query.setMaxResults(itemsPerPage);

Expand Down
Loading
Loading