From 4fc2b14b63a42e1a04947f7e6d87211750c67928 Mon Sep 17 00:00:00 2001 From: Felipe Fernandez Date: Tue, 7 Jun 2016 14:54:52 +0100 Subject: [PATCH 1/5] Java client should be able to accept collections. --- .../http/client/PrimingClientTest.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/java-client/src/test/java/org/scassandra/http/client/PrimingClientTest.java b/java-client/src/test/java/org/scassandra/http/client/PrimingClientTest.java index 9aa51dbf..40df02a5 100644 --- a/java-client/src/test/java/org/scassandra/http/client/PrimingClientTest.java +++ b/java-client/src/test/java/org/scassandra/http/client/PrimingClientTest.java @@ -18,10 +18,13 @@ import com.github.tomakehurst.wiremock.http.Fault; import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import static org.scassandra.cql.ListType.*; + import java.util.*; import static com.github.tomakehurst.wiremock.client.WireMock.*; @@ -739,10 +742,13 @@ public void testMultiPrime() throws Exception { MultiPrimeRequest prime = MultiPrimeRequest.request() .withWhen(when() - .withQuery("select * from person where name = ?")) + .withQuery("select * from person where name = ? and nicknames = ?")) .withThen(then() - .withVariableTypes(TEXT) - .withOutcomes(outcome(match().withVariableMatchers(exactMatch().withMatcher("Chris").build()), action())) + .withVariableTypes(TEXT, list(TEXT)) + .withOutcomes( + outcome(match().withVariableMatchers(exactMatch().withMatcher("Chris").build()), action()), + outcome(match().withVariableMatchers(exactMatch().withMatcher(Lists.newArrayList("Zen", "Nez")).build()), action()) + ) ) .build(); @@ -750,11 +756,11 @@ public void testMultiPrime() throws Exception { verify(postRequestedFor(urlEqualTo(PRIME_PREPARED_MULTI_PATH)) .withHeader("Content-Type", equalTo("application/json; charset=UTF-8")) - .withRequestBody(equalToJson("{\"when\":{\"query\":\"select * from person where name \\u003d ?\"}," + - "\"then\":{\"variable_types\":[\"text\"],\"outcomes\":[{\"criteria\":" + - "{\"variable_matcher\":[{\"matcher\":\"Chris\",\"type\":\"exact\"}]},\"action\":{}}]}}")) - - ); + .withRequestBody(equalToJson("{\"when\":{\"query\":\"select * from person where name \\u003d ? and nicknames \\u003d ?\"}," + + "\"then\":{\"variable_types\":[\"text\",\"list\\u003ctext\\u003e\"],\"outcomes\":[" + + "{\"criteria\":{\"variable_matcher\":[{\"matcher\":\"Chris\",\"type\":\"exact\"}]},\"action\":{}}," + + "{\"criteria\":{\"variable_matcher\":[{\"matcher\":[\"Zen\",\"Nez\"],\"type\":\"exact\"}]},\"action\":{}}]}})") + )); } @Test From 4d760e58a6815d0f6e6c1403c141036f3479f6f0 Mon Sep 17 00:00:00 2001 From: Felipe Fernandez Date: Tue, 7 Jun 2016 15:36:36 +0100 Subject: [PATCH 2/5] SCassandra server should accept collections in multi primes. --- .../priming/routes/PrimingPreparedRouteTest.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server/src/test/scala/org/scassandra/server/priming/routes/PrimingPreparedRouteTest.scala b/server/src/test/scala/org/scassandra/server/priming/routes/PrimingPreparedRouteTest.scala index 3dd3b3bd..b48f99b0 100644 --- a/server/src/test/scala/org/scassandra/server/priming/routes/PrimingPreparedRouteTest.scala +++ b/server/src/test/scala/org/scassandra/server/priming/routes/PrimingPreparedRouteTest.scala @@ -36,7 +36,7 @@ import org.mockito.Matchers._ import org.mockito.Mockito._ import org.scalatest.mock.MockitoSugar import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} -import org.scassandra.server.cqlmessages.types.{CqlText, CqlInt, CqlVarchar} +import org.scassandra.server.cqlmessages.types.{CqlList, CqlText, CqlInt, CqlVarchar} import org.scassandra.server.cqlmessages.{ONE, TWO} import org.scassandra.server.priming._ import org.scassandra.server.priming.json._ @@ -67,8 +67,12 @@ class PrimingPreparedRouteTest extends FunSpec with Matchers with ScalatestRoute describe("Priming multiple responses") { it("Should record it with the multi prime store") { - val when: WhenPrepared = WhenPrepared(Some("select * from people where name = ?")) - val thenDo = ThenPreparedMulti(Some(List(CqlText)), List(Outcome(Criteria(List(ExactMatch(Some("Chris")))), Action(None)))) + val when: WhenPrepared = WhenPrepared(Some("select * from people where name = ? and nicknames = ?")) + val outcomes = List( + Outcome(Criteria(List(ExactMatch(Some("Chris")))), Action(None)), + Outcome(Criteria(List(ExactMatch(Some(List("Zen","Nez"))))), Action(None)) + ) + val thenDo = ThenPreparedMulti(Some(List(CqlText, CqlList(CqlText))), outcomes) val prime = PrimePreparedMulti(when, thenDo) Post(primePreparedMultiPath, prime) ~> routeForPreparedPriming ~> check { status should equal(StatusCodes.OK) From 1b777800e525663834a6321868bddbcb2ec23dc2 Mon Sep 17 00:00:00 2001 From: Felipe Fernandez Date: Tue, 7 Jun 2016 16:41:38 +0100 Subject: [PATCH 3/5] Multi Prepared Prime should match on collections. --- .../PrimePreparedMultiStoreTest.scala | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/server/src/test/scala/org/scassandra/server/priming/prepared/PrimePreparedMultiStoreTest.scala b/server/src/test/scala/org/scassandra/server/priming/prepared/PrimePreparedMultiStoreTest.scala index 81a7baca..306726e1 100644 --- a/server/src/test/scala/org/scassandra/server/priming/prepared/PrimePreparedMultiStoreTest.scala +++ b/server/src/test/scala/org/scassandra/server/priming/prepared/PrimePreparedMultiStoreTest.scala @@ -4,7 +4,7 @@ import java.util.concurrent.TimeUnit import org.scalatest.{BeforeAndAfter, Matchers, FunSuite} import org.scassandra.server.cqlmessages.{Consistency, TWO, ONE} -import org.scassandra.server.cqlmessages.types.CqlText +import org.scassandra.server.cqlmessages.types._ import org.scassandra.server.priming.{WriteRequestTimeoutResult, ReadRequestTimeoutResult, SuccessResult} import org.scassandra.server.priming.json.{WriteTimeout, ReadTimeout, Success} import org.scassandra.server.priming.query.{PrimeCriteria, Prime, PrimeMatch} @@ -35,6 +35,23 @@ class PrimePreparedMultiStoreTest extends FunSuite with Matchers with BeforeAndA preparedPrime.value.getPrime(List(Some("Chris"))) should equal(Prime(rows = List(), result = SuccessResult)) } + test("Match on collection variable type - success") { + val variableTypes = List(CqlList(CqlText), CqlMap(CqlText, CqlInt), CqlSet(CqlText)) + val outcomeWithListMatch = Outcome(Criteria(List(ExactMatch(Some(List("Zen", "Nez"))))), Action(Some(List()), result = Some(Success))) + val outcomeWithMapMatch = Outcome(Criteria(List(ExactMatch(Some(Map("key" -> 1))))), Action(Some(List()), result = Some(Success))) + val outcomeWithSetMatch = Outcome(Criteria(List(ExactMatch(Some(Set("Zen", "Nez"))))), Action(Some(List()), result = Some(Success))) + val thenDo: ThenPreparedMulti = ThenPreparedMulti(Some(variableTypes), List(outcomeWithListMatch, outcomeWithMapMatch, outcomeWithSetMatch)) + val queryText = "Some query" + underTest.record(PrimePreparedMulti(WhenPrepared(Some(queryText)), thenDo)) + + val preparedPrime = underTest.findPrime(PrimeMatch(queryText, ONE)) + + preparedPrime.value.variableTypes should equal(variableTypes) + preparedPrime.value.getPrime(List(Some(List("Zen", "Nez")))) should equal(Prime(rows = List(), result = SuccessResult)) + preparedPrime.value.getPrime(List(Some(Map("key" -> 1)))) should equal(Prime(rows = List(), result = SuccessResult)) + preparedPrime.value.getPrime(List(Some(Set("Zen", "Nez")))) should equal(Prime(rows = List(), result = SuccessResult)) + } + test("Match on variable type - failure") { val variableTypes = List(CqlText) val thenDo: ThenPreparedMulti = ThenPreparedMulti(Some(variableTypes), List( From 7de1563a029b7f1364b226ce9dc5cd6ba21a1743 Mon Sep 17 00:00:00 2001 From: Felipe Fernandez Date: Wed, 8 Jun 2016 11:28:58 +0100 Subject: [PATCH 4/5] Provide integration tests for multi prime matching over collections. --- .../PreparedStatementPrimeOnVariables.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/java-it-tests/common/src/main/java/preparedstatements/PreparedStatementPrimeOnVariables.java b/java-it-tests/common/src/main/java/preparedstatements/PreparedStatementPrimeOnVariables.java index e093209c..410048d0 100644 --- a/java-it-tests/common/src/main/java/preparedstatements/PreparedStatementPrimeOnVariables.java +++ b/java-it-tests/common/src/main/java/preparedstatements/PreparedStatementPrimeOnVariables.java @@ -2,12 +2,15 @@ import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import common.AbstractScassandraTest; import common.CassandraExecutor; import common.CassandraResult; import common.CassandraRow; import org.junit.Test; +import org.scassandra.cql.CqlText; import org.scassandra.cql.CqlType; +import org.scassandra.cql.ListType; import org.scassandra.cql.PrimitiveType; import org.scassandra.http.client.Consistency; import org.scassandra.http.client.MultiPrimeRequest; @@ -23,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.scassandra.cql.ListType.*; import static org.scassandra.cql.PrimitiveType.*; import static org.scassandra.http.client.MultiPrimeRequest.*; @@ -312,5 +316,29 @@ public void testPrimeBasedOnMatchTimestamps() throws Exception { assertEquals(Result.read_request_timeout, result.status().getResult()); } + @Test + public void testPrimeBasedOnMatchCollection() { + String query = "select * from person where nicknames = ?"; + MultiPrimeRequest prime = MultiPrimeRequest.request() + .withWhen(when() + .withQuery(query)) + .withThen(then() + .withVariableTypes(list(TEXT)) + .withOutcomes( + outcome(match().withVariableMatchers(exactMatch().withMatcher(Lists.newArrayList("Zen", "Nez")).build()), action().withResult(Result.success)), + outcome(match().withVariableMatchers(exactMatch().withMatcher(Lists.newArrayList("timeout")).build()), action().withResult(Result.read_request_timeout)) + ) + ) + .build(); + + primingClient.multiPrime(prime); + + CassandraResult successResult = cassandra().prepareAndExecute(query, Lists.newArrayList("Zen", "Nez")); + CassandraResult timeoutResult = cassandra().prepareAndExecute(query, Lists.newArrayList("timeout")); + + assertEquals(Result.success, successResult.status().getResult()); + assertEquals(Result.read_request_timeout, timeoutResult.status().getResult()); + } + //todo blobs } From 057b7daad8c6b9a830c9022cb7834819c05d2c6a Mon Sep 17 00:00:00 2001 From: Felipe Fernandez Date: Wed, 8 Jun 2016 11:39:30 +0100 Subject: [PATCH 5/5] Update documentation to reflect collection variable matching. --- docs/java/priming-prepared-statements.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/java/priming-prepared-statements.md b/docs/java/priming-prepared-statements.md index 5cc82686..10f04855 100644 --- a/docs/java/priming-prepared-statements.md +++ b/docs/java/priming-prepared-statements.md @@ -101,7 +101,22 @@ outcomes as they will overwrite each other. If none of the outcomes match then a RuntimeException will currently be thrown. This will be replaced with default behaviour of returning an empty successful result. -Collections are not currently supported for variable matching. +Collections can also be used for variable matching: + +``` +MultiPrimeRequest prime = MultiPrimeRequest.request() + .withWhen(when() + .withQuery("select * from person where nicknames = ?")) + .withThen(then() + .withVariableTypes(list(TEXT)) + .withOutcomes( + outcome(match().withVariableMatchers(exactMatch().withMatcher(Lists.newArrayList("Zen", "Nez")).build()), action().withResult(Result.success)) + ) + ) + .build(); + +primingClient.multiPrime(prime); +``` #### Priming errors