package eu.ttbox.androgister.repository;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import javax.annotation.PostConstruct;
import me.prettyprint.cassandra.serializers.BigDecimalSerializer;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.cassandra.serializers.UUIDSerializer;
import me.prettyprint.cassandra.service.template.ColumnFamilyUpdater;
import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;
import me.prettyprint.cassandra.utils.TimeUUIDUtils;
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.beans.Row;
import me.prettyprint.hector.api.beans.Rows;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.MultigetSliceQuery;
import me.prettyprint.hom.EntityManagerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Repository;
import com.netflix.astyanax.model.ColumnFamily;
import eu.ttbox.androgister.config.cassandra.ColumnFamilyKeys;
import eu.ttbox.androgister.model.Product;
//@Repository
public class CassandraProductRepository extends AbstractEntityRepository<UUID, String> {
private static final Logger log = LoggerFactory.getLogger(CassandraProductRepository.class);
// ColumnFamily<String, String> CF_USER_INFO =
// new ColumnFamily<String, String>(
// "Standard1", // Column Family Name
// StringSerializer.get(), // Key Serializer
// StringSerializer.get()); // Column Serializer
@Autowired
public CassandraProductRepository(Keyspace keyspace) {
super(keyspace);
}
public enum ProductColumn {
uuid, name, description, priceHT;
}
@Autowired
private EntityManagerImpl em;
private ThriftColumnFamilyTemplate<String, UUID> productSalespointTemplate;
@PostConstruct
public void init() {
productSalespointTemplate = new ThriftColumnFamilyTemplate<String, UUID>(keyspace, ColumnFamilyKeys.PRODUCT_SALESPOINT_CF.cfName, StringSerializer.get(), UUIDSerializer.get());
}
@Override
public ThriftColumnFamilyTemplate<UUID, String> createTemplate(Keyspace keyspace) {
ThriftColumnFamilyTemplate<UUID, String> template = new ThriftColumnFamilyTemplate<UUID, String>(keyspace, ColumnFamilyKeys.PRODUCT_CF.cfName, UUIDSerializer.get(), StringSerializer.get());
template.addColumn("name", StringSerializer.get());
template.addColumn("description", StringSerializer.get());
template.addColumn("priceHT", BigDecimalSerializer.get());
return template;
}
public void persist(Map<String, Object> entity) {
// Define Id
UUID uuid = (UUID) entity.get(ProductColumn.uuid.name());
if (uuid == null) {
uuid = TimeUUIDUtils.getUniqueTimeUUIDinMillis();
entity.put(ProductColumn.uuid.name(), uuid);
} else {
// Get Previous
getById(uuid);
}
// Save It
ColumnFamilyUpdater<UUID, String> updater = template.createUpdater(uuid);
for (Entry<String, Object> entry : entity.entrySet()) {
String colName = entry.getKey();
if (!colName.equals(ProductColumn.uuid.name())) {
updater.setColumn(HFactory.createColumn(colName, entry.getValue()));
}
}
template.update(updater);
// Dep
ColumnFamilyUpdater<String, UUID> spUpdater = productSalespointTemplate.createUpdater("salepoint");
spUpdater.setByteArray(uuid, new byte[0]);
productSalespointTemplate.update(spUpdater);
}
public void validateEntity(Product product) {
}
public void persist(Product product) {
log.debug("Creating product : {}", product);
validateEntity(product);
if (product.serverId == null) {
product.serverId = TimeUUIDUtils.getUniqueTimeUUIDinMillis(); // UUID.randomUUID();//
}
try {
em.persist(product);
addProductToSalespointline(product.serverId);
} catch (Exception e) {
log.error("Error Creating product {} : " + e.getMessage());
}
log.debug("Creating End product : {}", product);
}
public void addProductToSalespointline(UUID productUUID) {
Mutator<String> mutator = HFactory.createMutator(keyspace, StringSerializer.get());
mutator.insert("ALL", ColumnFamilyKeys.PRODUCT_SALESPOINT_CF.cfName, HFactory.createColumn(productUUID, "", UUIDSerializer.get(), StringSerializer.get()));
}
public void removeProductToSalespointline(UUID productUUID) {
Mutator<String> mutator = HFactory.createMutator(keyspace, StringSerializer.get());
mutator.addDeletion("ALL", ColumnFamilyKeys.PRODUCT_SALESPOINT_CF.cfName, productUUID, UUIDSerializer.get());
mutator.execute();
}
@CacheEvict(value = "product-cache", key = "#product.login")
public void remove(Product product) {
log.debug("Deleting product : {} ", product);
Mutator<UUID> mutator = HFactory.createMutator(keyspace, UUIDSerializer.get());
mutator.addDeletion(product.serverId, ColumnFamilyKeys.PRODUCT_CF.cfName);
mutator.execute();
// template.deleteRow(product.uuid);
// productSalespointTemplate.doExecuteSlice(key, predicate, mapper)
// Depends
UUID productUUID = product.serverId;
removeProductToSalespointline(productUUID);
}
public Product findById(UUID uuid) {
Product entity = null;
try {
entity = em.find(Product.class, uuid);
} catch (Exception e) {
log.warn("Exception while looking for product {} : {}", uuid, e.getMessage());
}
return entity;
}
// https://github.com/rantav/hector/blob/master/core/src/test/java/me/prettyprint/cassandra/service/template/ColumnFamilyTemplateTest.java
// https://github.com/rantav/hector/wiki/Getting-started-%285-minutes%29
public List<Map<String, Object>> finddAll() {
// --- Version Slice --- //
// HFactory.createRangeSlicesQuery(keyspace, StringSerializer.get(),
// UUIDSerializer.get(), StringSerializer.get())
ColumnSlice<UUID, String> query = HFactory.createSliceQuery(keyspace, StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get()).setColumnFamily(ColumnFamilyKeys.PRODUCT_SALESPOINT_CF.cfName)//
.setKey("ALL")//
.setRange(null, null, false, 5)//
.execute().get();
// Read
List<UUID> productUUIDs = new ArrayList<UUID>();
List<HColumn<UUID, String>> resultCols = query.getColumns();
for (HColumn<UUID, String> column : resultCols) {
productUUIDs.add(column.getName());
}
// Multi get
MultigetSliceQuery<UUID, String, String> multiQuery = HFactory.createMultigetSliceQuery(keyspace, UUIDSerializer.get(), StringSerializer.get(), StringSerializer.get()) //
.setColumnFamily(ColumnFamilyKeys.PRODUCT_CF.cfName) //
.setRange(null, null, false, Integer.MAX_VALUE) //
.setKeys(productUUIDs);
Rows<UUID, String, String> rows = multiQuery.execute().get();
// --- Version VQL --- //
// CqlQuery<UUID, String, String> cqlQuery = new CqlQuery<UUID, String,
// String>(keyspace, UUIDSerializer.get(), StringSerializer.get(),
// StringSerializer.get()) //
// .setQuery("select * from Product")//
// ;
List<Map<String, Object>> entities = new LinkedList<Map<String, Object>>();
// QueryResult<CqlRows<UUID, String, String>> result =
// cqlQuery.execute();
// CqlRows<UUID, String, String> rows = result.get();
if (rows.getCount() > 0) {
Iterator<Row<UUID, String, String>> it = rows.iterator();
while (it.hasNext()) {
Row<UUID, String, String> row = it.next();
UUID key = row.getKey();
ColumnSlice<String, String> colSlice = row.getColumnSlice();
Map<String, Object> entity = readEntityRow(key, colSlice);
entities.add(entity);
}
}
return entities;
}
public Map<String, Object> readEntityRow(UUID key, ColumnSlice<String, String> colSlice) {
Map<String, Object> entity = new HashMap<String, Object>();
entity.put("uuid", key);
entity.put("name", getColumnStringValueByName(colSlice, "name"));
entity.put("description", getColumnStringValueByName(colSlice, "description"));
return entity;
}
public <T> T getColumnStringValueByName(ColumnSlice<String, T> colSlice, String columName) {
HColumn<String, T> col = colSlice.getColumnByName(columName);
if (col != null) {
return col.getValue();
} else {
return null;
}
}
}