Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions TourGuide/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,18 @@

<dependency>
<groupId>com.local</groupId>
<artifactId>rewardCentral</artifactId>
<artifactId>RewardCentral</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/rewardCentral.jar</systemPath>
<systemPath>${project.basedir}/libs/RewardCentral.jar</systemPath>
</dependency>

<dependency>
<groupId>com.local</groupId>
<artifactId>tripPricer</artifactId>
<artifactId>TripPricer</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/tripPricer.jar</systemPath>
<systemPath>${project.basedir}/libs/TripPricer.jar</systemPath>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TourguideApplication {
public class TourGuideApplication {

public static void main(String[] args) {
SpringApplication.run(TourguideApplication.class, args);
SpringApplication.run(TourGuideApplication.class, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
Expand All @@ -19,80 +21,82 @@
public class RewardsService {
private static final double STATUTE_MILES_PER_NAUTICAL_MILE = 1.15077945;

// proximity in miles
private int defaultProximityBuffer = 10;
private int proximityBuffer = defaultProximityBuffer;
private int attractionProximityRange = 200;
private final GpsUtil gpsUtil;
private final RewardCentral rewardsCentral;
private final ReentrantLock rewardsLock = new ReentrantLock();

public RewardsService(GpsUtil gpsUtil, RewardCentral rewardCentral) {
this.gpsUtil = gpsUtil;
this.rewardsCentral = rewardCentral;
}

public void setProximityBuffer(int proximityBuffer) {
this.proximityBuffer = proximityBuffer;
}

public void setDefaultProximityBuffer() {
proximityBuffer = defaultProximityBuffer;
}

public void calculateRewards(User user) {
rewardsLock.lock();
try {
List<VisitedLocation> userLocations = user.getVisitedLocations();
List<Attraction> attractions = gpsUtil.getAttractions();

for(VisitedLocation visitedLocation : userLocations) {
for(Attraction attraction : attractions) {
if(user.getUserRewards().stream().noneMatch(reward -> reward.attraction.attractionName
.equals(attraction.attractionName))) {
if(nearAttraction(visitedLocation, attraction)) {
user.addUserReward(new UserReward(visitedLocation, attraction));
}
}
}
}
} finally {
rewardsLock.unlock();
}
}

public boolean isWithinAttractionProximity(Attraction attraction, Location location) {
return getDistance(attraction, location) > attractionProximityRange ? false : true;
}

private boolean nearAttraction(VisitedLocation visitedLocation, Attraction attraction) {
return !(getDistance(attraction, visitedLocation.location) > proximityBuffer);
}

public int getRewardPoints(Attraction attraction, User user) {
return rewardsCentral.getAttractionRewardPoints(attraction.attractionId, user.getUserId());
}

public double getDistance(Location loc1, Location loc2) {
// proximity in miles
private static final int defaultProximityBuffer = 10;
private int proximityBuffer = defaultProximityBuffer;
private int attractionProximityRange = 200;
private final GpsUtil gpsUtil;
private final RewardCentral rewardsCentral;
private final List<Attraction> attractions;
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

public RewardsService(GpsUtil gpsUtil, RewardCentral rewardCentral) {
this.gpsUtil = gpsUtil;
this.rewardsCentral = rewardCentral;
this.attractions = gpsUtil.getAttractions();
}

public void setProximityBuffer(int proximityBuffer) {
this.proximityBuffer = proximityBuffer;
}

public void setDefaultProximityBuffer() {
proximityBuffer = defaultProximityBuffer;
}

public void calculateAllUsersRewards(List<User> users) {
List<CompletableFuture<Void>> futures = users.stream()
.map(u -> CompletableFuture.runAsync(() -> calculateRewards(u), executorService))
.toList();

futures.forEach(CompletableFuture::join);
}

public void calculateRewards(User user) {
List<VisitedLocation> userLocations = user.getVisitedLocations();

for (VisitedLocation visitedLocation : userLocations) {
for (Attraction attraction : attractions) {
if (user.getUserRewards().stream().noneMatch(r -> r.attraction.attractionName.equals(attraction.attractionName))) {
if (nearAttraction(visitedLocation, attraction)) {
user.addUserReward(new UserReward(visitedLocation, attraction));
}
}
}
}
}

public boolean isWithinAttractionProximity(Attraction attraction, Location location) {
return !(getDistance(attraction, location) > attractionProximityRange);
}

private boolean nearAttraction(VisitedLocation visitedLocation, Attraction attraction) {
return !(getDistance(attraction, visitedLocation.location) > proximityBuffer);
}

public int getRewardPoints(Attraction attraction, User user) {
return rewardsCentral.getAttractionRewardPoints(attraction.attractionId, user.getUserId());
}

public double getDistance(Location loc1, Location loc2) {
double lat1 = Math.toRadians(loc1.latitude);
double lon1 = Math.toRadians(loc1.longitude);
double lat2 = Math.toRadians(loc2.latitude);
double lon2 = Math.toRadians(loc2.longitude);

double angle = Math.acos(Math.sin(lat1) * Math.sin(lat2)
+ Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
+ Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));

double nauticalMiles = 60 * Math.toDegrees(angle);
double statuteMiles = STATUTE_MILES_PER_NAUTICAL_MILE * nauticalMiles;
return statuteMiles;
}

public List<Attraction> findClosestAttractions(Location userLocation, List<Attraction> attractions, int limit) {
return attractions.stream()
.sorted(Comparator.comparingDouble(a ->
getDistance(userLocation, new Location(a.latitude, a.longitude))))
.limit(limit)
.collect(Collectors.toList());
}
return STATUTE_MILES_PER_NAUTICAL_MILE * nauticalMiles;
}

public List<Attraction> findClosestAttractions(Location userLocation, List<Attraction> attractions, int limit) {
return attractions.stream()
.sorted(Comparator.comparingDouble(a ->
getDistance(userLocation, new Location(a.latitude, a.longitude))))
.limit(limit)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

Expand All @@ -32,6 +35,8 @@ public class TourGuideService {
private final TripPricer tripPricer = new TripPricer();
public final Tracker tracker;
boolean testMode = true;
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());


public TourGuideService(GpsUtil gpsUtil, RewardsService rewardsService) {
this.gpsUtil = gpsUtil;
Expand Down Expand Up @@ -98,6 +103,14 @@ public List<Provider> getTripDeals(User user) {
return providers;
}

public void trackAllUsersLocation(List<User> users) {
List<CompletableFuture<Void>> futures = users.stream()
.map(u -> CompletableFuture.runAsync(() -> trackUserLocation(u), executorService))
.toList();

futures.forEach(CompletableFuture::join);
}

public VisitedLocation trackUserLocation(User user) {
VisitedLocation visitedLocation = gpsUtil.getUserLocation(user.getUserId());
user.addToVisitedLocations(visitedLocation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void run() {
List<User> users = tourGuideService.getAllUsers();
logger.debug("Begin Tracker. Tracking " + users.size() + " users.");
stopWatch.start();
users.forEach(u -> tourGuideService.trackUserLocation(u));
tourGuideService.trackAllUsersLocation(users);
stopWatch.stop();
logger.debug("Tracker Time Elapsed: " + TimeUnit.MILLISECONDS.toSeconds(stopWatch.getTime()) + " seconds.");
stopWatch.reset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,13 @@ public void highVolumeTrackLocation() {
InternalTestHelper.setInternalUserNumber(100);
TourGuideService tourGuideService = new TourGuideService(gpsUtil, rewardsService);

List<User> allUsers = new ArrayList<>();
allUsers = tourGuideService.getAllUsers();
List<User> allUsers = tourGuideService.getAllUsers();

StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (User user : allUsers) {
tourGuideService.trackUserLocation(user);
}

tourGuideService.trackAllUsersLocation(allUsers);

stopWatch.stop();
tourGuideService.tracker.stopTracking();

Expand All @@ -89,7 +88,7 @@ public void highVolumeGetRewards() {
allUsers = tourGuideService.getAllUsers();
allUsers.forEach(u -> u.addToVisitedLocations(new VisitedLocation(u.getUserId(), attraction, new Date())));

allUsers.forEach(u -> rewardsService.calculateRewards(u));
rewardsService.calculateAllUsersRewards(allUsers);

for (User user : allUsers) {
assertTrue(user.getUserRewards().size() > 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.util.UUID;

import gpsUtil.location.Location;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import gpsUtil.GpsUtil;
Expand All @@ -23,13 +22,6 @@
import com.openclassrooms.tourguide.user.UserReward;

public class TestRewardsService {
private RewardsService rewardsService;

@BeforeEach
public void setup() {
rewardsService = new RewardsService(null, null); // on passe null pour gpsUtil et RewardCentral ici si inutilisés
}

@Test
public void userGetRewards() {
GpsUtil gpsUtil = new GpsUtil();
Expand Down Expand Up @@ -74,6 +66,9 @@ public void nearAllAttractions() {

@Test
public void testFindClosestAttractions() {
GpsUtil gpsUtil = new GpsUtil();
RewardsService rewardsService = new RewardsService(gpsUtil, new RewardCentral());

Location userLocation = new Location(40.0, -75.0);

Attraction a1 = new Attraction("Attraction1", "City1", "State1", 40.0, -75.0); // distance 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class TourguideApplicationTests {
class TourGuideApplicationTests {

@Test
void contextLoads() {
Expand Down