I have a several readers where I am reading continuously for rfid tags. I want to check these tags with what is in a database. I have a spring app that uses runnables to connect and get info from the readers. I'm adding the tags to a queue. I have a rest api that is running separately that will be used by this application. I want to use this api while the reader app is running to check the database multiple times as well as add info to the database. How do I do this?
I've tried multiple things such as using completablefuture, trying to use webflux, using resttemplate to make api calls, webclient to make api calls but nothing seems to work. I have an executor service that calls the readers from the main. Each reader is created with a runnable. The runnable creates the Reader and calls the function. In that function, 2 runnable tasks start. In one of these tasks I want to call the rest api. I will try and include all the code that is necessary.
This is the class that is called from main:
@Component
@Scope("prototype")
public class CSLReader{
public CSLReader(String ipAddress){
this.ipAddress=ipAddress;
}
public CSLReader(String ipAddress, String deviceName, int power, int
notifyPort, int dwellTime ) throws InterruptedException{
this.ipAddress=ipAddress;
this.deviceName=deviceName;
this.power=power;
this.notifyPort=notifyPort;
this.TagBuffer = new LinkedList<TagInfo>();
//this.taglist=new ArrayBlockingQueue<TagInfo>();
this.dwellTime=dwellTime;
//Start();
}
public void StartAsync() throws InterruptedException, IOException{
Runnable task = new Runnable() {
@Override
public void run() {
try {
StartInventory();
} catch (Exception ex) {
System.out.print("start
inventory thread could not start: "+ex.getLocalizedMessage());
ex.printStackTrace();
}
}
};
Runnable task2 = new Runnable() {
@Override
public void run() {
try {
StartTCPClient();
} catch (Exception ex) {
System.out.print("start
tcpclient thread could not start: "+ex.getMessage());
}
}
};
tcpClientThread = new Thread(task2, "TCPClientThread");
tcpClientThread.setDaemon(true);
tcpClientThread.start();
inventoryThread = new Thread(task, "InventoryThread");
inventoryThread.setDaemon(true);
inventoryThread.start();
}
I have this in the a service file:
@Async
public CompletableFuture<BmwvehicleTest> findVehicle(String rfidtag) throws InterruptedException{
log.info("trying to find a vehicle test by rfidtag");
String getUrl=String.format("http://localhost/api/tag/", rfidtag);
BmwvehicleTest results= restTemplate.getForObject(getUrl,BmwvehicleTest.class);
Thread.sleep(2000L);
return CompletableFuture.completedFuture(results);
}
Then I try and call it in my main prototype component:
public void StartInventory() throws InterruptedException,
ExecutionException{
ArrayBlockingQueue<TagInfo> taglist= new ArrayBlockingQueue<TagInfo>(10000);
synchronized (TagBuffer) {
if (TagBuffer.size() >= 10000){
TagBuffer.remove();
}
//test tag
TagInfo tag2= new TagInfo(51.2f, 2, "192.168.68.68", "Test Reader", new Date(), 0, "E200287878787878787", "3400");
if (tag2 != null){
TagBuffer.add(tag2);
System.out.println("tag added to tag buffer");
log.info("the tag is: "+tag2.epc);
CompletableFuture<BmwvehicleTest> num1=asyncServices.findVehicle(tag2.epc);
}
}
}
I would like the app to continue receiving info from the readers and when a tag is received to add the tag to the queue, then checked to see if in the database, if so I want the location added to the database. While this is happening, I still want the app to continue receiving info from the readers.