/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.user;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.Duration;
import org.threeten.bp.Instant;
/**
* A manager of users that provide access to underlying services which are managed.
* <p>
* This class is a placeholder until full user management is added.
*/
public class FinancialUserManager {
/** Logger. */
private static final Logger s_logger = LoggerFactory.getLogger(FinancialUserManager.class);
/**
* The map of users.
*/
private final ConcurrentHashMap<String, FinancialUser> _userMap = new ConcurrentHashMap<String, FinancialUser>();
/**
* The user services.
*/
private final FinancialUserServices _services;
/**
* The client tracker.
*/
private final FinancialClientTracker _clientTracker;
/**
* The user data tracker.
*/
private final FinancialUserDataTracker _userDataTracker;
/**
* Creates an instance.
*
* @param services the services, not null
* @param clientTracker the tracker, not null
* @param userDataTracker the tracker, not null
*/
public FinancialUserManager(FinancialUserServices services, FinancialClientTracker clientTracker, FinancialUserDataTracker userDataTracker) {
_services = services;
_clientTracker = clientTracker;
_userDataTracker = userDataTracker;
}
//-------------------------------------------------------------------------
/**
* Gets the services.
*
* @return the services, not null
*/
public FinancialUserServices getServices() {
return _services;
}
/**
* Gets the tracker.
*
* @return the tracker, not null
*/
public FinancialClientTracker getClientTracker() {
return _clientTracker;
}
/**
* Gets the tracker.
*
* @return the tracker, not null
*/
public FinancialUserDataTracker getUserDataTracker() {
return _userDataTracker;
}
//-------------------------------------------------------------------------
/**
* Gets a user.
*
* @param userName the user name, not null
* @return the user, null if not found
*/
public FinancialUser getUser(String userName) {
return _userMap.get(userName);
}
/**
* Gets a user, creating if it does not exist.
*
* @param userName the user name, not null
* @return the user, not null
*/
public FinancialUser getOrCreateUser(String userName) {
FinancialUser user = _userMap.get(userName);
if (user == null) {
_clientTracker.userCreated(userName);
FinancialUser freshUser = new FinancialUser(this, userName);
user = _userMap.putIfAbsent(userName, freshUser);
if (user == null) {
user = freshUser;
}
}
return user;
}
//-------------------------------------------------------------------------
/**
* Discards any users and clients that haven't been accessed since the given timestamp.
*
* @param timestamp any client resources with a last accessed time before this will be removed
*/
public void deleteClients(final Instant timestamp) {
final Iterator<Map.Entry<String, FinancialUser>> userIterator = _userMap.entrySet().iterator();
while (userIterator.hasNext()) {
final Map.Entry<String, FinancialUser> userEntry = userIterator.next();
s_logger.debug("deleting clients for user {}", userEntry.getKey());
int activeClients = userEntry.getValue().getClientManager().deleteClients(timestamp);
if (activeClients == 0) {
s_logger.debug("deleting user {}", userEntry.getKey());
userIterator.remove();
getClientTracker().userDiscarded(userEntry.getKey());
}
}
}
//-------------------------------------------------------------------------
/**
* Creates the scheduled deletion task.
*
* @param scheduler the scheduler, not null
* @param clientTimeOut the time out for clients, not null
*/
public void createDeleteTask(ScheduledExecutorService scheduler, Duration clientTimeOut) {
long timeOutMillis = clientTimeOut.toMillis();
DeleteClientsRunnable runnable = new DeleteClientsRunnable(timeOutMillis);
scheduler.scheduleWithFixedDelay(runnable, timeOutMillis, timeOutMillis, TimeUnit.MILLISECONDS);
}
/**
* Runnable to delete clients.
*/
class DeleteClientsRunnable implements Runnable {
private final long _timeoutMillis;
public DeleteClientsRunnable(long timeoutMillis) {
super();
_timeoutMillis = timeoutMillis;
}
@Override
public void run() {
deleteClients(Instant.now().minusMillis(_timeoutMillis));
}
}
}