package org.dcache.services.info.stateInfo;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* A simple class to store information about a link.
*/
public class LinkInfo
{
/**
* The different types of unit that may be used to select a link. These
* are dcache, store, protocol and network.
*/
public enum UNIT_TYPE
{
DCACHE("dcache"), STORE("store"), PROTOCOL("protocol"), NETWORK("net");
private String _pathElement;
UNIT_TYPE(String pathElement)
{
_pathElement = pathElement;
}
public String getPathElement()
{
return _pathElement;
}
}
/**
* The four different types of operation that may be allowed on a link.
* These are read, write, stage and pool-to-pool destination.
*/
public enum OPERATION
{
READ("read"), WRITE("write"), CACHE("cache"), P2P("p2p");
private String _pathElement;
OPERATION(String pathElement)
{
_pathElement = pathElement;
}
public String getPathElement()
{
return _pathElement;
}
}
private final String _id;
private final Set<String> _pools = new HashSet<>();
private final Set<String> _poolgroups = new HashSet<>();
private final Set<String> _unitgroups = new HashSet<>();
private final Multimap<UNIT_TYPE, String> _units = HashMultimap.create();
private final Map<OPERATION, Long> _operationPref = new ConcurrentHashMap<>();
public LinkInfo(String id)
{
_id = id;
}
protected void addPool(String poolName)
{
synchronized (_pools) {
_pools.add(poolName);
}
}
protected void addPoolgroup(String poolgroup)
{
synchronized (_poolgroups) {
_poolgroups.add(poolgroup);
}
}
protected void addUnitgroup(String unitgroupName)
{
synchronized (_unitgroups) {
_unitgroups.add(unitgroupName);
}
}
protected void addUnit(UNIT_TYPE type, String unitName)
{
synchronized (_units) {
_units.put(type, unitName);
}
}
protected void setOperationPref(OPERATION operation, long pref)
{
_operationPref.put(operation, pref);
}
public String getId()
{
return _id;
}
public Set<String> getPools()
{
synchronized (_pools) {
return ImmutableSet.copyOf(_pools);
}
}
public Set<String> getPoolgroups()
{
synchronized (_poolgroups) {
return ImmutableSet.copyOf(_poolgroups);
}
}
public Set<String> getUnitgroups()
{
synchronized (_unitgroups) {
return ImmutableSet.copyOf(_unitgroups);
}
}
public Set<String> getUnits(UNIT_TYPE unitType)
{
synchronized (_units) {
return ImmutableSet.copyOf(_units.get(unitType));
}
}
public long getOperationPref(OPERATION operation)
{
Long preference = _operationPref.get(operation);
// If not defined, assume not accessible for this operation.
if (preference == null) {
return 0;
}
return preference;
}
public boolean isAccessableFor(OPERATION operation)
{
long pref = getOperationPref(operation);
if (operation == OPERATION.P2P) {
return pref > 0 ||
(pref == -1 && getOperationPref(OPERATION.READ) > 0);
}
return pref > 0;
}
@Override
public int hashCode()
{
return _pools.hashCode() ^ _poolgroups.hashCode() ^ _units.hashCode() ^
_operationPref.hashCode();
}
@Override
public boolean equals(Object otherObject)
{
if (!(otherObject instanceof LinkInfo)) {
return false;
}
if (this == otherObject) {
return true;
}
LinkInfo otherLink = (LinkInfo) otherObject;
if (!_pools.equals(otherLink._pools)) {
return false;
}
if (!_poolgroups.equals(otherLink._poolgroups)) {
return false;
}
if (!_units.equals(otherLink._units)) {
return false;
}
if (!_operationPref.equals(otherLink._operationPref)) {
return false;
}
return true;
}
/**
* A handy method to emit some debugging information about this LinkInfo.
*/
public String debugInfo()
{
StringBuilder sb = new StringBuilder();
sb.append("=== LinkInfo for link \"").append(_id).append("\" ===\n");
if (_pools.size() > 0) {
sb.append(" Pools:\n");
for (String poolName : _pools) {
sb.append(" ").append(poolName).append("\n");
}
}
if (_poolgroups.size() > 0) {
sb.append(" Poolgroups:\n");
for (String poolgroupName : _poolgroups) {
sb.append(" ").append(poolgroupName).append("\n");
}
}
boolean haveOperation = false;
for (OPERATION operation : OPERATION.values()) {
if (_operationPref.containsKey(operation)) {
haveOperation = true;
break;
}
}
if (haveOperation) {
sb.append(" Preferences:\n");
for (OPERATION operation : OPERATION.values()) {
if (_operationPref.containsKey(operation)) {
sb.append(" ").append(operation).append(": ")
.append(_operationPref.get(operation)).append("\n");
}
}
}
boolean haveUnits = false;
for (UNIT_TYPE type : UNIT_TYPE.values()) {
if (_units.containsKey(type)) {
haveUnits = true;
break;
}
}
if (haveUnits) {
sb.append(" Units:\n");
for (UNIT_TYPE type : UNIT_TYPE.values()) {
Collection<String> units = _units.get(type);
if (!units.isEmpty()) {
sb.append(" ").append(type).append(":\n");
for (String unitName : units) {
sb.append(" ").append(unitName).append("\n");
}
}
}
}
return sb.toString();
}
}