TEXT Query in Apache Ignite not giving any result - lucene

Following are the items that I did
I started the ignite in remote mode.
I created a cache and added some data. (Also created the cache configuration)
I am doing the text query.
My code looks like this
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
String hosts[] = new String[]{"ip:48500"} ;
ipFinder.setAddresses(Arrays.asList(hosts));
/**
* create a new instance of tcp discovery multicast ip finder TcpDiscoveryMulticastIpFinder tcMp = new TcpDiscoveryMulticastIpFinder();
*
**tcMp.setAddresses(Arrays.asList("localhost")); // change your IP address here // set the multi cast ip finder for spi
*/
spi.setIpFinder(ipFinder);
/**
* create new ignite configuration
*/
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setClientMode(true);
cfg.setPeerClassLoadingEnabled(true);
/**
* CacheConfiguration cacheConfig = cacheConfigure();
* cfg.setCacheConfiguration(cacheConfig);
*/
#SuppressWarnings("rawtypes")
CacheConfiguration cacheConfig = cacheConfigure();
cfg.setCacheConfiguration(cacheConfig);
/**
* set the discovery spi to ignite configuration
*/
cfg.setDiscoverySpi(spi);
/**
* Start ignite
*/
Ignite ignite = Ignition.getOrStart(cfg);
and my cache configuration is
CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME);
QueryEntity queryEntity = new QueryEntity();
queryEntity.setKeyType(Integer.class.getName());
queryEntity.setValueType(Account.class.getName());
LinkedHashMap<String, String> fields = new LinkedHashMap();
fields.put("accid", Integer.class.getName());
fields.put("attrbool", Boolean.class.getName());
fields.put("accbalance", BigDecimal.class.getName());
fields.put("acctype", String.class.getName());
fields.put("attrbyte", Byte.class.getName());
fields.put("accifsc", String.class.getName());
queryEntity.setFields(fields);
// Listing indexes.
Collection<QueryIndex> indexes = new ArrayList<>(3);
indexes.add(new QueryIndex("accid"));
indexes.add(new QueryIndex("accifsc"));
indexes.add(new QueryIndex("acctype"));
queryEntity.setIndexes(indexes);
ccfg.setQueryEntities(Arrays.asList(queryEntity));
and I am putting data to cache
for(int i=0;i<5;i++) {
Account account=new Account();
account.setAccid(1234+i);
account.setAttrbool(true);
account.setAccbalance(new BigDecimal(100000+i));
account.setAcctype("Demat");
account.setAttrbyte(new Byte("1"));
account.setAccifsc("Master Degree Pstgraduate");
cache.put(new Integer(i), account);
}
and now doing the text query
TextQuery txt = new TextQuery(Account.class,"IFC" );
try (#SuppressWarnings("unchecked")
QueryCursor<Entry<Integer, Account>> masters = cache.query(txt)) {
for (Entry<Integer, Account> e : masters)
System.out.println("results "+e.getValue().toString());
}
My Data Class is
public class Account {
//primary key
#QueryTextField
private Integer accid ;
#QueryTextField
private BigDecimal accbalance ;
#QueryTextField#QuerySqlField
private String accifsc ;
private BigInteger accnum ;
private String accstr ;
#QueryTextField
private String acctype ;
#QueryTextField
private Boolean attrbool ;
#QueryTextField
private Byte attrbyte ;
// getter and setter
}
What am I doing wrong? There is no error in the log.

I changed the Text query code part a bit and it worked for me
TextQuery txt = new TextQuery(Account.class,"IFC" );
try (#SuppressWarnings({ "unchecked", "rawtypes" })
QueryCursor masters = cache.query(txt)) {
#SuppressWarnings("unchecked")
List<CacheEntryImpl<Integer,Account>> accounts = masters.getAll();
Iterator<CacheEntryImpl<Integer, Account>> iterator = accounts.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next().getValue().getAccifsc());
}
}

Related

Apache-ignite Pojo for key

I have apache-ignite running in a cluster with 3 nodes and populated it with some random data using a Long as the key.
IgniteCache<Long, String> cache = ignite.getOrCreateCache("myCache");
Map<Long, String> data = new HashMap<>();
data.put(1L,"Data for 1");
data.put(2L,"Data for 2");
cache.putAll(data);
for retrieval
Set<Long> keys = new HashSet<Long>(Arrays.asList(new Long[]{1L,2L}));
Map<Long,String> data = cache.getAll(keys);
data.forEach( (k,v) -> {
System.out.println(k+" "+v);
});
This all works great but when changing the key of the map to a POJO I am unable to retrieve the data...
IgniteCache<IdTimeStamp, String> cache = ignite.getOrCreateCache("myCache");
Map<IdTimeStamp, String> data = new HashMap<>();
data.put(new IdTimeStamp(1L, 1514759400000L),"Data for 1514759400000");
data.put(new IdTimeStamp(1L, 1514757600000L),"Data for 1514757600000L");
cache.putAll(data);
for retrieval
Set<IdTimeStamp> keys = new HashSet<IdTimeStamp>();
keys.add(new IdTimeStamp(1L, 1514757600000L));
keys.add(new IdTimeStamp(1L, 1514759400000L));
Map<IdTimeStamp,String> data = cache.getAll(keys);
System.out.println(data.size());
data.forEach( (k,v) -> {
System.out.println(k+" "+v);
});
and the IdTimeStamp class:
public class IdTimeStamp {
private Long id;
private Long timestamp;
public IdTimeStamp(Long id, Long timestamp) {
this.id = id;
this.timestamp = timestamp;
}
}
Not working:
ClientConfiguration cfg = new ClientConfiguration().setAddresses("127.0.0.1:10800");
IgniteClient client = Ignition.startClient(cfg);
ClientCache<IdTimeStamp, String> cache = client.cache("myCache");
Working:
public static IgniteCache<IdTimeStamp, String> getIgnite() {
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setClientMode(true);
cfg.setPeerClassLoadingEnabled(false); //true ??
// Setting up an IP Finder to ensure the client can locate the servers.
TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
ipFinder.setAddresses(Collections.singletonList("127.0.0.1:47500..47509"));
TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
discoverySpi.setClientReconnectDisabled(true);
discoverySpi.setIpFinder(ipFinder);
cfg.setDiscoverySpi(discoverySpi);
// Starting the node
Ignite ignite = Ignition.start(cfg);
// Create an IgniteCache and put some values in it.
IgniteCache<IdTimeStamp, String> cache = ignite.getOrCreateCache("myCache");
return cache;
}
Looks like a known limitation when you are using different clients for data population and retrieving the records. Take a look at this question if configuring compactFooter=true solves that problem.
clientConfig.setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(true)
Otherwise, your code looks fine and should work as expected.

can Ignite Streamer.addData be executed on separate node from the StreamReceiver/Visitor?

Is it possible to do Stream injection from a Client Node and intercept the same stream in the Server Node to process the stream before inserting in the cache ?
The reason for doing this is that the Client Node receives the stream from an external source and the same needs to be injected into a partitioned cache based on AffinityKey across multiple server nodes. The stream needs to be intercepted on each node and processed with the lowest latency.
I could've used cache events to do this but StreamVisitor is supposed to be faster.
following is the sample that i am trying to execute. Start 2 nodes : one containing the streamer, other containing the streamReciever :
public class StreamerNode {
public static void main(String[] args) {
......
Ignition.setClientMode(false);
Ignite ignite = Ignition.start(igniteConfiguration);
CacheConfiguration<SeqKey, String> myCfg = new CacheConfiguration<SeqKey, String>("myCache");
......
IgniteCache<SeqKey, String> myCache = ignite.getOrCreateCache(myCfg);
IgniteDataStreamer<SeqKey, String> myStreamer = ignite.dataStreamer(myCache.getName()); // Create Ignite Streamer for windowing data
for (int i = 51; i <= 100; i++) {
String paddedString = org.apache.commons.lang.StringUtils.leftPad(i+"", 7, "0") ;
String word = "TEST_" + paddedString;
SeqKey seqKey = new SeqKey("TEST", counter++ );
myStreamer.addData(seqKey, word) ;
}
}
}
public class VisitorNode {
public static void main(String[] args) {
......
Ignition.setClientMode(false);
Ignite ignite = Ignition.start(igniteConfiguration);
CacheConfiguration<SeqKey, String> myCfg = new CacheConfiguration<SeqKey, String>("myCache");
......
IgniteCache<SeqKey, String> myCache = ignite.getOrCreateCache(myCfg);
IgniteDataStreamer<SeqKey, String> myStreamer = ignite.dataStreamer(myCache.getName()); // Create Ignite Streamer for windowing data
myStreamer.receiver(new StreamVisitor<SeqKey, String>() {
int i=1 ;
#Override
public void apply(IgniteCache<SeqKey, String> cache, Map.Entry<SeqKey, String> e) {
String tradeGetData = e.getValue();
System.out.println(nodeID+" : visitorNode ..count="+ i++ + " received key="+e.getKey() + " : val="+ e.getValue());
//do some processing here before inserting in the cache ..
cache.put(e.getKey(), tradeGetData);
}
});
}
}
Of course it can be executed on a different node. Usually, addData() is executed on client node, and StreamReceiver works on server node. You don't have to do anything special to make it happen.
As for the rest of your post, can you elaborate it with more details and samples perhaps? I could not understand the setup that is desired.
You can use continuous queries if you don't need to modify data, only act on it.

apache ignite service deploy cluster singleton

I try create spring java application with apache ignite inside.
When application startup it deploy service(cluster singleton) to cluster. (it`s ok)
But when i start second node which deploy this service too it is locked.
why this hapends ?
Apache Ignite 2.5.0
code of service class:
public class TaskLockWatcher implements Service {
#IgniteInstanceResource
private Ignite ignite;
private SchedulerFuture scheduler;
#Override
public void cancel(ServiceContext ctx) {
LOGGER.info("schedule service cancel");
if (scheduler != null){
scheduler.cancel();
}
}
#Override
public void init(ServiceContext ctx) throws Exception {
LOGGER.info("schedule service init");
}
#Override
public void execute(ServiceContext ctx) throws Exception {
LOGGER.info("schedule service execute");
scheduler = ignite.scheduler().scheduleLocal(() -> {
LOGGER.info("schedule service call");
List<Ticket> tickets = getTicketForUnlock();
if (!tickets.isEmpty()){
changeTicketStatus(tickets, TicketStatus.CREATED);
}
}, "* * * * *");
}
}
But the locking occurs even if I leave only the output of messages in all TaskLockWatcher methods.
publishing code:
Ignite ignite = connector.getClient();
IgniteServices svcs = ignite.services();
svcs.deployClusterSingleton("taskLockWatcher", new TaskLockWatcher());
ignite configuration code:
IgniteConfiguration igniteConfiguration = new IgniteConfiguration();
DataStorageConfiguration dataStorageConfiguration = new DataStorageConfiguration();
dataStorageConfiguration.setWalMode(WALMode.LOG_ONLY);
dataStorageConfiguration.getDefaultDataRegionConfiguration().setPersistenceEnabled(false);
dataStorageConfiguration.getDefaultDataRegionConfiguration().setMaxSize(128); // MB
List<DataRegionConfiguration> list = new ArrayList<>();
DataRegionConfiguration configuration = new DataRegionConfiguration();
configuration.setName("TASK_REGION");
configuration.setMaxSize(1024);
configuration.setPersistenceEnabled(true);
list.add(conf);
dataStorageConfiguration.setDataRegionConfigurations(list.toArray(new DataRegionConfiguration[0]));
igniteConfiguration.setDataStorageConfiguration(dataStorageConfiguration);
TcpCommunicationSpi tcpCommunicationSpi = new TcpCommunicationSpi();
tcpCommunicationSpi.setSlowClientQueueLimit(1000);
igniteConfiguration.setCommunicationSpi(tcpCommunicationSpi);
Map<String, String> attrs = Collections.singletonMap("group.node.filter", "CLUSTER_TASKS,CLUSTER_TICKETS");
igniteConfiguration.setUserAttributes(attrs);
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryZookeeperIpFinder ipFinder = new TcpDiscoveryZookeeperIpFinder();
ipFinder.setBasePath("/datagrid");
ipFinder.setCurator(getCuratorFramework());
spi.setIpFinder(ipFinder);
igniteConfiguration.setDiscoverySpi(spi);
AtomicConfiguration atomicConfiguration = new AtomicConfiguration();
atomicConfiguration.setBackups(1);
atomicConfiguration.setCacheMode(CacheMode.REPLICATED);
igniteConfiguration.setAtomicConfiguration(atomicConfiguration);
igniteConfiguration.setIncludeEventTypes(EventType.EVTS_CACHE);
CacheConfiguration<UUID, Ticket> cacheConfiguration = new CacheConfiguration<>("TICKETS");
cacheConfiguration.setIndexedTypes(keyClass, UUID.class);
cacheConfiguration.setNodeFilter((ClusterNode clusterNode) -> {
String dataNode = clusterNode.attribute("group.node.filter");
return dataNode != null && dataNode.contains("CLUSTER_TICKETS");
});
cacheConfiguration.setStatisticsEnabled(true);
cacheConfiguration.setDataRegionName("TASK_REGION");
cacheConfiguration.setBackups(1);
cacheConfiguration.setCacheMode(CacheMode.PARTITIONED);
cacheConfiguration.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
IgniteCache<UUID, Ticket> ticketCache = ignite.getOrCreateCache(cacheConfiguration);

Create and query a binary cache in ignite

I am trying to use BinaryObjects to create the cache at runtime. For example, instead of writing a pojo class such as Employee and configuring it as a cache value type, I need to be able to dynamically configure the cache with the field names and field types for the particular cache.
Here is some sample code:
public class EmployeeQuery {
public static void main(String[] args) throws Exception {
Ignition.setClientMode(true);
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
if (!ExamplesUtils.hasServerNodes(ignite))
return;
CacheConfiguration<Integer, BinaryObject> cfg = getbinaryCache("emplCache", 1);
ignite.destroyCache(cfg.getName());
try (IgniteCache<Integer, BinaryObject> emplCache = ignite.getOrCreateCache(cfg)) {
SqlFieldsQuery top5Qry = new SqlFieldsQuery("select * from Employee where salary > 500 limit 5", true);
while (true) {
QueryCursor<List<?>> top5qryResult = emplCache.query(top5Qry);
System.out.println(">>> Employees ");
List<List<?>> all = top5qryResult.getAll();
for (List<?> list : all) {
System.out.println("Top 5 query result : "+list.get(0) + " , "+ list.get(1) + " , " + list.get(2));
}
System.out.println("..... ");
Thread.sleep(5000);
}
}
finally {
ignite.destroyCache(cfg.getName());
}
}
}
private static QueryEntity createEmployeeQueryEntity() {
QueryEntity employeeEntity = new QueryEntity();
employeeEntity.setTableName("Employee");
employeeEntity.setValueType(BinaryObject.class.getName());
employeeEntity.setKeyType(Integer.class.getName());
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("id", Integer.class.getName());
fields.put("firstName", String.class.getName());
fields.put("lastName", String.class.getName());
fields.put("salary", Float.class.getName());
fields.put("gender", String.class.getName());
employeeEntity.setFields(fields);
employeeEntity.setIndexes(Arrays.asList(
new QueryIndex("id"),
new QueryIndex("firstName"),
new QueryIndex("lastName"),
new QueryIndex("salary"),
new QueryIndex("gender")
));
return employeeEntity;
}
public static CacheConfiguration<Integer, BinaryObject> getbinaryCache(String cacheName, int duration) {
CacheConfiguration<Integer, BinaryObject> cfg = new CacheConfiguration<>(cacheName);
cfg.setCacheMode(CacheMode.PARTITIONED);
cfg.setName(cacheName);
cfg.setStoreKeepBinary(true);
cfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
cfg.setIndexedTypes(Integer.class, BinaryObject.class);
cfg.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new CreatedExpiryPolicy(new Duration(SECONDS, duration))));
cfg.setQueryEntities(Arrays.asList(createEmployeeQueryEntity()));
return cfg;
}
}
I am trying to configure the cache with the employeeId (Integer) as key and the whole employee record (BinaryObject) as value. When I run the above class, I get the following exception :
Caused by: org.h2.jdbc.JdbcSQLException: Table "EMPLOYEE" not found; SQL statement:
select * from "emplCache".Employee where salary > 500 limit 5
What am I doing wrong here? Is there anything more other than this line:
employeeEntity.setTableName("Employee");
Next, I am trying to stream data into the cache. Is this the right way to do it?
public class CsvStreamer {
public static void main(String[] args) throws IOException {
Ignition.setClientMode(true);
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
if (!ExamplesUtils.hasServerNodes(ignite))
return;
CacheConfiguration<Integer, BinaryObject> cfg = EmployeeQuery.getbinaryCache("emplCache", 1);
try (IgniteDataStreamer<Integer, BinaryObject> stmr = ignite.dataStreamer(cfg.getName())) {
while (true) {
InputStream in = new FileInputStream(new File(args[0]));
try (LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in))) {
int count =0;
for (String line = rdr.readLine(); line != null; line = rdr.readLine()) {
String[] words = line.split(",");
BinaryObject emp = getBinaryObject(words);
stmr.addData(new Integer(words[0]), emp);
System.out.println("Sent data "+count++ +" , sal : "+words[6]);
}
}
}
}
}
}
private static BinaryObject getBinaryObject(String[] rawData) {
BinaryObjectBuilder builder = Ignition.ignite().binary().builder("Employee");
builder.setField("id", new Integer(rawData[0]));
builder.setField("firstName", rawData[1]);
builder.setField("lastName", rawData[2]);
builder.setField("salary", new Float(rawData[6]));
builder.setField("gender", rawData[4]);
BinaryObject binaryObj = builder.build();
return binaryObj;
}
}
Note: I am running this in cluster mode. Both EmployeeQuery and CsvStreamer I run from one machine, and I have ignite running in server mode in two other machines. Ideally I want to avoid the use of a pojo class in my application and make things as dynamic and generic as possible.
You are getting this exception because you didn't configure SQL scheme. In your case (you don't want to create pojo object and etc) I recommend to use SQL like syntacsis which was added to Apache Ignite since 2.0 version. I sure that the following example helps you with configuration: https://github.com/apache/ignite/blob/master/examples/src/main/java/org/apache/ignite/examples/datagrid/CacheQueryDdlExample.java

akka fails silently while serializing TypedActor proxies and ActorRef across 32 bit and 64 bit JVMs

What configuration is required to fix the following problem?
Akka Actor on 64 bit jvm(machine1) CANNOT use TypedActor proxies on the 32 bit jvm(machine2) (CASE1)
but WORKS vice versa (CASE2).
Is there some configuration setting for serialization I'm missing out?
I'm using akka-2.2.1 from java.
I've a small test code which replicates this problem always.
There are no logs which report "ERRORS", despite enabling even remote-lifecycle events.
It just times out when calling registerListener() on CASE1.
I'm clueless, any help/clue is greatly appreciated.
server.java
public class Server implements ServerActor {
public static final String serverActorName = "server";
public static final String serverIP = "192.168.11.112";
public static final int serverPort = 9999;
public static void main(String[] args) {
new Server();
}
ActorSystem serverSystem;
public Server() {
String network = String
.format("akka.actor.provider = \"akka.remote.RemoteActorRefProvider\" \n"
+ "akka.remote.enabled-transports = [\"akka.remote.netty.tcp\"] \n"
+ "akka.remote.netty.tcp.hostname = \"%s\" \n"
+ "akka.remote.netty.tcp.port = %d", Server.serverIP,
Server.serverPort);
Config config = ConfigFactory.parseString("akka.loglevel = DEBUG \n"
+ "akka.actor.debug.lifecycle = on \n" + network);
serverSystem = ActorSystem.create("sys", config);
RemoteActorRefProvider ref = (RemoteActorRefProvider) serverSystem
.provider();
Address addr = ref.transport().defaultAddress();
String port = addr.port().get().toString();
System.out.printf("Server Akka IP=%s PORT=%s\n", addr, port);
final Server server = this;
// start server service
#SuppressWarnings("unused")
ServerActor proxy = TypedActor.get(serverSystem).typedActorOf(
new TypedProps<Server>(ServerActor.class,
new Creator<Server>() {
private static final long serialVersionUID = 6301999771454618282L;
#Override
public Server create() {
return server;
}
}), Server.serverActorName);
}
#Override
public boolean registerListener(ITestListener listener) {
listener.update(10);
return true;
}
}
And client.java
public class Client implements ITestListener {
public static final String clientActorName = "client";
public static final String clientIP = "192.168.11.111";
public static void main(String[] args) {
new Client();
}
ActorSystem clientSystem;
private ITestListener clientListener = null;
public Client() {
String network = String
.format("akka.actor.provider = \"akka.remote.RemoteActorRefProvider\" \n"
+ "akka.remote.enabled-transports = [\"akka.remote.netty.tcp\"] \n"
+ "akka.remote.netty.tcp.hostname = \"%s\" \n"
+ "akka.remote.netty.tcp.port = 0", Client.clientIP);
Config config = ConfigFactory.parseString("akka.loglevel = DEBUG \n"
+ "akka.actor.debug.lifecycle = on \n" + network);
clientSystem = ActorSystem.create("sys", config);
RemoteActorRefProvider ref = (RemoteActorRefProvider) clientSystem
.provider();
Address addr = ref.transport().defaultAddress();
String port = addr.port().get().toString();
System.out.printf("Client Akka IP=%s PORT=%s\n", addr, port);
final Client client = this;
// start server service
clientListener = TypedActor.get(clientSystem).typedActorOf(
new TypedProps<Client>(ITestListener.class,
new Creator<Client>() {
private static final long serialVersionUID = 2034444366744329184L;
#Override
public Client create() {
return client;
}
}), Client.clientActorName);
connect();
}
private void connect() {
// Connect to remote actor system
String remotePath = String.format("akka.tcp://sys#%s:%d/user/%s",
Server.serverIP, Server.serverPort, Server.serverActorName);
// get remote server proxy object
// TypedActor.context().setReceiveTimeout(Duration.create("3 second"));
ActorRef remoteRef = clientSystem.actorFor(remotePath);
if (remoteRef == null)
throw new RuntimeException("Cannot get remote akka actor");
final ServerActor server = TypedActor.get(clientSystem).typedActorOf(
new TypedProps<ServerActor>(ServerActor.class), remoteRef);
server.registerListener(clientListener);
}
#Override
public void update(int a) {
System.out.printf("*********** Server Sent %d ************\n", a);
}
}