RM-2604 Bootstrap the CaveatDAO and create the Spring context file.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/caveatmarkdatatype@114175 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tom Page
2015-10-12 14:52:21 +00:00
parent cb4823f9eb
commit 1e109021eb
9 changed files with 315 additions and 8 deletions

View File

@@ -68,6 +68,12 @@ rm.classification.reasonsFile=/alfresco/module/org_alfresco_module_rm/classifica
# The location of the exemption categories configuration file (relative to the classpath). # The location of the exemption categories configuration file (relative to the classpath).
rm.classification.exemptionCategoriesFile=/alfresco/module/org_alfresco_module_rm/classification/rm-exemption-categories.json rm.classification.exemptionCategoriesFile=/alfresco/module/org_alfresco_module_rm/classification/rm-exemption-categories.json
#
# Caveats
#
# The location of the caveats configuration file (relative to the classpath).
rm.caveat.configFile=/alfresco/module/org_alfresco_module_rm/caveat/rm-caveats.json
# #
# Content cleansing # Content cleansing
# #

View File

@@ -0,0 +1,33 @@
<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:annotation-config/>
<!-- Caveat DAO -->
<bean id="caveatDAOFromJSON" class="org.alfresco.module.org_alfresco_module_rm.caveat.dao.CaveatDAOFromJSON">
<property name="configLocation" value="${rm.caveat.configFile}" />
</bean>
<bean id="caveatDAO" class="org.alfresco.module.org_alfresco_module_rm.caveat.dao.CaveatDAOCache">
<property name="caveatDAO" ref="caveatDAOFromJSON" />
</bean>
<bean id="caveatDAOFromJSONBootstrap"
class="org.alfresco.module.org_alfresco_module_rm.caveat.dao.CaveatDAOFromJSONBootstrap">
<constructor-arg ref="rm.authenticationUtil"/>
<constructor-arg ref="TransactionService"/>
<constructor-arg ref="attributeService"/>
<constructor-arg ref="caveatDAO"/>
</bean>
</beans>

View File

@@ -273,6 +273,9 @@
<!-- Import the Classified Content Services --> <!-- Import the Classified Content Services -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/classified-content-context.xml"/> <import resource="classpath:alfresco/module/org_alfresco_module_rm/classified-content-context.xml"/>
<!-- Import the Caveat Services -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/caveat-context.xml"/>
<!-- Import the Content Services --> <!-- Import the Content Services -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/content-context.xml"/> <import resource="classpath:alfresco/module/org_alfresco_module_rm/content-context.xml"/>

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.caveat;
import java.io.Serializable;
/**
* Constants for use by the caveats feature.
*
* @author Tom Page
* @since 2.4.a
*/
public class CaveatConstants
{
/** This utility class should not be instantiated. */
private CaveatConstants() {}
/** Key for accessing the persisted caveat groups and marks in the attribute service. */
public static final Serializable[] CAVEAT_ATTRIBUTE_KEY = new String[] { "org.alfresco", "module.org_alfresco_module_rm", "caveat.groups" };
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.caveat.dao;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.caveat.scheme.CaveatGroup;
/**
* A cache that ensures the underlying caveat DAO is only executed once per query.
*
* @author Tom Page
* @since 2.4.a
*/
public class CaveatDAOCache implements CaveatDAOInterface
{
/** The wrapped caveat DAO. */
private CaveatDAOInterface caveatDAO;
/** A cache of the system caveat groups. */
private Map<String, CaveatGroup> caveatGroups;
/**
* {@inheritDoc} The first call to this method will be cached and returned for every successive call.
*/
@Override
public Map<String, CaveatGroup> getCaveatGroups()
{
if (caveatGroups == null)
{
caveatGroups = caveatDAO.getCaveatGroups();
}
return caveatGroups;
}
/**
* Set the caveat DAO to be wrapped.
*
* @param caveatDAO The caveat DAO to be wrapped.
*/
public void setCaveatDAO(CaveatDAOInterface caveatDAO)
{
this.caveatDAO = caveatDAO;
}
}

View File

@@ -66,7 +66,7 @@ public class CaveatDAOFromJSON implements CaveatDAOInterface
private static final Logger LOGGER = LoggerFactory.getLogger(CaveatDAOFromJSON.class); private static final Logger LOGGER = LoggerFactory.getLogger(CaveatDAOFromJSON.class);
/** The location of the configuration file relative to the classpath. */ /** The location of the configuration file relative to the classpath. */
String configLocation; private String configLocation;
/** Set the location of the configuration file relative to the classpath. */ /** Set the location of the configuration file relative to the classpath. */
public void setConfigLocation(String configLocation) public void setConfigLocation(String configLocation)

View File

@@ -0,0 +1,162 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.caveat.dao;
import static org.alfresco.module.org_alfresco_module_rm.caveat.CaveatConstants.CAVEAT_ATTRIBUTE_KEY;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.caveat.CaveatException.MalformedConfiguration;
import org.alfresco.module.org_alfresco_module_rm.caveat.scheme.CaveatGroup;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.transaction.TransactionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
/**
* This class is responsible for ensuring all caveat data is loaded from the JSON configuration on start-up.
*
* @author Tom Page
* @since 2.4.a
*/
public class CaveatDAOFromJSONBootstrap extends AbstractLifecycleBean implements ClassifiedContentModel
{
/** Logging utility for the class. */
private static final Logger LOGGER = LoggerFactory.getLogger(CaveatDAOFromJSONBootstrap.class);
private final AuthenticationUtil authenticationUtil;
private final TransactionService transactionService;
private AttributeService attributeService;
private CaveatDAOInterface caveatDAO;
private boolean isInitialised = false;
public CaveatDAOFromJSONBootstrap(AuthenticationUtil authUtil,
TransactionService txService,
AttributeService attributeService,
CaveatDAOInterface caveatDAO)
{
this.authenticationUtil = authUtil;
this.transactionService = txService;
this.attributeService = attributeService;
this.caveatDAO = caveatDAO;
}
/** Set the object from which configuration options will be read. */
public void setClassificationServiceDAO(CaveatDAOInterface caveatDAO) { this.caveatDAO = caveatDAO; }
public void setAttributeService(AttributeService attributeService) { this.attributeService = attributeService; }
public boolean isInitialised()
{
return isInitialised;
}
@Override public void onBootstrap(ApplicationEvent event)
{
authenticationUtil.runAsSystem(new org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork<Void>()
{
public Void doWork()
{
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>()
{
public Void execute()
{
initialiseConfiguredCaveatGroups(CAVEAT_ATTRIBUTE_KEY);
isInitialised = true;
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(callback);
return null;
}
});
}
/**
* Gets the caveat configuration persisted in the system.
*
* @return the persisted caveat groups if they have been persisted, else {@code null}.
*/
private Map<String, CaveatGroup> getPersistedValues(final Serializable[] key)
{
return authenticationUtil.runAsSystem(new RunAsWork<Map<String, CaveatGroup>>()
{
@Override
@SuppressWarnings("unchecked")
public Map<String, CaveatGroup> doWork() throws Exception
{
return (Map<String, CaveatGroup>) attributeService.getAttribute(key);
}
});
}
/** Return true if the map is null or empty. */
private boolean isEmpty(Map<String, CaveatGroup> caveatGroups)
{
return (caveatGroups == null || caveatGroups.isEmpty());
}
/** Helper method for debug-logging sensitive caveat group information. */
private String loggableStatusOf(Map<String, CaveatGroup> caveatGroups)
{
if (caveatGroups == null) { return "null"; }
else if (caveatGroups.isEmpty()) { return "empty"; }
else { return "non-empty"; }
}
/**
* Get the configured caveat groups and marks from the JSON file.
*
* @param key The attribute service key for the caveat scheme.
*/
protected void initialiseConfiguredCaveatGroups(Serializable[] key)
{
final Map<String, CaveatGroup> persistedValues = getPersistedValues(key);
final Map<String, CaveatGroup> classpathValues = caveatDAO.getCaveatGroups();
// Note! We cannot log the entities or even the size of these lists for security reasons.
LOGGER.debug("Persisted CaveatGroup: {}", loggableStatusOf(persistedValues));
LOGGER.debug("Classpath CaveatGroup: {}", loggableStatusOf(classpathValues));
if (isEmpty(classpathValues))
{
throw new MalformedConfiguration("CaveatGroup configuration is missing.");
}
if (!classpathValues.equals(persistedValues))
{
if (!isEmpty(persistedValues))
{
LOGGER.warn("CaveatGroup configuration changed. This may result in unpredictable results if the caveat scheme is already in use.");
}
attributeService.setAttribute((Serializable) classpathValues, key);
}
}
@Override protected void onShutdown(ApplicationEvent event)
{
// Intentionally empty.
}
}

View File

@@ -19,6 +19,7 @@
package org.alfresco.module.org_alfresco_module_rm.caveat.scheme; package org.alfresco.module.org_alfresco_module_rm.caveat.scheme;
import java.io.Serializable;
import java.util.List; import java.util.List;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -31,8 +32,10 @@ import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
* @author Tom Page * @author Tom Page
* @since 2.4.a * @since 2.4.a
*/ */
public class CaveatGroup public class CaveatGroup implements Serializable
{ {
/** Generated serial version id. */
private static final long serialVersionUID = -8909291192015016370L;
/** The unique id of the caveat group. */ /** The unique id of the caveat group. */
private String id; private String id;
/** The key to retrieve the I18n'ed display label for the caveat group. */ /** The key to retrieve the I18n'ed display label for the caveat group. */

View File

@@ -19,6 +19,8 @@
package org.alfresco.module.org_alfresco_module_rm.caveat.scheme; package org.alfresco.module.org_alfresco_module_rm.caveat.scheme;
import java.io.Serializable;
import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras; import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
/** /**
@@ -28,8 +30,10 @@ import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
* @author Tom Page * @author Tom Page
* @since 2.4.a * @since 2.4.a
*/ */
public class CaveatMark public class CaveatMark implements Serializable
{ {
/** Generated serial version id. */
private static final long serialVersionUID = 2805846540946220526L;
/** The id of the group that this mark belongs to. */ /** The id of the group that this mark belongs to. */
private String groupId; private String groupId;
/** The id for this mark. */ /** The id for this mark. */