/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ignite.internal.processors.cache; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ThreadLocalRandom; import javax.cache.CacheException; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteClientDisconnectedException; import org.apache.ignite.cache.affinity.Affinity; import org.apache.ignite.cache.query.ScanQuery; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.cache.query.SqlQuery; import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteClientReconnectFailoverAbstractTest; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.lang.IgniteBiPredicate; import static org.apache.ignite.cache.CacheMode.PARTITIONED; /** * */ public class IgniteClientReconnectCacheQueriesFailoverTest extends IgniteClientReconnectFailoverAbstractTest { /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); CacheConfiguration<Object, Object> ccfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME); ccfg.setCacheMode(PARTITIONED); ccfg.setBackups(1); ccfg.setIndexedTypes(Integer.class, Person.class); cfg.setCacheConfiguration(ccfg); return cfg; } /** {@inheritDoc} */ @Override protected void beforeTestsStarted() throws Exception { super.beforeTestsStarted(); final IgniteCache<Integer, Person> cache = grid(serverCount()).cache(DEFAULT_CACHE_NAME); assertNotNull(cache); for (int i = 0; i <= 10_000; i++) cache.put(i, new Person(i, "name-" + i)); } /** * @throws Exception If failed. */ public void testReconnectCacheQueries() throws Exception { final Ignite client = grid(serverCount()); final IgniteCache<Integer, Person> cache = client.cache(DEFAULT_CACHE_NAME); assertNotNull(cache); reconnectFailover(new Callable<Void>() { @Override public Void call() throws Exception { SqlQuery<Integer, Person> sqlQry = new SqlQuery<>(Person.class, "where id > 1"); try { assertEquals(9999, cache.query(sqlQry).getAll().size()); } catch (CacheException e) { if (e.getCause() instanceof IgniteClientDisconnectedException) throw e; else log.info("Ignore error: " + e); } try { SqlFieldsQuery fieldsQry = new SqlFieldsQuery("select avg(p.id) from Person p"); List<List<?>> res = cache.query(fieldsQry).getAll(); assertEquals(1, res.size()); Double avg = (Double)res.get(0).get(0); assertEquals(5_000, avg.intValue()); } catch (CacheException e) { if (e.getCause() instanceof IgniteClientDisconnectedException) throw e; else log.info("Ignore error: " + e); } return null; } }); } /** * @throws Exception If failed. */ public void testReconnectScanQuery() throws Exception { final Ignite client = grid(serverCount()); final IgniteCache<Integer, Person> cache = client.cache(DEFAULT_CACHE_NAME); assertNotNull(cache); final Affinity<Integer> aff = client.affinity(DEFAULT_CACHE_NAME); final Map<Integer, Integer> partMap = new HashMap<>(); for (int i = 0; i < aff.partitions(); i++) partMap.put(i, 0); for (int i = 0; i <= 10_000; i++) { Integer part = aff.partition(i); Integer size = partMap.get(part); partMap.put(part, size + 1); } reconnectFailover(new Callable<Void>() { @Override public Void call() throws Exception { ScanQuery<Integer, Person> qry = new ScanQuery<>(new IgniteBiPredicate<Integer, Person>() { @Override public boolean apply(Integer key, Person val) { return val.getId() % 2 == 1; } }); assertEquals(5000, cache.query(qry).getAll().size()); ThreadLocalRandom rnd = ThreadLocalRandom.current(); Integer part = rnd.nextInt(0, aff.partitions()); qry = new ScanQuery<>(part); assertEquals((int)partMap.get(part), cache.query(qry).getAll().size()); return null; } }); } /** * */ public static class Person { /** */ @QuerySqlField public int id; /** */ @QuerySqlField public String name; /** * @param id Id. * @param name Name. */ public Person(int id, String name) { this.id = id; this.name = name; } /** * @return Id. */ public int getId() { return id; } /** * @param id Set id. */ public void setId(int id) { this.id = id; } /** * @return Name. */ public String getName() { return name; } /** * @param name Name. */ public void setName(String name) { this.name = name; } /** {@inheritDoc} */ @Override public boolean equals(Object o) { return this == o || !(o == null || getClass() != o.getClass()) && id == ((Person)o).id; } /** {@inheritDoc} */ @Override public int hashCode() { return id; } /** {@inheritDoc} */ @Override public String toString() { return S.toString(Person.class, this); } } }