public void testEventFilterAndConverter() {
    QueryFactory qf = Search.getQueryFactory(cache());

    Query query =
        qf.from(Person.class).having("age").lte(31).toBuilder().select("name", "age").build();

    EntryListener listener = new EntryListener();

    // we want our cluster listener to be notified only if the entity matches our query
    cache().addListener(listener, Search.makeFilter(query), null);

    for (int i = 0; i < 10; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 25);

      cache.put(i, value);
    }

    assertEquals(10, cache.size());
    assertEquals(7, listener.createEvents.size());
    assertTrue(listener.modifyEvents.isEmpty());

    for (ObjectFilter.FilterResult r : listener.createEvents) {
      assertNotNull(r.getProjection());
      assertEquals(2, r.getProjection().length);
      assertTrue((Integer) r.getProjection()[1] <= 31);
    }

    cache().removeListener(listener);
  }
  public void testEventFilter() {
    for (int i = 0; i < 10; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(99);

      cache().put(i, value);
    }
    assertEquals(10, cache.size());

    QueryFactory qf = Search.getQueryFactory(cache());

    Query query =
        qf.from(Person.class)
            .having("age")
            .lte(param("ageParam"))
            .toBuilder()
            .build()
            .setParameter("ageParam", 31);

    EntryListener listener = new EntryListener();

    // we want our cluster listener to be notified only if the entity matches our query
    cache().addListener(listener, Search.makeFilter(query), null);

    assertTrue(listener.createEvents.isEmpty());
    assertTrue(listener.modifyEvents.isEmpty());

    for (int i = 0; i < 10; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 25);

      cache().put(i, value);
    }

    assertEquals(10, cache.size());
    assertTrue(listener.createEvents.isEmpty());
    assertEquals(7, listener.modifyEvents.size());

    for (ObjectFilter.FilterResult r : listener.modifyEvents) {
      Person p = (Person) r.getInstance();
      assertTrue(p.getAge() <= 31);
    }

    cache().removeListener(listener);

    // ensure no more invocations after the listener was removed
    listener.createEvents.clear();
    listener.modifyEvents.clear();
    Person value = new Person();
    value.setName("George");
    value.setAge(30);

    cache().put(-1, value);
    assertTrue(listener.createEvents.isEmpty());
    assertTrue(listener.modifyEvents.isEmpty());
  }
  /** Using grouping and aggregation with event filters is not allowed. */
  @Test(
      expectedExceptions = ParsingException.class,
      expectedExceptionsMessageRegExp = ".*ISPN028509:.*")
  public void testDisallowGroupingAndAggregation() {
    Query query =
        Search.getQueryFactory(cache(0))
            .from(Person.class)
            .having("age")
            .gte(20)
            .select(max("age"))
            .build();

    cache(0).addListener(new EntryListener(), Search.makeFilter(query), null);
  }
  public void testEventFilter() {
    QueryFactory qf = Search.getQueryFactory(cache(0));

    Query query = qf.from(org.infinispan.query.test.Person.class).having("age").lte(31).build();

    EntryListener listener = new EntryListener();

    for (int i = 0; i < 5; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 30);

      Cache<Object, Person> cache = cache(i % NUM_NODES);
      Object key = new MagicKey(cache);
      cache.put(key, value);
    }

    // we want our cluster listener to be notified only if the entity matches our query
    cache(0).addListener(listener, Search.makeFilter(query), null);

    for (int i = 0; i < 10; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 25);

      Cache<Object, Person> cache = cache(i % NUM_NODES);
      Object key = new MagicKey(cache);
      cache.put(key, value);
    }

    assertEquals(9, listener.results.size());
    for (ObjectFilter.FilterResult r : listener.results) {
      Person p = (Person) r.getInstance();
      assertTrue(p.getAge() <= 31);
    }

    cache(0).removeListener(listener);

    // ensure no more invocations after the listener was removed
    listener.results.clear();
    Person value = new Person();
    value.setName("George");
    value.setAge(30);

    Object key = new MagicKey(cache(0));
    cache(0).put(key, value);
    assertEquals(0, listener.results.size());
  }
  public void testEventFilterAndConverter() {
    QueryFactory qf = Search.getQueryFactory(cache(0));

    Query query =
        qf.from(org.infinispan.query.test.Person.class)
            .having("age")
            .lte(31)
            .select("name", "age")
            .build();

    EntryListener listener = new EntryListener();

    for (int i = 0; i < 5; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 30);

      Cache<Object, Person> cache = cache(i % NUM_NODES);
      Object key = new MagicKey(cache);
      cache.put(key, value);
    }

    // we want our cluster listener to be notified only if the entity matches our query
    cache(0).addListener(listener, Search.makeFilter(query), null);

    for (int i = 0; i < 10; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 25);

      Cache<Object, Person> cache = cache(i % NUM_NODES);
      Object key = new MagicKey(cache);
      cache.put(key, value);
    }

    assertEquals(9, listener.results.size());
    for (ObjectFilter.FilterResult r : listener.results) {
      assertTrue((Integer) r.getProjection()[1] <= 31);
    }

    cache(0).removeListener(listener);
  }
  private long testEventFilterPerformance(boolean doRegisterListener) {
    final int numEntries = 100000;
    final int numListeners = 1000;
    List<NoOpEntryListener> listeners = new ArrayList<NoOpEntryListener>(numListeners);
    if (doRegisterListener) {
      Query query = makeQuery(cache(0));
      for (int i = 0; i < numListeners; i++) {
        NoOpEntryListener listener = new NoOpEntryListener();
        listeners.add(listener);
        cache(0).addListener(listener, Search.makeFilter(query), null);
      }
    }

    long startTs = System.nanoTime();
    // create entries
    for (int i = 0; i < numEntries; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 25);

      Cache<Object, Person> cache = cache(i % NUM_NODES);
      cache.put(value.getName(), value);
    }
    // update entries (with same value)
    for (int i = 0; i < numEntries; ++i) {
      Person value = new Person();
      value.setName("John");
      value.setAge(i + 25);

      Cache<Object, Person> cache = cache(i % NUM_NODES);
      cache.put(value.getName(), value);
    }
    long endTs = System.nanoTime();

    for (NoOpEntryListener listener : listeners) {
      cache(0).removeListener(listener);
    }

    return endTs - startTs;
  }