From: Mathieu Baudier Date: Sun, 27 Oct 2019 11:05:21 +0000 (+0100) Subject: Introduce abstract maintenance service. X-Git-Tag: argeo-commons-2.1.82~7 X-Git-Url: http://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=b0aa5659a33348fa6db4e55a8cee06131121cd1d Introduce abstract maintenance service. --- diff --git a/org.argeo.maintenance/pom.xml b/org.argeo.maintenance/pom.xml index ddfb9c411..9b95c825a 100644 --- a/org.argeo.maintenance/pom.xml +++ b/org.argeo.maintenance/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.argeo.commons @@ -21,5 +23,10 @@ org.argeo.enterprise 2.1.82-SNAPSHOT + + org.argeo.commons + org.argeo.node.api + 2.1.82-SNAPSHOT + \ No newline at end of file diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/AbstractMaintenanceService.java b/org.argeo.maintenance/src/org/argeo/maintenance/AbstractMaintenanceService.java new file mode 100644 index 000000000..1a742d917 --- /dev/null +++ b/org.argeo.maintenance/src/org/argeo/maintenance/AbstractMaintenanceService.java @@ -0,0 +1,220 @@ +package org.argeo.maintenance; + +import java.io.IOException; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.jcr.Jcr; +import org.argeo.jcr.JcrUtils; +import org.argeo.naming.Distinguished; +import org.argeo.node.NodeUtils; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdmin; + +/** Make sure roles and access rights are properly configured. */ +public abstract class AbstractMaintenanceService { + private final static Log log = LogFactory.getLog(AbstractMaintenanceService.class); + + private Repository repository; +// private UserAdminService userAdminService; + private UserAdmin userAdmin; + private UserTransaction userTransaction; + + public void init() { + makeSureRolesExists(getRequiredRoles()); + configureStandardRoles(); + + Set workspaceNames = getWorkspaceNames(); + if (workspaceNames == null || workspaceNames.isEmpty()) { + configureJcr(repository, null); + } else { + for (String workspaceName : workspaceNames) + configureJcr(repository, workspaceName); + } + } + + protected void configureJcr(Repository repository, String workspaceName) { + Session adminSession; + try { + adminSession = NodeUtils.openDataAdminSession(repository, workspaceName); + } catch (RuntimeException e1) { + if (e1.getCause() != null && e1.getCause() instanceof NoSuchWorkspaceException) { + Session defaultAdminSession = NodeUtils.openDataAdminSession(repository, null); + try { + defaultAdminSession.getWorkspace().createWorkspace(workspaceName); + log.info("Created JCR workspace " + workspaceName); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot create workspace " + workspaceName, e); + } finally { + Jcr.logout(defaultAdminSession); + } + adminSession = NodeUtils.openDataAdminSession(repository, workspaceName); + } else + throw e1; + } + try { + if (prepareJcrTree(adminSession)) { + configurePrivileges(adminSession); + } + } catch (RepositoryException | IOException e) { + throw new IllegalStateException("Cannot initialise JCR data layer.", e); + } finally { + JcrUtils.logoutQuietly(adminSession); + } + } + + /** To be overridden. */ + protected Set getWorkspaceNames() { + return null; + } + + protected void configureStandardRoles() { + } + + protected void addManagersToGroup(String groupDn) { + } + + /** + * Creates the base JCR tree structure expected for this app if necessary. + * + * Expects a clean session ({@link Session#hasPendingChanges()} should return + * false) and saves it once the changes have been done. Thus the session can be + * rolled back if an exception occurs. + * + * @return true if something as been updated + */ + public boolean prepareJcrTree(Session adminSession) throws RepositoryException, IOException { + return false; + } + + /** + * Adds app specific default privileges. + * + * Expects a clean session ({@link Session#hasPendingChanges()} should return + * false} and saves it once the changes have been done. Thus the session can be + * rolled back if an exception occurs. + * + * Warning: no check is done and corresponding privileges are always added, so + * only call this when necessary + */ + public void configurePrivileges(Session session) throws RepositoryException { + } + + /** The system roles that must be available in the system. */ + protected Set getRequiredRoles() { + return new HashSet<>(); + } + + public void destroy() { + + } + + /* + * UTILITIES + */ + + protected void makeSureRolesExists(EnumSet enumSet) { + makeSureRolesExists(Distinguished.enumToDns(enumSet)); + } + + protected void makeSureRolesExists(Set requiredRoles) { + if (requiredRoles == null) + return; + if (getUserAdmin() == null) { + log.warn("No user admin service available, cannot make sure that role exists"); + return; + } + for (String role : requiredRoles) { + Role systemRole = getUserAdmin().getRole(role); + if (systemRole == null) { + try { + getUserTransaction().begin(); + getUserAdmin().createRole(role, Role.GROUP); + getUserTransaction().commit(); + log.info("Created role " + role); + } catch (Exception e) { + try { + getUserTransaction().rollback(); + } catch (Exception e1) { + // silent + } + throw new IllegalStateException("Cannot create role " + role, e); + } + } + } + } + + protected void addManagersToGroups(List groupDns) { + for (String groupDn : groupDns) + addManagersToGroup(groupDn); + } + + protected void addToGroup(String officeGroup, String groupDn) { + if (officeGroup.contentEquals(groupDn)) { + if (log.isTraceEnabled()) + log.trace("Ignore adding group " + groupDn + " to itself"); + return; + } + + if (getUserAdmin() == null) { + log.warn("No user admin service available, cannot add group " + officeGroup + " to " + groupDn); + return; + } + Group managerGroup = (Group) getUserAdmin().getRole(officeGroup); + Group group = (Group) getUserAdmin().getRole(groupDn); + if (group == null) + throw new IllegalArgumentException("Group " + groupDn + " not found"); + try { + getUserTransaction().begin(); + if (group.addMember(managerGroup)) + log.info("Added " + officeGroup + " to " + group); + getUserTransaction().commit(); + } catch (Exception e) { + try { + getUserTransaction().rollback(); + } catch (Exception e1) { + // silent + } + throw new IllegalStateException("Cannot add " + managerGroup + " to " + group); + } + } + + /* + * DEPENDENCY INJECTION + */ + public void setRepository(Repository repository) { + this.repository = repository; + } + +// public void setUserAdminService(UserAdminService userAdminService) { +// this.userAdminService = userAdminService; +// } + + protected UserTransaction getUserTransaction() { + return userTransaction; + } + + protected UserAdmin getUserAdmin() { + return userAdmin; + } + + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } + + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } + +}