Skip to content
Snippets Groups Projects

Matching system is ready for find new matches, but still need to handle the update and delete on offer and Wishlist records

Merged fz2907 requested to merge matching_service into sprint_2
7 files
+ 212
14
Compare changes
  • Side-by-side
  • Inline
Files
7
@@ -11,9 +11,9 @@ import vt.CS5934.SwitchRoom.models.*;
import vt.CS5934.SwitchRoom.repositories.*;
import vt.CS5934.SwitchRoom.utility.LookupTables;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import static vt.CS5934.SwitchRoom.utility.UsefulTools.DATE_FORMAT;
@@ -35,6 +35,9 @@ public class OfferWishlistMatchingJob {
@Autowired
WishlistWaitingMatchRepository wishlistWaitingMatchRepository;
@Autowired
MatchedWishlistRecordRepository matchedWishlistRecordRepository;
@Async
@Scheduled(fixedDelayString = "${offer.wishlist.job.gap.seconds:60}000",
@@ -60,20 +63,22 @@ public class OfferWishlistMatchingJob {
}catch (Exception e){
logger.error("Error occur when fetch the new records from Offer table / Wishlist table or" +
"push them into their waiting table.");
"push them into their waiting table: " +e.toString());
// may need to stop the task if needed.
}
try{
// TODO: find the match records and push to the matched table
//find the match records and push to the matched table
findMatchFromWaitingTable(lastPullTimeMap.get(LookupTables.MATCHING_JOB_DB_ID));
}catch (Exception e){
logger.error("Error occur when finding matches and push them to matched table.");
logger.error("Error occur when finding matches and push them to matched table: " +e.fillInStackTrace());
}
}
/**
* This function is to get the last pull time into a map, so the job knows the starting time range.
* If DB do not have the job record info, it will build a default with starting of time as last pull time
@@ -103,11 +108,12 @@ public class OfferWishlistMatchingJob {
private void pushNewOfferRecordsIntoWaitingTable(MatchingJobInfoModel offerJobRecord){
logger.info("Starting pushNewOfferRecordsIntoWaitingTable function with lastPullTime:{}"
,DATE_FORMAT.format(offerJobRecord.getLastPullTime()));
// update the job info record time
java.util.Date lastPullOfferTime = offerJobRecord.getLastPullTime();
Date lastPullOfferTime = offerJobRecord.getLastPullTime();
offerJobRecord.setJobStatus(LookupTables.JOB_STATUS.Done);
offerJobRecord.setLastPullTime(new Date(System.currentTimeMillis()));
matchingJobInfoRepository.save(offerJobRecord);
// fetch the Offer records and push them to waiting table
List<UserOfferModel> newOfferList = userOfferRepository
.findAllByOfferingAndModifyDateAfter(true, lastPullOfferTime);
@@ -118,6 +124,8 @@ public class OfferWishlistMatchingJob {
newOffer.getAvailableTimeStart(), newOffer.getAvailableTimeEnd(), newOffer.getStateCityCode());
offerWaitingMatchRepository.save(offerWaitingRecord);
}
matchingJobInfoRepository.save(offerJobRecord);
}
/**
@@ -127,11 +135,12 @@ public class OfferWishlistMatchingJob {
private void pushNewWishlistItemRecordsIntoWaitingTable(MatchingJobInfoModel wishlistJobInfo){
logger.info("Starting pushNewWishlistItemRecordsIntoWaitingTable function with lastPullTime:{}"
,DATE_FORMAT.format(wishlistJobInfo.getLastPullTime()));
// update the job info record time
Date lastPullOfferTime = wishlistJobInfo.getLastPullTime();
wishlistJobInfo.setJobStatus(LookupTables.JOB_STATUS.Done);
wishlistJobInfo.setLastPullTime(new Date(System.currentTimeMillis()));
matchingJobInfoRepository.save(wishlistJobInfo);
// fetch the Wishlist records and push them to waiting table
List<WishlistItemModel> newWishlistItemList = wishlistItemRepository
.findAllByModifyDateAfter(lastPullOfferTime);
@@ -143,6 +152,122 @@ public class OfferWishlistMatchingJob {
, newWishlistItem.getEndTime(), newWishlistItem.getStateCityCode());
wishlistWaitingMatchRepository.save(wishlistWaitingRecord);
}
matchingJobInfoRepository.save(wishlistJobInfo);
}
private void findMatchFromWaitingTable(MatchingJobInfoModel matchJobRecord){
logger.info("Starting findMatchFromWaitingTable function with lastPullTime:{}"
,DATE_FORMAT.format(matchJobRecord.getLastPullTime()));
// update the job info record time
Date lastPullOfferTime = matchJobRecord.getLastPullTime();
matchJobRecord.setJobStatus(LookupTables.JOB_STATUS.Done);
matchJobRecord.setLastPullTime(new Date(System.currentTimeMillis()));
// fetch both new records
List<OfferWaitingMatchModel> newOfferRecords =
offerWaitingMatchRepository.findAllByModifyDateAfter(lastPullOfferTime);
List<WishlistWaitingMatchModel> newWishlistRecords =
wishlistWaitingMatchRepository.findAllByModifyDateAfter(lastPullOfferTime);
// if one of them have new records
if(newOfferRecords.size() > 0 || newWishlistRecords.size() > 0){
// load new Offers into map
HashMap<Long, List<OfferWaitingMatchModel>> newStateCityCodeOfferMap = new HashMap<>();
HashMap<Long, List<WishlistWaitingMatchModel>> newStateCityCodeWishlistMap = new HashMap<>();
loadListIntoMap(newOfferRecords, newWishlistRecords,newStateCityCodeOfferMap, newStateCityCodeWishlistMap);
// fetch both old records
List<OfferWaitingMatchModel> oldOfferRecords =
offerWaitingMatchRepository.findAllByModifyDateLessThanEqualAndStateCityCodeIn(lastPullOfferTime,
newStateCityCodeWishlistMap.keySet());
List<WishlistWaitingMatchModel> oldWishlistRecords =
wishlistWaitingMatchRepository.findAllByModifyDateLessThanEqualAndStateCityCodeIn(lastPullOfferTime,
newStateCityCodeOfferMap.keySet());
// build maps by use the StateCityCode as the key so make the next pair step easier.
HashMap<Long, List<OfferWaitingMatchModel>> oldStateCityCodeOfferMap = new HashMap<>();
HashMap<Long, List<WishlistWaitingMatchModel>> oldStateCityCodeWishlistMap = new HashMap<>();
loadListIntoMap(oldOfferRecords, oldWishlistRecords,oldStateCityCodeOfferMap, oldStateCityCodeWishlistMap);
// after fetch all new Wishlist item records by unique stateCityCode
// match them with all Offer records
newStateCityCodeWishlistMap.entrySet()
.parallelStream()
.forEach(entry -> {
List<OfferWaitingMatchModel> newStateCityCodeOfferList =
!newStateCityCodeOfferMap.containsKey(entry.getKey())? new ArrayList<>()
: newStateCityCodeOfferMap.get(entry.getKey());
List<OfferWaitingMatchModel> oldStateCityCodeOfferList =
!oldStateCityCodeOfferMap.containsKey(entry.getKey())? new ArrayList<>()
:oldStateCityCodeOfferMap.get(entry.getKey());
List<OfferWaitingMatchModel> offerList =
Stream.concat(newStateCityCodeOfferList.stream(),
oldStateCityCodeOfferList.stream()).toList();
findMatchedOfferForNewWishlistItemToDB(offerList, entry.getValue());
});
// If new offers and old Wishlist item records' unique stateCityCode has intersection,
// fetch old Wishlist item by new Offer stateCityCode
if(newOfferRecords.size() > 0){
oldStateCityCodeWishlistMap.entrySet()
.parallelStream()
.forEach(entry ->{
List<OfferWaitingMatchModel> newStateCityCodeOfferList =
!newStateCityCodeOfferMap.containsKey(entry.getKey())? new ArrayList<>()
: newStateCityCodeOfferMap.get(entry.getKey());
findMatchedOfferForNewWishlistItemToDB(newStateCityCodeOfferList,
entry.getValue());
});
}
}
matchingJobInfoRepository.save(matchJobRecord);
}
private void findMatchedOfferForNewWishlistItemToDB(List<OfferWaitingMatchModel> offerList,
List<WishlistWaitingMatchModel> wishlistItemList) {
wishlistItemList.stream().forEach( wishlistItem ->{
useWishlistItemAndOfferListBuildMatchedRecordDB(wishlistItem, offerList);
});
}
private void useWishlistItemAndOfferListBuildMatchedRecordDB(WishlistWaitingMatchModel wishlistItem,
List<OfferWaitingMatchModel> offerList) {
List<MatchedWishlistRecordModel> matchedRecordList = new ArrayList<>();
offerList.stream().forEach( offer ->{
if(isOverlapping(wishlistItem.getStartTime(),wishlistItem.getEndTime(),
offer.getStartTime(),offer.getEndTime()))
matchedRecordList.add(new MatchedWishlistRecordModel(wishlistItem.getWishlistItemId(),
offer.getOfferId(), LookupTables.MATCHING_RECORD_USER_RESULT.Waiting));
});
matchedWishlistRecordRepository.saveAll(matchedRecordList);
}
private void loadListIntoMap(List<OfferWaitingMatchModel> offerRecords,
List<WishlistWaitingMatchModel> wishlistRecords,
HashMap<Long, List<OfferWaitingMatchModel>> stateCityCodeOfferMap,
HashMap<Long, List<WishlistWaitingMatchModel>> stateCityCodeWishlistMap){
offerRecords.stream().forEach(a -> {
if(!stateCityCodeOfferMap.containsKey(a.getStateCityCode()))
stateCityCodeOfferMap.put(a.getStateCityCode(), new ArrayList<>());
stateCityCodeOfferMap.get(a.getStateCityCode()).add(a);
});
wishlistRecords.stream().forEach(a->{
if(!stateCityCodeWishlistMap.containsKey(a.getStateCityCode()))
stateCityCodeWishlistMap.put(a.getStateCityCode(), new ArrayList<>());
stateCityCodeWishlistMap.get(a.getStateCityCode()).add(a);
});
}
private boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
return start1.before(end2) && start2.before(end1);
}
}
Loading