Added cache that stores space used for user with a TTL of 5 minutes. The label "total space used" has been changed to "space used" and fixed a bug when retrieving profile strength: if the avatar was null, a null exception was raised

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/user-statistics@128786 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-05-23 15:45:17 +00:00
parent 7a0600ee4a
commit ae69711cda
6 changed files with 242 additions and 38 deletions

View File

@ -70,7 +70,7 @@ public class StatisticsPanel extends Composite {
* Labels
*/
private final static String POSTS_LABEL = "Posts";
private final static String STORAGE_LABEL = "Total Space Used";
private final static String STORAGE_LABEL = "Space Used";
private final static String LIKES_COMMENTS_LABEL = "Got";
private final static String PROFILE_STRENGTH_LABEL = "Profile Strength";

View File

@ -16,6 +16,7 @@ import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl;
import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portlet.user.userstatisticsportlet.client.UserStatisticsService;
import org.gcube.portlet.user.userstatisticsportlet.server.cache.UserInfrastructureSpaceCache;
import org.gcube.portlet.user.userstatisticsportlet.shared.PostsStatsBean;
import org.gcube.portlet.user.userstatisticsportlet.shared.UserInformation;
import org.gcube.vomanagement.usermanagement.GroupManager;
@ -65,7 +66,7 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
// get connection to Cassandra
_log.debug("Getting connection to Cassandra..");
store = new DBCassandraAstyanaxImpl();
// add statistics option for profile pages and set to true
createUserCustomField(CUSTOM_FIELD_NAME_USER_STATISTICS_VISIBILITY, true);
@ -176,9 +177,25 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
long init = System.currentTimeMillis();
Workspace workspace = HomeLibrary.getUserWorkspace(statisticsOfUsername);
long storage = workspace.getDiskUsage();
storageInUse = formatFileSize(storage);
// retrieve the cache
UserInfrastructureSpaceCache cacheWorkspace = UserInfrastructureSpaceCache.getCacheInstance();
// check if information is present
Long storageInUseLong = (Long) cacheWorkspace.get(statisticsOfUsername);
// if not, ask the workspace
if(storageInUseLong == null){
_log.debug("Information not available in the cache, asking workspace");
Workspace workspace = HomeLibrary.getUserWorkspace(statisticsOfUsername);
storageInUseLong = workspace.getDiskUsage();
_log.debug("Put information in the cache");
cacheWorkspace.insert(statisticsOfUsername, storageInUseLong);
}
storageInUse = formatFileSize(storageInUseLong);
long end = System.currentTimeMillis();
_log.debug("[USER-STATISTICS] time taken to retrieve user space is " + (end - init) + "ms");
@ -222,11 +239,11 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
try{
long init = System.currentTimeMillis();
// check if the avatar is present
boolean avatarPresent = (new LiferayUserManager().getUserAvatarBytes(statisticsOfUsername) != null);
long init = System.currentTimeMillis();
User user = UserLocalServiceUtil.getUserByScreenName(SiteManagerUtil.getCompany().getCompanyId(), statisticsOfUsername);
profileStrenght = evaluateProfileStrenght(user, avatarPresent);
@ -235,7 +252,7 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
}catch(Exception e){
_log.error("Profile strenght evaluation failed!!");
_log.error("Profile strenght evaluation failed!!" + e.toString(), e);
}
}
@ -309,7 +326,7 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
actualVre = temp[temp.length - 1];
}
// page landing
String pageLanding = PortalContext.getConfiguration().getSiteLandingPagePath(getThreadLocalRequest());
@ -459,14 +476,14 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
user.getExpandoBridge().setAttribute(CUSTOM_FIELD_NAME_USER_STATISTICS_VISIBILITY, show);
}
}catch(Exception e){
_log.error("Unable to check user's privacy for his statistics", e);
}
}
}
/**
* On servlet instanciation, create the custom field and set it to startingValue
* @param customFieldNameUserStatisticsVisibility
@ -474,31 +491,31 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
*/
private void createUserCustomField(
String customFieldNameUserStatisticsVisibility, boolean startingValue) {
// set permission checker
setPermissionChecker();
try{
User defaultUser = UserLocalServiceUtil.getDefaultUser(ManagementUtils.getCompany().getCompanyId());
// check if it exists
boolean exists = defaultUser.getExpandoBridge().hasAttribute(customFieldNameUserStatisticsVisibility);
if(exists){
_log.debug("Custom field already exists... There is no need to create it");
}else{
_log.debug("Creating custom field " + customFieldNameUserStatisticsVisibility +
" with starting value " + startingValue);
// create
defaultUser.getExpandoBridge().addAttribute(CUSTOM_FIELD_NAME_USER_STATISTICS_VISIBILITY, ExpandoColumnConstants.BOOLEAN, (Serializable)(true));
}
}catch(Exception e){
_log.error("Unable to create custom field " + customFieldNameUserStatisticsVisibility);
}
@ -557,12 +574,16 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
private static int evaluateInformationScore(User user, boolean imageIsPresent) {
int score = 0;
score += user.getJobTitle().compareTo("") != 0 ? 20 : 0;
score += user.getOpenId().compareTo("") != 0 ? 20 : 0;
if(user.getJobTitle() != null)
score += !user.getJobTitle().isEmpty() ? 20 : 0;
if(user.getOpenId() != null)
score += !user.getOpenId().isEmpty() ? 20 : 0;
String summary = getSummary(user);
int lenght = summary.replace(" ", "").length();
float partialScore = ((float)lenght / 10.0f);
score += partialScore > 20f ? 20 : (int)partialScore;
if(summary != null){
int lenght = summary.replace(" ", "").length();
float partialScore = ((float)lenght / 10.0f);
score += partialScore > 20f ? 20 : (int)partialScore;
}
if(imageIsPresent)
score += 5;
@ -576,12 +597,15 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
* @return
*/
private static String getSummary(User user) {
String toReturn = escapeHtml(user.getComments());
// replace all the line breaks by <br/>
toReturn = toReturn.replaceAll("(\r\n|\n)"," <br/> ");
// then replace all the double spaces by the html version &nbsp;
toReturn = toReturn.replaceAll("\\s\\s","&nbsp;&nbsp;");
return toReturn;
if(user.getComments() != null){
String toReturn = escapeHtml(user.getComments());
// replace all the line breaks by <br/>
toReturn = toReturn.replaceAll("(\r\n|\n)"," <br/> ");
// then replace all the double spaces by the html version &nbsp;
toReturn = toReturn.replaceAll("\\s\\s","&nbsp;&nbsp;");
return toReturn;
}else
return null;
}
/**
@ -611,12 +635,18 @@ public class UserStatisticsServiceImpl extends RemoteServiceServlet implements U
try{
Contact contact = user.getContact();
score += contact.getMySpaceSn().compareTo("") != 0 ? 5 : 0;
score += contact.getTwitterSn().compareTo("") != 0 ? 5 : 0;
score += contact.getFacebookSn().compareTo("") != 0 ? 5 : 0;
score += contact.getSkypeSn().compareTo("") != 0 ? 5 : 0;
score += contact.getJabberSn().compareTo("") != 0 ? 5 : 0;
score += contact.getAimSn().compareTo("") != 0 ? 5 : 0;
if(contact.getMySpaceSn() != null)
score += !contact.getMySpaceSn().isEmpty() ? 5 : 0;
if(contact.getTwitterSn() != null)
score += !contact.getTwitterSn().isEmpty() ? 5 : 0;
if(contact.getFacebookSn() != null)
score += !contact.getFacebookSn().isEmpty() ? 5 : 0;
if(contact.getSkypeSn() != null)
score += !contact.getSkypeSn().isEmpty() ? 5 : 0;
if(contact.getJabberSn() != null)
score += !contact.getJabberSn().isEmpty() ? 5 : 0;
if(contact.getAimSn() != null)
score += !contact.getAimSn().isEmpty() ? 5 : 0;
List<Website> websites = WebsiteLocalServiceUtil.getWebsites(user.getCompanyId(), "com.liferay.portal.model.Contact", contact.getContactId());
score += websites.size() > 0 ? 5 : 0;

View File

@ -0,0 +1,26 @@
package org.gcube.portlet.user.userstatisticsportlet.server.cache;
/**
* Statistics cache interface
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @param <K> the key type
* @param <V> the value type
*/
public interface CacheInterface <K,V>{
/**
* Retrieve a value V from the cache
* @param key
* @return
*/
public V get(K key);
/**
* Insert an object V with key K into the cache
* @param key
* @param value
* @return
*/
public boolean insert(K key, V value);
}

View File

@ -0,0 +1,26 @@
package org.gcube.portlet.user.userstatisticsportlet.server.cache;
/**
* Utility functions for caches
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*
*/
public class CacheUtilities {
/**
* Check if the bean expired
* @param beanTimestamp
* @param ttl
* @return <true> if expired, <false> otherwise
*/
public static boolean expired(long beanTimestamp, long ttl){
long currentTime = System.currentTimeMillis();
if((beanTimestamp + ttl) <= currentTime)
return true;
else
return false;
}
}

View File

@ -0,0 +1,40 @@
package org.gcube.portlet.user.userstatisticsportlet.server.cache;
/**
* A bean object to be used as value within statistics' caches. It contains a TTL value too.
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*
* @param <V> the value type
*/
public class CacheValueBean <V>{
private V value;
private long TTL;
/**
* @param value
* @param tTL
*/
public CacheValueBean(V value, long ttl) {
super();
this.value = value;
this.TTL = ttl;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public long getTTL() {
return TTL;
}
public void setTTL(long ttl) {
this.TTL = ttl;
}
@Override
public String toString() {
return "CacheValueBean [value=" + value + ", TTL=" + TTL + "]";
}
}

View File

@ -0,0 +1,82 @@
package org.gcube.portlet.user.userstatisticsportlet.server.cache;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.LoggerFactory;
/**
* Cache for the user's space in use within the infrastructure
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*/
public class UserInfrastructureSpaceCache implements CacheInterface<String, Long> {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(UserInfrastructureSpaceCache.class);
/**
* The instance
*/
private static UserInfrastructureSpaceCache instance = new UserInfrastructureSpaceCache();
/**
* The hashmap
*/
private Map<String, CacheValueBean<Long>> userSpaceMap;
/**
* Cache entry expires after EXPIRED_AFTER ms
*/
private static final long EXPIRED_AFTER = 1000 * 60 * 10;
/**
* Private constructor
*/
private UserInfrastructureSpaceCache(){
userSpaceMap = new ConcurrentHashMap<>();
}
/**
* Retrieve the current cache instance object
* @return
*/
public static UserInfrastructureSpaceCache getCacheInstance(){
return instance;
}
@Override
public Long get(String key) {
if(userSpaceMap.containsKey(key)){
CacheValueBean<Long> bean = userSpaceMap.get(key);
if(CacheUtilities.expired(bean.getTTL(), EXPIRED_AFTER)){
userSpaceMap.remove(key);
logger.debug("Amount of space in the infrastructure used expired for key " + key + ", returning null");
}
else
return bean.getValue();
}
return null;
}
@Override
public boolean insert(String key, Long value) {
CacheValueBean<Long> newBean = new CacheValueBean<Long>(value, System.currentTimeMillis());
if(userSpaceMap.containsKey(key))
userSpaceMap.remove(key);
userSpaceMap.put(key, newBean);
return true;
}
}