2010-10-24 39 views
1

J'ai écrit un test simpe pour valider ma propre compréhension de l'interface d'épargne pour Cassandra. Il insère simplement une ligne dans la base de données (en utilisant l'espace de clés et la colonne familty qui sont préconfigurées avec l'installation de Cassandra), puis le lit dans la base de données et compare les résultats.L'insertion dans Cassandra via thrift-client ne fonctionne pas après la suppression d'une ligne via cassandra-cli

public class CassandraAPITest { 
    @Test 
    public void testCassandraAPI() throws Exception { 
     TTransport tr = new TSocket("localhost", 9160); 
     tr.open(); 
     Client client = new Cassandra.Client(new TBinaryProtocol(tr)); 
     String key = "123"; 
     byte[] value = { 52, 53, 54 }; 
     ColumnPath columnPath = new ColumnPath("Standard1"); 
     columnPath.setColumn("abc".getBytes("UTF8")); 
     long timestamp = System.currentTimeMillis(); 

     client.insert("Keyspace1", key, columnPath, value, timestamp, ConsistencyLevel.ONE); 

     SlicePredicate predicate = new SlicePredicate(); 
     SliceRange sliceRange = new SliceRange(); 
     sliceRange.setStart(new byte[0]); 
     sliceRange.setFinish(new byte[0]); 
     predicate.setSlice_range(sliceRange); 

     List<ColumnOrSuperColumn> result = client.get_slice("Keyspace1", key, new ColumnParent("Standard1"), predicate, ConsistencyLevel.ONE); 

     assertEquals(1, result.size()); 
     byte[] actual = result.get(0).column.value; 
     assertArrayEquals(value, actual); 

     // client.remove("Keyspace1", key, columnPath, System.currentTimeMillis(), ConsistencyLevel.ONE); 

     tr.close(); 
    } 
} 

Ce test fonctionne correctement. Bien sûr, il laisse une rangée derrière dans la base de données. Je pourrais supprimer la ligne à la fin du test en décommentant l'instruction client.remove ci-dessus (cela fonctionne également très bien). Mais ce que j'ai essayé à la place était de supprimer la ligne via l'interface de ligne de commande:

cassandra> connect localhost/9160     
Connected to: "Test Cluster" on localhost/9160 
cassandra> get Keyspace1.Standard1['123'] 
=> (column=616263, value=456, timestamp=1287909211506) 
Returned 1 results. 
cassandra> del Keyspace1.Standard1['123'] 
row removed. 
cassandra> get Keyspace1.Standard1['123'] 
Returned 0 results. 

Le test échoue par la suite. L'insertion de la ligne dans la base de données ne semble avoir aucun effet plus, donc les assertEquals ligne (1, result.size()) échoue:

java.lang.AssertionError: expected:<1> but was:<0> 
    at org.junit.Assert.fail(Assert.java:91) 
    at org.junit.Assert.failNotEquals(Assert.java:618) 
    at org.junit.Assert.assertEquals(Assert.java:126) 
    at org.junit.Assert.assertEquals(Assert.java:443) 
    at org.junit.Assert.assertEquals(Assert.java:427) 
    at test.package.CassandraAPITest.testCassandraAPI(CassandraAPITest.java:48) 

Je ne reçois aucun message d'erreur (ni le client ni sur le serveur) et je n'ai aucune idée de la cause du problème.

Répondre

2

Vous insérez avec une résolution d'une milliseconde mais l'interface CLI (et d'autres clients de haut niveau) utilise des microsecondes. Donc, votre deuxième insertion est dans le passé, par rapport à la suppression, donc Cassandra l'ignore correctement.

+0

Je ne vois pas comment les différentes résolutions pourraient faire la différence. Après avoir exécuté UnitTest (qui insère la ligne), je saisis manuellement les instructions de suppression dans la fenêtre du terminal. Par la suite, je passe à nouveau à Eclipse et relance mes tests. Ces tâches manuelles qui se produisent entre l'exécution des déclarations prennent sûrement plus d'une microseconde. Est-ce que je me trompe ici? – sme

+0

Par exemple, pour garder les chiffres simples, dites que vous faites votre insertion originale le 1er janvier 1970, 00:01, votre suppression à 00:02, et votre insertion suivante à 00:03. Ainsi, votre première insertion, System.currentTimeMillis() renvoie 1000. Pour la suppression, microsecondes renvoie 2000000. Pour l'insertion finale, currentTimeMillis renvoie 3000. 3000 <20000000 afin que Cassandra ignore cela comme un événement obsolète. – jbellis

+0

Aussi: vous devriez vraiment utiliser Hector de Java, au lieu d'écrire Thrift brut. http://github.com/rantav/hector – jbellis