/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.smartitengineering.user.service.impl.cache;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.smartitengineering.dao.common.cache.CacheServiceProvider;
import com.smartitengineering.dao.common.cache.Lock;
import com.smartitengineering.dao.common.cache.Mutex;
import com.smartitengineering.dao.common.cache.impl.CacheAPIFactory;
import com.smartitengineering.user.domain.SecuredObject;
import com.smartitengineering.user.service.SecuredObjectService;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author imyousuf
*/
public class SecuredObjectServiceCacheImpl implements SecuredObjectService {
@Inject
@Named("primaryService")
private SecuredObjectService primaryService;
@Inject
private CacheServiceProvider<Long, SecuredObject> cacheProvider;
@Inject
private CacheServiceProvider<String, Long> nameCacheProvider;
private transient final Logger logger = LoggerFactory.getLogger(getClass());
private final Mutex<Long> mutex = CacheAPIFactory.<Long>getMutex();
@Override
public void save(SecuredObject securedObject) {
primaryService.save(securedObject);
}
@Override
public void update(SecuredObject securedObject) {
//First update then delete if update successful!
try {
primaryService.update(securedObject);
expireFromCache(securedObject);
}
catch (RuntimeException exception) {
logger.info("Could not update thus invalidate cache!", exception);
throw exception;
}
}
@Override
public void delete(SecuredObject securedObject) {
//First update then delete if update successful!
try {
primaryService.delete(securedObject);
expireFromCache(securedObject);
}
catch (RuntimeException exception) {
logger.warn("Could not delete thus invalidate cache!", exception);
throw exception;
}
}
@Override
public SecuredObject getById(Long id) {
//Check cache first
SecuredObject securedObject = cacheProvider.retrieveFromCache(id);
if (securedObject != null) {
return securedObject;
}
else {
try {
Lock<Long> lock = mutex.acquire(id);
securedObject = cacheProvider.retrieveFromCache(id);
if (securedObject != null) {
return securedObject;
}
securedObject = primaryService.getById(id);
if (securedObject != null) {
putToCache(securedObject);
}
mutex.release(lock);
}
catch (Exception ex) {
logger.warn("Could not do cache lookup!", ex);
}
return securedObject;
}
}
@Override
public SecuredObject getByOrganizationAndObjectID(String organizationName, String objectID) {
Long id = nameCacheProvider.retrieveFromCache(getObjectIDCacheKey(objectID, organizationName));
if (id != null) {
SecuredObject set = getById(id);
if (set != null) {
return set;
}
}
return primaryService.getByOrganizationAndObjectID(organizationName, objectID);
}
@Override
public SecuredObject getByOrganizationAndName(String organizationName, String name) {
Long id = nameCacheProvider.retrieveFromCache(getNameCacheKey(name, organizationName));
if (id != null) {
SecuredObject set = getById(id);
if (set != null) {
return set;
}
}
return primaryService.getByOrganizationAndName(organizationName, name);
}
@Override
public Collection<SecuredObject> getByOrganization(String organizationName) {
return primaryService.getByOrganization(organizationName);
}
@Override
public void validateSecuredObject(SecuredObject securedObject) {
primaryService.validateSecuredObject(securedObject);
}
private String getNameCacheKey(SecuredObject securedObject) {
final String name = securedObject.getName();
return getNameCacheKey(name, securedObject.getOrganization().getUniqueShortName());
}
protected String getNameCacheKey(final String name, final String organizationName) {
return new StringBuilder("secObjName:").append(name).append(':').append(organizationName).toString();
}
private String getObjectIDCacheKey(SecuredObject securedObject) {
final String objectId = securedObject.getObjectID();
return getObjectIDCacheKey(objectId, securedObject.getOrganization().getUniqueShortName());
}
protected String getObjectIDCacheKey(final String objId, final String organizationName) {
return new StringBuilder("secObjObjId:").append(objId).append(':').append(organizationName).toString();
}
private void putToCache(SecuredObject securedObject) {
cacheProvider.putToCache(securedObject.getId(), securedObject);
nameCacheProvider.putToCache(getNameCacheKey(securedObject), securedObject.getId());
nameCacheProvider.putToCache(getObjectIDCacheKey(securedObject), securedObject.getId());
}
private void expireFromCache(SecuredObject secObj) {
if (cacheProvider.containsKey(secObj.getId())) {
SecuredObject securedObject = getById(secObj.getId());
if (securedObject != null) {
nameCacheProvider.expireFromCache(getNameCacheKey(securedObject));
nameCacheProvider.expireFromCache(getObjectIDCacheKey(securedObject));
}
cacheProvider.expireFromCache(secObj.getId());
}
}
}