/*
* Copyright (c) 2008-2012 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.db.client.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.emc.storageos.db.client.model.DataObject;
import com.emc.storageos.db.client.model.EncryptionProvider;
import com.emc.storageos.db.client.model.TimeSeries;
import com.emc.storageos.db.client.model.TimeSeriesSerializer;
import com.emc.storageos.db.client.util.KeyspaceUtil;
/**
* Global type map for all data object types
*/
public class TypeMap {
private static ConcurrentMap<Class<? extends DataObject>, DataObjectType> _typeMap =
new ConcurrentHashMap<Class<? extends DataObject>, DataObjectType>();
private static ConcurrentHashMap<Class<? extends TimeSeries>, TimeSeriesType> _timeSeriesMap =
new ConcurrentHashMap<Class<? extends TimeSeries>, TimeSeriesType>();
private static ConcurrentHashMap<String, TimeSeriesType> _tsTypeMap = new ConcurrentHashMap<>();
private static final SchemaRecordType _srType = new SchemaRecordType();
private static final GlobalLockType _glType = new GlobalLockType();
private static volatile EncryptionProvider _encryptionProvider;
private static volatile EncryptionProvider _geoEncryptionProvider;
/**
* Time series configuration overrides
*/
public static class TimeSeriesConfiguration {
private Class<? extends TimeSeries> _tsClass;
private Integer _ttl;
public void setTsClass(Class<? extends TimeSeries> clazz) {
_tsClass = clazz;
}
public Class<? extends TimeSeries> getTsClass() {
return _tsClass;
}
/**
* Overrie TTL configuration
*
* @param ttl
*/
public void setTtl(int ttl) {
_ttl = ttl;
}
/**
* TTL configuration
*
* @return
*/
public Integer getTtl() {
return _ttl;
}
}
/**
* Data object field configuration overrides
*/
public static class DataObjectFieldConfiguration {
private Class<? extends DataObject> _doClass;
private String _fieldName;
private Integer _ttl;
/**
* DataObject class
*
* @param clazz
*/
public void setDoClass(Class<? extends DataObject> clazz) {
_doClass = clazz;
}
public Class<? extends DataObject> getDoClass() {
return _doClass;
}
/**
* Target data object field
*
* @param fieldName
*/
public void setFieldName(String fieldName) {
_fieldName = fieldName;
}
public String getFieldName() {
return _fieldName;
}
/**
* Override default TTL configuration
*
* @param ttl
*/
public void setTtl(int ttl) {
_ttl = ttl;
}
/**
* TTL configuration
*
* @return
*/
public Integer getTtl() {
return _ttl;
}
}
/**
* User may optionally override default data object configuration (like TTL)
* by calling this method. Note that configuration must be loaded before
* DbClient is used
*/
public static void loadDataObjectConfiguration(List<DataObjectFieldConfiguration> configuration) {
for (DataObjectFieldConfiguration fieldConfig : configuration) {
DataObjectType doType = getDoType(fieldConfig.getDoClass());
ColumnField field = doType.getColumnField(fieldConfig.getFieldName());
if (field == null) {
throw new IllegalArgumentException(String.format(
"Unknown field: %1$s", fieldConfig.getFieldName()));
}
field.setTtl(fieldConfig.getTtl());
}
}
/**
* User may optionally override default time series configuration (like TTL) by calling this method.
* Note that configuration must be loaded before DbClient is used
*/
public static void loadTimeSeriesConfiguration(List<TimeSeriesConfiguration> configuration) {
for (TimeSeriesConfiguration tsConfig : configuration) {
TimeSeriesType tsType = getTimeSeriesType(tsConfig.getTsClass());
tsType.setTtl(tsConfig.getTtl());
}
}
/**
* Set encryption provider for all local data object types
*
* @param encryptionProvider
*/
public static void setEncryptionProviders(EncryptionProvider encryptionProvider,
EncryptionProvider geoEncryptionProvider) {
_encryptionProvider = encryptionProvider;
_geoEncryptionProvider = geoEncryptionProvider;
Iterator<DataObjectType> it = _typeMap.values().iterator();
while (it.hasNext()) {
setEncryptionProvider(it.next());
}
}
private static void setEncryptionProvider(DataObjectType doType) {
if (KeyspaceUtil.isLocal(doType.getDataObjectClass())) {
doType.setEncryptionProvider(_encryptionProvider);
} else {
doType.setEncryptionProvider(_geoEncryptionProvider);
}
}
/**
* Retrieve time series type
*
* @param clazz time series class
* @param <T>
* @return
*/
@SuppressWarnings(value = "unchecked")
public static <T extends TimeSeriesSerializer.DataPoint>
TimeSeriesType<T> getTimeSeriesType(Class<? extends TimeSeries> clazz) {
TimeSeriesType<T> ttype = _timeSeriesMap.get(clazz);
if (ttype != null) {
return ttype;
}
ttype = new TimeSeriesType<T>(clazz);
_timeSeriesMap.putIfAbsent(clazz, ttype);
_tsTypeMap.putIfAbsent(ttype.getCf().getName(), ttype);
return _timeSeriesMap.get(clazz);
}
/**
* Retrieve time series type
*
* @param cfName time series CF
* @param <T>
* @return
*/
@SuppressWarnings(value = "unchecked")
public static <T extends TimeSeriesSerializer.DataPoint>
TimeSeriesType<T> getTimeSeriesType(String cfName) {
return _tsTypeMap.get(cfName);
}
/**
* Retrieve data object type
*
* @param clazz data object class
* @return
*/
public static DataObjectType getDoType(Class<? extends DataObject> clazz) {
DataObjectType doType = _typeMap.get(clazz);
if (doType != null) {
return doType;
}
doType = new DataObjectType(clazz);
setEncryptionProvider(doType);
_typeMap.putIfAbsent(clazz, doType);
if (doType.getInstrumentedType() != null) {
_typeMap.putIfAbsent(doType.getInstrumentedType(), doType);
}
return doType;
}
public static String getCFName(Class<? extends DataObject> clazz) {
return getDoType(clazz).getCF().getName();
}
public static SchemaRecordType getSchemaRecordType() {
return _srType;
}
public static GlobalLockType getGlobalLockType() {
return _glType;
}
public static void clear() {
_typeMap.clear();
}
/**
* Check the integrity of DataObject classes
* throws RuntimeException if error occurs.
*/
public static void check() {
Iterator<DataObjectType> doIterator = _typeMap.values().iterator();
while (doIterator.hasNext()) {
DataObjectType doType = doIterator.next();
Iterator<ColumnField> columnIterator = doType.getColumnFields().iterator();
while (columnIterator.hasNext()) {
ColumnField field = columnIterator.next();
field.check();
}
}
}
/**
* @return a copy of all DoType objects
*/
public static Collection<DataObjectType> getAllDoTypes() {
return Collections.unmodifiableCollection(_typeMap.values());
}
}