/*************************************************************************
* Copyright 2009-2014 Eucalyptus Systems, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
* Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
* CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
* additional information or have any questions.
************************************************************************/
package com.eucalyptus.system.tracking;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import edu.ucsb.eucalyptus.msgs.BaseMessage;
/**
* @author Sang-Min Park
*
*/
public class MessageContexts {
private static final Logger LOG = Logger.getLogger(MessageContexts.class);
private static Cache<String, List<MessageCache>> correlationIds =
CacheBuilder.newBuilder()
.maximumSize(3000)
.expireAfterAccess(1, TimeUnit.HOURS)
.build();
public static synchronized void remember(final String resourceId, final Class<? extends BaseMessage> msgType, BaseMessage message) {
List<MessageCache> listIds = null;
listIds = correlationIds.getIfPresent(resourceId);
if(listIds == null){
listIds = Lists.newArrayList();
correlationIds.put(resourceId, listIds);
}
int duplicate = -1;
for(int i=0; i<listIds.size(); i++){
final MessageCache corrId = listIds.get(i);
if(msgType.equals(corrId.getKey())){
duplicate = i;
break;
}
}
if(duplicate>=0)
listIds.remove(duplicate);
try{
listIds.add(new MessageCache(msgType, message ));
}catch(final Exception ex){
throw Exceptions.toUndeclared(new EucalyptusCloudException("Correlation Id is in wrong format"));
}
}
public static synchronized boolean contains(final String resourceId, final Class<? extends BaseMessage> msgType){
return lookup(resourceId, msgType) != null;
}
public static synchronized BaseMessage lookupLast(final String resourceId, Set<Class> msgTypes) {
List<MessageCache> messages = correlationIds.getIfPresent(resourceId);
if(messages == null)
return null;
final List<MessageCache> result = Lists.newArrayList();
for(final MessageCache corrId : messages){
if(msgTypes.contains(corrId.getKey()))
result.add(corrId);
}
if(result.size()<=0)
return null;
BaseMessage lastMsg = result.get(0).getValue();
long lastTs = result.get(0).getCreationTime().getTime();
for(final MessageCache corrId : result){
if(corrId.getCreationTime().getTime() > lastTs){
lastMsg = corrId.getValue();
lastTs = corrId.getCreationTime().getTime();
}
}
return lastMsg;
}
public static synchronized List<BaseMessage> lookup(final String resourceId, final Set<Class> msgTypes) {
List<MessageCache> messages = correlationIds.getIfPresent(resourceId);
if(messages == null)
return Lists.newArrayList();
final List<BaseMessage> result = Lists.newArrayList();
for(final MessageCache corrId : messages){
if(msgTypes.contains(corrId.getKey()))
result.add(corrId.getValue());
}
return result;
}
public static synchronized BaseMessage lookup(final String resourceId, final Class<? extends BaseMessage> msgType) {
List<MessageCache> messages = correlationIds.getIfPresent(resourceId);
if(messages == null)
return null;
for(final MessageCache corrId : messages){
if(msgType.equals(corrId.getKey()))
return corrId.getValue();
}
return null;
}
public static synchronized List<BaseMessage> lookup(final String resourceId){
List<MessageCache> messages = correlationIds.getIfPresent(resourceId);
if(messages == null)
return Lists.newArrayList();
return Lists.transform(messages, new Function<MessageCache, BaseMessage>(){
@Override
public BaseMessage apply(MessageCache arg0) {
return arg0.getValue();
}
});
}
}