Ok, this might be a little too late. But here is my take on the implementation
Yes you could make use of itemreader, itemprocessor and itemwriter to do it. It maybe a little overkill, but nevertheless it could be done
The main issue (since the job keeps coming back to the reader) I see is there should have been a way to tell spring that all items have been read from the Itemreader and there are no more objects to read. To do that you have explicitly return a null when spring tries to read more objects.
So this is an example returning List from ItemReader
Here the read() method should have a similar implementation
Leave out the Redis implementation , but here is the gist of it, I declare a variable called -
iterateindex
Have the iterateIndex created and initialzied at the start of the Item reader like this
I have also included the redisson cache to store the list. Again that can be negated
public class XXXConfigItemReader implements
ItemStreamReader<FeedbackConfigResponseModel> {
private int iterateIndex;
@Autowired
Environment env;
@Autowired
RestTemplateBuilder templateBuilder;
public DeferralConfigItemReader() {
this.iterateIndex = 0;
}
and make sure that the read() returns null when it reaches the list size
public List<FeedbackConfigResponseModel> read()
throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
// TODO Auto-generated method stub
// Get the config details from db
List<XXX> feedbackConfigModelList = new ArrayList<>;
// store all the values from the db or read from a file , read
//it line by line and marshall that to a list
// now on the first itemreader call, the iterateindex will not be
// equal to the list size and hence the entire list is returned
// in the first call
if (feedbackConfigModelList == null || this.iterateIndex == feedbackConfigModelList.size()) {
return null;
} else {
// and now we equate the list size and store it in iterateIndex
// the second call will return null.
this.iterateIndex = feedbackConfigModelList.size();
return feedbackConfigModelList;
}
}
Hope it helps people who are getting the same issue.
EDIT:
Showing how restTemplateBuilder is being used. note instead of RestTemplateBuilder you could jut autowire the RestTemplate. I made use of restTemplateBuilder to have some additionalConfig for my prj needs
Now this is the complete itemreader implemented using itemstreamreader interface
public class XXXX implements ItemStreamReader<FeedbackConfigResponseModel> {
private int iterateIndex;
@Autowired
Environment env;
@Autowired
RestTemplateBuilder templateBuilder;
@Autowired
RedissonClient redisClient;
public DeferralConfigItemReader() {
this.iterateIndex = -1;
this.feedbackConfigModelList = new ArrayList<>();
}
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
// TODO Auto-generated method stub
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
// TODO Auto-generated method stub
}
@Override
public void close() throws ItemStreamException {
// TODO Auto-generated method stub
}
@Override
public FeedbackConfigResponseModel read()
throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
// TODO Auto-generated method stub
String feedbackConfigFetchUrl = null;
ResponseEntity<FeedbackConfigResponseListModel> respModelEntity = null;
// if the cache is empty then fetch it from resttemplate
RList<FeedbackConfigResponseModel> rList = redisClient.getList(AppConstants.CACHE_DBCONFIG_LIST);
List<FeedbackConfigResponseModel> feedbackConfigModelList = new ArrayList<>();
FeedbackConfigResponseModel firstDbItem = rList.get(0);
if (firstDbItem == null) {
feedbackConfigFetchUrl = this.env.getProperty("restTemplate.default.url") + "/test";
respModelEntity = templateBuilder.build().getForEntity(feedbackConfigFetchUrl,
FeedbackConfigResponseListModel.class);
System.out.println("Response Model from template:" + respModelEntity.getBody());
feedbackConfigModelList = respModelEntity.getBody() == null ? null
: respModelEntity.getBody().getFeedbackResponseList();
rList.addAll(feedbackConfigModelList);
} else {
System.out.println("coming inside else");
feedbackConfigModelList = rList;
}
if (feedbackConfigModelList == null || this.iterateIndex == feedbackConfigModelList.size()) {
return null;
} else {
this.iterateIndex++;
System.out.println("itenrating index"+iterateIndex + feedbackConfigModelList.size());
return feedbackConfigModelList.get(iterateIndex);
}
}
}