/*
* Copyright (C) 2012 eXo Platform SAS.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.jcr.impl.quota;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.ValueParam;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.management.annotations.ManagedName;
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.naming.InitialContextInitializer;
import org.exoplatform.services.rpc.RPCService;
import org.picocontainer.Startable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author <a href="abazko@exoplatform.com">Anatoliy Bazko</a>
* @version $Id: BaseQuotaManager.java 34360 2009-07-22 23:58:59Z tolusha $
*/
@Managed
@NameTemplate(@Property(key = "service", value = "QuotaManager"))
public abstract class BaseQuotaManager implements QuotaManager, Startable
{
/**
* Logger.
*/
protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.BaseQuotaManager");
/**
* Name of cache configuration properties parameter.
*/
public static final String CACHE_CONFIGURATION_PROPERTIES_PARAM = "cache-configuration";
/**
* Name of exceeded quota behavior value parameter.
*/
public static final String EXCEEDED_QUOTA_BEHAVIOUR_PARAM = "exceeded-quota-behaviour";
/**
* All {@link WorkspaceQuotaManager} belonging to repository.
*/
protected Map<String, RepositoryQuotaManager> rQuotaManagers =
new ConcurrentHashMap<String, RepositoryQuotaManager>();
/**
* RPCService to communicate with other nodes in cluster.
*/
protected final RPCService rpcService;
/**
* What should to do when node exceeds quota limit. There are two behaviors:
* <ul>
* <li>{@link ExceededQuotaBehavior#WARNING}: log a warning</li>
* <li>{@link ExceededQuotaBehavior#EXCEPTION}: throw an exception</li>
* </ul>
*/
protected final ExceededQuotaBehavior exceededQuotaBehavior;
/**
* {@link QuotaPersister}
*/
protected final QuotaPersister quotaPersister;
/**
* Initialization parameters.
*/
protected final InitParams initParams;
/**
* Configuration manager.
*/
protected final ConfigurationManager cfm;
/**
* QuotaManager constructor.
*
* @param contextInitializer
* is added since BaseQuotaManager should be started after InitialContextInitializer to have
* binded datasource at startup
*/
public BaseQuotaManager(InitParams initParams, RPCService rpcService, ConfigurationManager cfm,
InitialContextInitializer contextInitializer) throws RepositoryConfigurationException, QuotaManagerException
{
ValueParam param = initParams.getValueParam(EXCEEDED_QUOTA_BEHAVIOUR_PARAM);
this.exceededQuotaBehavior =
param == null ? ExceededQuotaBehavior.WARNING : ExceededQuotaBehavior.valueOf(param.getValue().toUpperCase());
this.cfm = cfm;
this.initParams = initParams;
this.rpcService = rpcService == null ? new DummyRPCServiceImpl() : rpcService;
this.quotaPersister = initQuotaPersister();
}
/**
* QuotaManager constructor.
*/
public BaseQuotaManager(InitParams initParams, ConfigurationManager cfm, InitialContextInitializer contextInitializer)
throws RepositoryConfigurationException, QuotaManagerException
{
this(initParams, null, cfm, contextInitializer);
}
/**
* {@inheritDoc}
*/
public long getNodeDataSize(String repositoryName, String workspaceName, String nodePath)
throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getNodeDataSize(workspaceName, nodePath);
}
/**
* {@inheritDoc}
*/
public void setNodeQuota(String repositoryName, String workspaceName, String nodePath, long quotaLimit,
boolean asyncUpdate) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.setNodeQuota(workspaceName, nodePath, quotaLimit, asyncUpdate);
}
/**
* {@inheritDoc}
*/
public void removeNodeQuota(String repositoryName, String workspaceName, String nodePath)
throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.removeNodeQuota(workspaceName, nodePath);
}
/**
* {@inheritDoc}
*/
public void removeGroupOfNodesQuota(String repositoryName, String workspaceName, String nodePath)
throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.removeGroupOfNodesQuota(workspaceName, nodePath);
}
/**
* {@inheritDoc}
*/
public long getNodeQuota(String repositoryName, String workspaceName, String nodePath) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getNodeQuota(workspaceName, nodePath);
}
/**
* {@inheritDoc}
*/
public void setGroupOfNodesQuota(String repositoryName, String workspaceName, String patternPath, long quotaLimit,
boolean asyncUpdate) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.setGroupOfNodesQuota(workspaceName, patternPath, quotaLimit, asyncUpdate);
}
/**
* {@inheritDoc}
*/
public void setWorkspaceQuota(String repositoryName, String workspaceName, long quotaLimit)
throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.setWorkspaceQuota(workspaceName, quotaLimit);
}
/**
* {@inheritDoc}
*/
public void removeWorkspaceQuota(String repositoryName, String workspaceName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.removeWorkspaceQuota(workspaceName);
}
/**
* {@inheritDoc}
*/
public long getWorkspaceQuota(String repositoryName, String workspaceName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getWorkspaceQuota(workspaceName);
}
/**
* {@inheritDoc}
*/
public long getWorkspaceDataSize(String repositoryName, String workspaceName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getWorkspaceDataSize(workspaceName);
}
/**
* {@inheritDoc}
*/
public long getWorkspaceIndexSize(String repositoryName, String workspaceName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getWorkspaceIndexSize(workspaceName);
}
/**
* {@inheritDoc}
*/
public void setRepositoryQuota(String repositoryName, long quotaLimit) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.setRepositoryQuota(quotaLimit);
}
/**
* {@inheritDoc}
*/
public void removeRepositoryQuota(String repositoryName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
rqm.removeRepositoryQuota();
}
/**
* {@inheritDoc}
*/
public long getRepositoryQuota(String repositoryName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getRepositoryQuota();
}
/**
* {@inheritDoc}
*/
public long getRepositoryDataSize(String repositoryName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getRepositoryDataSize();
}
/**
* {@inheritDoc}
*/
public long getRepositoryIndexSize(String repositoryName) throws QuotaManagerException
{
RepositoryQuotaManager rqm = getRepositoryQuotaManager(repositoryName);
return rqm.getRepositoryIndexSize();
}
/**
* {@inheritDoc}
*/
@Managed
@ManagedDescription("Returns global data size")
public long getGlobalDataSize() throws QuotaManagerException
{
return quotaPersister.getGlobalDataSize();
}
/**
* {@inheritDoc}
*/
@Managed
@ManagedDescription("Returns global quota limit")
public void setGlobalQuota(@ManagedName("quotaLimit") long quotaLimit) throws QuotaManagerException
{
quotaPersister.setGlobalQuota(quotaLimit);
}
/**
* {@inheritDoc}
*/
@Managed
@ManagedDescription("Removes global quota limit")
public void removeGlobalQuota() throws QuotaManagerException
{
quotaPersister.removeGlobalQuota();
}
/**
* {@inheritDoc}
*/
@Managed
@ManagedDescription("Returns global quota limit")
public long getGlobalQuota() throws QuotaManagerException
{
return quotaPersister.getGlobalQuota();
}
/**
* {@inheritDoc}
*/
@Managed
@ManagedDescription("Returns global index size")
public long getGlobalIndexSize() throws QuotaManagerException
{
long size = 0;
for (RepositoryQuotaManager rqm : rQuotaManagers.values())
{
size += rqm.getRepositoryIndexSize();
}
return size;
}
/**
* {@inheritDoc}
*/
public void start()
{
}
/**
* {@inheritDoc}
*/
public void stop()
{
quotaPersister.destroy();
rQuotaManagers.clear();
}
/**
* Registers {@link RepositoryQuotaManager} by name. To delegate repository based operation
* to appropriate level.
*/
protected void registerRepositoryQuotaManager(String repositoryName, RepositoryQuotaManager rQuotaManager)
{
rQuotaManagers.put(repositoryName, rQuotaManager);
}
/**
* Unregisters {@link RepositoryQuotaManager} by name.
*/
protected void unregisterRepositoryQuotaManager(String repositoryName)
{
rQuotaManagers.remove(repositoryName);
}
/**
* Behavior when quota exceeded.
*/
public enum ExceededQuotaBehavior {
WARNING, EXCEPTION
}
/**
* Calculates the global size by summing sized of all repositories.
*/
public long getGlobalDataSizeDirectly() throws QuotaManagerException
{
long size = 0;
for (RepositoryQuotaManager rqm : rQuotaManagers.values())
{
size += rqm.getRepositoryDataSizeDirectly();
}
return size;
}
/**
* Returns registered {@link RepositoryQuotaManager} or throws exception.
*/
private RepositoryQuotaManager getRepositoryQuotaManager(String repositoryName) throws IllegalStateException
{
RepositoryQuotaManager rqm = rQuotaManagers.get(repositoryName);
if (rqm == null)
{
throw new IllegalStateException("Repository " + repositoryName + " is not registered");
}
return rqm;
}
/**
* Initialize persister.
*/
protected abstract QuotaPersister initQuotaPersister() throws RepositoryConfigurationException,
QuotaManagerException;
}