/** * 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.Collections; import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentSkipListSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.id.ExternalId; import com.opengamma.id.ObjectId; import com.opengamma.master.config.ConfigMaster; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotMaster; import com.opengamma.util.ArgumentChecker; /** * Tracks userData and clients */ public class DefaultFinancialUsersTracker implements FinancialUserDataTracker, FinancialClientTracker { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(DefaultFinancialUsersTracker.class); private final ConcurrentMap<String, Set<String>> _username2clients = new ConcurrentHashMap<String, Set<String>>(); private final ConcurrentMap<ExternalId, Set<ObjectId>> _viewDefinitionIds = new ConcurrentHashMap<ExternalId, Set<ObjectId>>(); private final ConcurrentMap<ExternalId, Set<ObjectId>> _marketDataSnapShots = new ConcurrentHashMap<ExternalId, Set<ObjectId>>(); private final FinancialUserServices _services; public DefaultFinancialUsersTracker(FinancialUserServices services) { ArgumentChecker.notNull(services, "services"); _services = services; } //------------------------------------------------------------------------- /** * Gets the services. * * @return the services, not null */ public FinancialUserServices getServices() { return _services; } //------------------------------------------------------------------------- @Override public void created(String userName, String clientName, FinancialUserDataType type, ObjectId identifier) { switch (type) { case VIEW_DEFINITION: trackCreatedViewDefinition(userName, clientName, identifier); break; case MARKET_DATA_SNAPSHOT: trackCreatedMarketDataSnapshot(userName, clientName, identifier); break; } Set<String> clients = _username2clients.get(userName); if (clients != null) { if (clients.contains(clientName)) { s_logger.debug("{} created by {}", identifier, userName); } } else { s_logger.debug("Late creation of {} by {}", identifier, userName); } } private void trackCreatedMarketDataSnapshot(String userName, String clientName, ObjectId identifier) { ConcurrentSkipListSet<ObjectId> freshIds = new ConcurrentSkipListSet<ObjectId>(); Set<ObjectId> marketDataSnapshotIds = _marketDataSnapShots.putIfAbsent(ExternalId.of(userName, clientName), freshIds); if (marketDataSnapshotIds == null) { marketDataSnapshotIds = freshIds; } marketDataSnapshotIds.add(identifier); s_logger.debug("{} marketdatasnapshot created by {}", identifier, userName); } private void trackCreatedViewDefinition(String userName, String clientName, ObjectId identifier) { ConcurrentSkipListSet<ObjectId> freshDefinitions = new ConcurrentSkipListSet<ObjectId>(); Set<ObjectId> viewDefinitions = _viewDefinitionIds.putIfAbsent(ExternalId.of(userName, clientName), freshDefinitions); if (viewDefinitions == null) { viewDefinitions = freshDefinitions; } viewDefinitions.add(identifier); s_logger.debug("{} view created by {}", identifier, userName); } @Override public void deleted(String userName, String clientName, FinancialUserDataType type, ObjectId identifier) { Set<String> clients = _username2clients.get(userName); if (clients != null) { if (clients.contains(clientName)) { s_logger.debug("{} deleted by {}", identifier, userName); return; } } s_logger.debug("Late deletion of {} by {}", identifier, userName); } @Override public void clientCreated(String userName, String clientName) { Set<String> clients = _username2clients.get(userName); if (clients == null) { s_logger.debug("Late client construction for discarded user {}", userName); return; } clients.add(clientName); s_logger.debug("Client {} created for user {}", clientName, userName); } @Override public void clientDiscarded(String userName, String clientName) { Set<String> clients = _username2clients.get(userName); if (clients == null) { s_logger.debug("Late client discard for discarded user {}", userName); } else { clients.remove(clientName); s_logger.debug("Client {} discarded for user {}", clientName, userName); } removeUserViewDefinitions(userName, clientName); removeUserMarketDataSnapshot(userName, clientName); } private void removeUserMarketDataSnapshot(String userName, String clientName) { MarketDataSnapshotMaster marketDataSnapshotMaster = getServices().getSnapshotMaster(); if (marketDataSnapshotMaster != null) { Set<ObjectId> snapshotIds = _marketDataSnapShots.remove(ExternalId.of(userName, clientName)); for (ObjectId oid : snapshotIds) { marketDataSnapshotMaster.remove(oid); s_logger.debug("market data snapshot {} discarded for {}/{}", new Object[]{oid, userName, clientName}); } } } private void removeAllUserMarketDataSnapshot(String userName) { MarketDataSnapshotMaster marketDataSnapshotMaster = getServices().getSnapshotMaster(); if (marketDataSnapshotMaster != null) { Iterator<Entry<ExternalId, Set<ObjectId>>> iterator = _marketDataSnapShots.entrySet().iterator(); while (iterator.hasNext()) { Entry<ExternalId, Set<ObjectId>> entry = iterator.next(); ExternalId identifier = entry.getKey(); if (identifier.getScheme().getName().equals(userName)) { Set<ObjectId> oids = entry.getValue(); for (ObjectId oid : oids) { marketDataSnapshotMaster.remove(oid); s_logger.debug("market data snapshot {} discarded for {}/{}", new Object[]{oid, userName, identifier.getValue()}); } iterator.remove(); } } } } @Override public void userCreated(String userName) { Set<String> clients = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); _username2clients.putIfAbsent(userName, clients); s_logger.debug("User {} created", userName); } @Override public void userDiscarded(String userName) { Set<String> removedClients = _username2clients.remove(userName); s_logger.debug("User {} discarded", userName); if (removedClients != null) { for (String clientName : removedClients) { removeUserViewDefinitions(userName, clientName); removeUserMarketDataSnapshot(userName, clientName); } } else { removeAllUserViewDefinitions(userName); removeAllUserMarketDataSnapshot(userName); } } private void removeAllUserViewDefinitions(String userName) { ConfigMaster configMaster = getServices().getConfigMaster(); if (configMaster != null) { Iterator<Entry<ExternalId, Set<ObjectId>>> iterator = _viewDefinitionIds.entrySet().iterator(); while (iterator.hasNext()) { Entry<ExternalId, Set<ObjectId>> entry = iterator.next(); ExternalId identifier = entry.getKey(); if (identifier.getScheme().getName().equals(userName)) { Set<ObjectId> viewDefinitions = entry.getValue(); for (ObjectId viewDefinitionId : viewDefinitions) { configMaster.remove(viewDefinitionId); s_logger.debug("View definition {} discarded for {}/{}", new Object[]{viewDefinitionId, userName, identifier.getValue()}); } iterator.remove(); } } } } private void removeUserViewDefinitions(final String userName, final String clientName) { ConfigMaster configMaster = getServices().getConfigMaster(); if (configMaster != null) { Set<ObjectId> viewDefinitions = _viewDefinitionIds.remove(ExternalId.of(userName, clientName)); for (ObjectId viewDefinitionId : viewDefinitions) { configMaster.remove(viewDefinitionId); s_logger.debug("View definition {} discarded for {}/{}", new Object[]{viewDefinitionId, userName, clientName}); } } } }