package fr.ippon.tatami.repository.cassandra;
import com.google.common.collect.Maps;
import fr.ippon.tatami.repository.RegistrationRepository;
import fr.ippon.tatami.service.util.RandomUtil;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.hector.api.Keyspace;
import me.prettyprint.hector.api.beans.ColumnSlice;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.ColumnQuery;
import me.prettyprint.hector.api.query.SliceQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import javax.inject.Inject;
import java.util.List;
import java.util.Map;
import static fr.ippon.tatami.config.ColumnFamilyKeys.REGISTRATION_CF;
/**
* Cassandra implementation of the Registration repository.
* <p/>
* Structure :
* - Key = "registration_key"
* - Name = key
* - Value = login
*
* @author Julien Dubois
*/
@Repository
public class CassandraRegistrationRepository implements RegistrationRepository {
private static final Logger log = LoggerFactory.getLogger(CassandraRegistrationRepository.class);
private final static String ROW_KEY = "registration_key";
private final static int COLUMN_TTL = 60 * 60 * 24 * 2; // The column is stored for 2 days.
@Inject
private Keyspace keyspaceOperator;
@Override
public String generateRegistrationKey(String login) {
String key = RandomUtil.generateRegistrationKey();
HColumn<String, String> column = HFactory.createColumn(key,
login, COLUMN_TTL, StringSerializer.get(), StringSerializer.get());
Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());
mutator.insert(ROW_KEY, REGISTRATION_CF, column);
return key;
}
@Override
public String getLoginByRegistrationKey(String registrationKey) {
ColumnQuery<String, String, String> query = HFactory.createStringColumnQuery(keyspaceOperator);
HColumn<String, String> column =
query.setColumnFamily(REGISTRATION_CF)
.setKey(ROW_KEY)
.setName(registrationKey)
.execute()
.get();
if (column != null) {
return column.getValue();
} else {
return null;
}
}
/**
* !! For testing purpose only !!
* This method is not efficient and is limited to 10000 registrations.
* Other limitation : if a login is associated to multiple registrationKey
*/
public Map<String, String> _getAllRegistrationKeyByLogin() {
log.warn("Calling _getAllRegistrationKeyByLogin() is only for testing purposes!");
Map<String, String> registrationKeyByLogin = Maps.newHashMap();
SliceQuery<String, String, String> sliceQuery = HFactory.createSliceQuery(keyspaceOperator,
StringSerializer.get(), StringSerializer.get(), StringSerializer.get());
ColumnSlice<String, String> columnSlice =
sliceQuery.setColumnFamily(REGISTRATION_CF)
.setKey(ROW_KEY)
.setRange(null, null, false, 10000)
.execute().get();
List<HColumn<String, String>> columns = columnSlice.getColumns();
for (HColumn<String, String> hColumn : columns) {
// WARN : here we don't handle multiple registrationKey for one login
registrationKeyByLogin.put(hColumn.getValue(), hColumn.getName());
log.debug("Key={}|Value={}", hColumn.getValue(), hColumn.getName());
}
return registrationKeyByLogin;
}
}