From 6549c2714f535a50773985253ba057a58c0d1972 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:14:20 +0900 Subject: [PATCH 01/11] feat: google geocoding api --- build.gradle | 2 ++ src/main/resources/application.yml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index a92a83e..d85abc9 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,8 @@ dependencies { implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.12' implementation 'net.minidev:json-smart:2.4.9' + implementation 'com.google.maps:google-maps-services:0.2.7' + compileOnly 'org.projectlombok:lombok:1.18.30' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok:1.18.30' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 20cf506..726908d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -16,6 +16,9 @@ spring: path: /h2-console jwt: secret: fpvuvttzKZKGmQ3UoD0QpU7oSDAmCKb8X6l78RULm1Rm01R5Itcg5C8Q9me5sffF +gcp: + geocoding: + api-key: AIzaSyCZ9Kh15ocpwy2GTliq-zKgu64h8_8qPzM logging: level: From 8e84895908cfd6605664e37ac08e5f11b9db8be8 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:14:32 +0900 Subject: [PATCH 02/11] style: optimize imports --- .../java/com/gdscys/cokepoke/poke/controller/PokeController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/gdscys/cokepoke/poke/controller/PokeController.java b/src/main/java/com/gdscys/cokepoke/poke/controller/PokeController.java index d2b5fa7..c1dc9fc 100644 --- a/src/main/java/com/gdscys/cokepoke/poke/controller/PokeController.java +++ b/src/main/java/com/gdscys/cokepoke/poke/controller/PokeController.java @@ -15,7 +15,6 @@ import java.util.stream.Collectors; import static com.gdscys.cokepoke.auth.SecurityUtil.getLoginUsername; -import static java.util.Arrays.stream; @Controller @RequiredArgsConstructor From 0a700034d539baeb2b84d1e3c04dfa0709202e99 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:35:26 +0900 Subject: [PATCH 03/11] feat: dependencies for geocoding api & calculating distance --- build.gradle | 3 +++ .../com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java diff --git a/build.gradle b/build.gradle index d85abc9..b8bd3b6 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,7 @@ configurations { } repositories { + maven { url "https://repo.osgeo.org/repository/release/"} mavenCentral() } @@ -31,6 +32,8 @@ dependencies { implementation 'net.minidev:json-smart:2.4.9' implementation 'com.google.maps:google-maps-services:0.2.7' + implementation 'org.apache.httpcomponents:httpclient:4.5.14' + implementation 'org.geotools:gt-main:28.5' compileOnly 'org.projectlombok:lombok:1.18.30' runtimeOnly 'com.h2database:h2' diff --git a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java new file mode 100644 index 0000000..9fa5891 --- /dev/null +++ b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java @@ -0,0 +1,2 @@ +package com.gdscys.cokepoke.api.geocoding;public class GeocodingService { +} From 2bce6232a92fb4b3c55bae6593ed4431e4fe9da1 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:35:34 +0900 Subject: [PATCH 04/11] feat: geocoding service --- .../api/geocoding/GeocodingAPIService.java | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java index 9fa5891..5defcb9 100644 --- a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java +++ b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java @@ -1,2 +1,68 @@ -package com.gdscys.cokepoke.api.geocoding;public class GeocodingService { +package com.gdscys.cokepoke.api.geocoding; + +import org.geotools.geometry.jts.JTS; +import org.geotools.referencing.GeodeticCalculator; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClients; +import org.locationtech.jts.geom.Coordinate; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +@Service +public class GeocodingAPIService { + @Value("${gcp.geocoding.api-key}") + private String apiKey; + + private final String GEOCODING_API_URL = "https://maps.googleapis.com/maps/api/geocode/json"; + + public double[] getCoordinates(String address) { + try { + HttpClient httpClient = HttpClients.createDefault(); + HttpGet getRequest = new HttpGet(GEOCODING_API_URL + "?address=" + address + "&key=" + apiKey); + + HttpResponse response = httpClient.execute(getRequest); + + if (response.getStatusLine().getStatusCode() == 200) { + BufferedReader reader = new BufferedReader(new InputStreamReader( + response.getEntity().getContent())); + + StringBuilder responseStringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + responseStringBuilder.append(line); + } + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(responseStringBuilder.toString()); + + double latitude = jsonNode.path("results").path(0).path("geometry").path("location").path("lat").asDouble(); + double longitude = jsonNode.path("results").path(0).path("geometry").path("location").path("lng").asDouble(); + + return new double[]{latitude, longitude}; + } + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public double calculateDistance(double lat1, double lon1, double lat2, double lon2) { + GeodeticCalculator calculator = new GeodeticCalculator(); + Coordinate coord1 = new Coordinate(lon1, lat1); + Coordinate coord2 = new Coordinate(lon2, lat2); + + calculator.setStartingGeographicPoint(coord1.x, coord1.y); + calculator.setDestinationGeographicPoint(coord2.x, coord2.y); + + return calculator.getOrthodromicDistance() / 1000; // Convert to kilometers + } + } From e5f6c49069aa3c9ee7a877463c2dcfbbe646f4b7 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:35:50 +0900 Subject: [PATCH 05/11] feat: add myAddress field in friendship request to filter out members out of 1km distance --- .../com/gdscys/cokepoke/friendship/dto/FriendshipRequest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/gdscys/cokepoke/friendship/dto/FriendshipRequest.java b/src/main/java/com/gdscys/cokepoke/friendship/dto/FriendshipRequest.java index 7873205..5fab09c 100644 --- a/src/main/java/com/gdscys/cokepoke/friendship/dto/FriendshipRequest.java +++ b/src/main/java/com/gdscys/cokepoke/friendship/dto/FriendshipRequest.java @@ -11,5 +11,8 @@ public class FriendshipRequest { @NotBlank private String toUsername; + @NotBlank + private String myAddress; + protected FriendshipRequest() {} } From fc5bf3518d41a858bd629928a05cd47f0d96e0b8 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:44:17 +0900 Subject: [PATCH 06/11] feat: check distance when creating friendship --- .../friendship/controller/FriendshipController.java | 2 +- .../friendship/service/FriendshipService.java | 9 ++++++++- .../friendship/service/IFriendshipService.java | 3 +-- .../com/gdscys/cokepoke/member/domain/Member.java | 12 +++++++++++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java b/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java index c9b373c..583b9a5 100644 --- a/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java +++ b/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java @@ -29,7 +29,7 @@ public class FriendshipController { @PostMapping("/create") public ResponseEntity createFriendship(@RequestBody @Valid FriendshipRequest request) { String username = getLoginUsername(); - friendshipService.createFriendship(username, request.getToUsername()); + friendshipService.createFriendship(username, request.getToUsername(), request.getMyAddress()); return ResponseEntity.status(HttpStatus.CREATED).build(); } diff --git a/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java b/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java index 87f8409..388e58a 100644 --- a/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java +++ b/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java @@ -1,5 +1,6 @@ package com.gdscys.cokepoke.friendship.service; +import com.gdscys.cokepoke.api.geocoding.GeocodingAPIService; import com.gdscys.cokepoke.friendship.domain.Friendship; import com.gdscys.cokepoke.friendship.repository.FriendshipRepository; import com.gdscys.cokepoke.member.domain.Member; @@ -19,14 +20,20 @@ public class FriendshipService implements IFriendshipService { private final FriendshipRepository friendshipRepository; private final MemberService memberService; + private final GeocodingAPIService geocodingAPIService; private static final int PAGE_SIZE = 15; @Override @Transactional - public void createFriendship(String username, String recipientUsername) { + public void createFriendship(String username, String recipientUsername, String requestAddress) { Member member = memberService.getMemberByUsername(username); Member to = memberService.getMemberByUsername(recipientUsername); + + double[] location = geocodingAPIService.getCoordinates(requestAddress); + double distanceInKm = geocodingAPIService.calculateDistance(location[0], location[1], to.getLatitude(), to.getLongitude()); + if (distanceInKm > 1.0) throw new IllegalArgumentException("You are too far away from " + to.getUsername()); + if (member.equals(to)) throw new IllegalArgumentException("You cannot be friends with yourself"); if (friendshipRepository.findByFromAndTo(member, to).isPresent()) { throw new IllegalArgumentException("You already sent a friend request"); diff --git a/src/main/java/com/gdscys/cokepoke/friendship/service/IFriendshipService.java b/src/main/java/com/gdscys/cokepoke/friendship/service/IFriendshipService.java index 86da5c5..ffc278c 100644 --- a/src/main/java/com/gdscys/cokepoke/friendship/service/IFriendshipService.java +++ b/src/main/java/com/gdscys/cokepoke/friendship/service/IFriendshipService.java @@ -1,13 +1,12 @@ package com.gdscys.cokepoke.friendship.service; import com.gdscys.cokepoke.friendship.domain.Friendship; -import com.gdscys.cokepoke.member.domain.Member; import java.util.List; public interface IFriendshipService { - void createFriendship(String username, String recipientUsername); + void createFriendship(String username, String recipientUsername, String requestAddress); Friendship getFriendshipById(Long friendshipId); Friendship getFriendshipByMembers(String username, String username2); diff --git a/src/main/java/com/gdscys/cokepoke/member/domain/Member.java b/src/main/java/com/gdscys/cokepoke/member/domain/Member.java index 8c8d009..9f454d7 100644 --- a/src/main/java/com/gdscys/cokepoke/member/domain/Member.java +++ b/src/main/java/com/gdscys/cokepoke/member/domain/Member.java @@ -57,6 +57,12 @@ public class Member implements UserDetails { @Column(name = "timezone", nullable = false) private ZoneId timezone; + @Column(name = "latitude", nullable = false) + private double latitude; + + @Column(name = "longitude", nullable = false) + private double longitude; + @OneToOne(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private RefreshToken refreshToken; @@ -72,14 +78,18 @@ public Member(String email, String username, String passwordHash, Set ro this.passwordHash = passwordHash; this.roles = roles; this.timezone = ZoneId.of("Asia/Seoul"); + this.latitude = 0; + this.longitude = 0; } - public Member(String email, String username, String passwordHash, Set roles, ZoneId timezone) { + public Member(String email, String username, String passwordHash, Set roles, ZoneId timezone, double latitude, double longitude) { this.email = email; this.username = username; this.passwordHash = passwordHash; this.roles = roles; this.timezone = timezone; + this.latitude = latitude; + this.longitude = longitude; } public void addRequested(Friendship friendship) { From 1aea9ec676942e3dcef09d3210d198e3e18ebe47 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:44:26 +0900 Subject: [PATCH 07/11] fix: reflect changes made --- .../com/gdscys/cokepoke/controller/PokeControllerTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java b/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java index 2335d9b..1dfe2ac 100644 --- a/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java +++ b/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java @@ -1,9 +1,6 @@ package com.gdscys.cokepoke.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import com.gdscys.cokepoke.friendship.domain.Friendship; -import com.gdscys.cokepoke.friendship.dto.FriendshipRequest; -import com.gdscys.cokepoke.friendship.repository.FriendshipRepository; import com.gdscys.cokepoke.friendship.service.FriendshipService; import com.gdscys.cokepoke.member.domain.Member; import com.gdscys.cokepoke.member.repository.MemberRepository; @@ -51,8 +48,8 @@ public void setup() { memberRepository.save(new Member("test3@gmail.com", "test3", "test3", new HashSet<>())); //test1 & test3 are friends - friendshipService.createFriendship("test1", "test3"); - friendshipService.createFriendship("test3", "test1"); + friendshipService.createFriendship("test1", "test3", "1600 Amphitheatre Parkway, Mountain View, CA"); + friendshipService.createFriendship("test3", "test1", "1600 Amphitheatre Parkway, Mountain View, CA"); } @Test From 2ed8c6fdf4cae2665dbb2f4ff0e7aad51b9d17f2 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 17:46:04 +0900 Subject: [PATCH 08/11] fix: reflect changes due to addition of gecoding api --- .../cokepoke/controller/FriendshipControllerTest.java | 8 +++++--- .../gdscys/cokepoke/controller/PokeControllerTest.java | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java b/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java index 65e6b66..0b61b88 100644 --- a/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java +++ b/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java @@ -46,6 +46,8 @@ public class FriendshipControllerTest { @Autowired private ObjectMapper objectMapper; + private final String address = "1600 Amphitheatre Parkway, Mountain View, CA"; + @BeforeEach public void setup() { memberRepository.save(new Member("test1@gmail.com", "test1", "test1", new HashSet<>())); @@ -58,7 +60,7 @@ public void setup() { @DisplayName("친구관계 만들기") @WithMockUser(username = "test1", password = "test1") public void create_friendship() throws Exception { - String content = objectMapper.writeValueAsString(new FriendshipRequest("test2")); + String content = objectMapper.writeValueAsString(new FriendshipRequest("test2", address)); mockMvc.perform(post("/friendship/create") .content(content) .contentType(MediaType.APPLICATION_JSON)) @@ -70,7 +72,7 @@ public void create_friendship() throws Exception { @DisplayName("나 자신과는 친구 관계 못함") @WithMockUser(username = "test1", password = "test1") public void create_self_friendship() throws Exception { - String content = objectMapper.writeValueAsString(new FriendshipRequest("test1")); + String content = objectMapper.writeValueAsString(new FriendshipRequest("test1", address)); mockMvc.perform(post("/friendship/create") .content(content) .contentType(MediaType.APPLICATION_JSON)) @@ -82,7 +84,7 @@ public void create_self_friendship() throws Exception { @DisplayName("이미 친구 신청했으면 다시 하지는 못함") @WithMockUser(username = "test1", password = "test1") public void reattempt_friendship() throws Exception { - String content = objectMapper.writeValueAsString(new FriendshipRequest("test3")); + String content = objectMapper.writeValueAsString(new FriendshipRequest("test3", address)); mockMvc.perform(post("/friendship/create") .content(content) .contentType(MediaType.APPLICATION_JSON)) diff --git a/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java b/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java index 1dfe2ac..dfc762e 100644 --- a/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java +++ b/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java @@ -41,6 +41,8 @@ public class PokeControllerTest { @Autowired private ObjectMapper objectMapper; + private final String address = "1600 Amphitheatre Parkway, Mountain View, CA"; + @BeforeEach public void setup() { memberRepository.save(new Member("test1@gmail.com", "test1", "test1", new HashSet<>())); @@ -48,8 +50,8 @@ public void setup() { memberRepository.save(new Member("test3@gmail.com", "test3", "test3", new HashSet<>())); //test1 & test3 are friends - friendshipService.createFriendship("test1", "test3", "1600 Amphitheatre Parkway, Mountain View, CA"); - friendshipService.createFriendship("test3", "test1", "1600 Amphitheatre Parkway, Mountain View, CA"); + friendshipService.createFriendship("test1", "test3", address); + friendshipService.createFriendship("test3", "test1", address); } @Test From df3cc952a8978787bc3df9fef1f2e4a54842d9f4 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 18:22:41 +0900 Subject: [PATCH 09/11] fix: check geolocation --- .../api/geocoding/GeocodingAPIService.java | 5 ++++- .../auth/controller/AuthController.java | 2 +- .../controller/FriendshipController.java | 2 -- .../friendship/service/FriendshipService.java | 6 +++-- .../gdscys/cokepoke/member/domain/Member.java | 22 +++++++++---------- .../cokepoke/member/dto/SignupRequest.java | 10 ++++++++- .../member/service/IMemberService.java | 3 ++- .../member/service/MemberService.java | 5 +++-- .../controller/FriendshipControllerTest.java | 8 +++---- .../controller/PokeControllerTest.java | 8 +++---- 10 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java index 5defcb9..285e21b 100644 --- a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java +++ b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java @@ -14,6 +14,8 @@ import java.io.BufferedReader; import java.io.InputStreamReader; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; @Service public class GeocodingAPIService { @@ -25,7 +27,8 @@ public class GeocodingAPIService { public double[] getCoordinates(String address) { try { HttpClient httpClient = HttpClients.createDefault(); - HttpGet getRequest = new HttpGet(GEOCODING_API_URL + "?address=" + address + "&key=" + apiKey); + String encodedAddress = URLEncoder.encode(address, StandardCharsets.UTF_8.toString()); + HttpGet getRequest = new HttpGet(GEOCODING_API_URL + "?address=" + encodedAddress + "&key=" + apiKey); HttpResponse response = httpClient.execute(getRequest); diff --git a/src/main/java/com/gdscys/cokepoke/auth/controller/AuthController.java b/src/main/java/com/gdscys/cokepoke/auth/controller/AuthController.java index 601599e..83ac291 100644 --- a/src/main/java/com/gdscys/cokepoke/auth/controller/AuthController.java +++ b/src/main/java/com/gdscys/cokepoke/auth/controller/AuthController.java @@ -27,7 +27,7 @@ public class AuthController { @PostMapping("/signup") public ResponseEntity signup(@RequestBody @Valid SignupRequest request) { - Member member = memberService.saveMember(request.getEmail(), request.getUsername(), request.getPassword()); + Member member = memberService.saveMember(request.getEmail(), request.getUsername(), request.getPassword(), request.getTimezone(), request.getAddress()); return ResponseEntity.status(HttpStatus.CREATED) .body(MemberResponse.of(member)); } diff --git a/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java b/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java index 583b9a5..3d18b7d 100644 --- a/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java +++ b/src/main/java/com/gdscys/cokepoke/friendship/controller/FriendshipController.java @@ -3,11 +3,9 @@ import com.gdscys.cokepoke.friendship.dto.FriendshipRequest; import com.gdscys.cokepoke.friendship.dto.FriendshipResponse; import com.gdscys.cokepoke.friendship.service.FriendshipService; -import com.gdscys.cokepoke.member.domain.Member; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java b/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java index 388e58a..e37b1fc 100644 --- a/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java +++ b/src/main/java/com/gdscys/cokepoke/friendship/service/FriendshipService.java @@ -28,10 +28,12 @@ public class FriendshipService implements IFriendshipService { @Transactional public void createFriendship(String username, String recipientUsername, String requestAddress) { Member member = memberService.getMemberByUsername(username); + member.updateAddress(requestAddress); Member to = memberService.getMemberByUsername(recipientUsername); - double[] location = geocodingAPIService.getCoordinates(requestAddress); - double distanceInKm = geocodingAPIService.calculateDistance(location[0], location[1], to.getLatitude(), to.getLongitude()); + double[] requestingLocation = geocodingAPIService.getCoordinates(requestAddress); + double[] receivingLocation = geocodingAPIService.getCoordinates(to.getAddress()); + double distanceInKm = geocodingAPIService.calculateDistance(requestingLocation[0], requestingLocation[1], receivingLocation[0], receivingLocation[1]); if (distanceInKm > 1.0) throw new IllegalArgumentException("You are too far away from " + to.getUsername()); if (member.equals(to)) throw new IllegalArgumentException("You cannot be friends with yourself"); diff --git a/src/main/java/com/gdscys/cokepoke/member/domain/Member.java b/src/main/java/com/gdscys/cokepoke/member/domain/Member.java index 9f454d7..574faf4 100644 --- a/src/main/java/com/gdscys/cokepoke/member/domain/Member.java +++ b/src/main/java/com/gdscys/cokepoke/member/domain/Member.java @@ -57,11 +57,8 @@ public class Member implements UserDetails { @Column(name = "timezone", nullable = false) private ZoneId timezone; - @Column(name = "latitude", nullable = false) - private double latitude; - - @Column(name = "longitude", nullable = false) - private double longitude; + @Column(name = "address", nullable = false) + private String address; @OneToOne(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private RefreshToken refreshToken; @@ -72,24 +69,22 @@ public class Member implements UserDetails { protected Member() {} - public Member(String email, String username, String passwordHash, Set roles) { + public Member(String email, String username, String passwordHash) { this.email = email; this.username = username; this.passwordHash = passwordHash; - this.roles = roles; + this.roles = new HashSet<>(); this.timezone = ZoneId.of("Asia/Seoul"); - this.latitude = 0; - this.longitude = 0; + this.address = "1 Gwanghwamun Square, Jongno-gu, Seoul, South Korea"; } - public Member(String email, String username, String passwordHash, Set roles, ZoneId timezone, double latitude, double longitude) { + public Member(String email, String username, String passwordHash, Set roles, ZoneId timezone, String address) { this.email = email; this.username = username; this.passwordHash = passwordHash; this.roles = roles; this.timezone = timezone; - this.latitude = latitude; - this.longitude = longitude; + this.address = address; } public void addRequested(Friendship friendship) { @@ -104,6 +99,9 @@ public void updatePassword(String passwordHash) { this.passwordHash = passwordHash; } + public void updateAddress(String address) { + this.address = address; + } @Override public Collection getAuthorities() { return this.roles.stream() diff --git a/src/main/java/com/gdscys/cokepoke/member/dto/SignupRequest.java b/src/main/java/com/gdscys/cokepoke/member/dto/SignupRequest.java index 5093db7..9bb1daa 100644 --- a/src/main/java/com/gdscys/cokepoke/member/dto/SignupRequest.java +++ b/src/main/java/com/gdscys/cokepoke/member/dto/SignupRequest.java @@ -26,13 +26,21 @@ public class SignupRequest { @Length(min = 8, max = 20) private String confirmPassword; + @NotBlank + private String timezone; + + @NotBlank + private String address; + protected SignupRequest() {} @Builder - public SignupRequest(String email, String username, String password, String confirmPassword) { + public SignupRequest(String email, String username, String password, String confirmPassword, String timezone, String address) { this.email = email; this.username = username; this.password = password; this.confirmPassword = confirmPassword; + this.timezone = timezone; + this.address = address; } } diff --git a/src/main/java/com/gdscys/cokepoke/member/service/IMemberService.java b/src/main/java/com/gdscys/cokepoke/member/service/IMemberService.java index fa6f874..33eb12c 100644 --- a/src/main/java/com/gdscys/cokepoke/member/service/IMemberService.java +++ b/src/main/java/com/gdscys/cokepoke/member/service/IMemberService.java @@ -3,10 +3,11 @@ import com.gdscys.cokepoke.member.domain.Member; import com.gdscys.cokepoke.member.dto.UpdateMemberRequest; +import java.time.ZoneId; import java.util.List; public interface IMemberService { - Member saveMember(String email, String username, String password); + Member saveMember(String email, String username, String password, String timezone, String address); Member getMemberByUsername(String username); void updateMember(Member member, UpdateMemberRequest request); void deleteMember(Member member); diff --git a/src/main/java/com/gdscys/cokepoke/member/service/MemberService.java b/src/main/java/com/gdscys/cokepoke/member/service/MemberService.java index 1631bf3..76237bd 100644 --- a/src/main/java/com/gdscys/cokepoke/member/service/MemberService.java +++ b/src/main/java/com/gdscys/cokepoke/member/service/MemberService.java @@ -18,6 +18,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.ZoneId; import java.util.Comparator; import java.util.List; import java.util.Optional; @@ -37,8 +38,8 @@ public class MemberService implements IMemberService { private final static int PAGE_SIZE = 15; @Override - public Member saveMember(String email, String username, String password) { - Member member = new Member(email, username, passwordEncoder.encode(password), Set.of("USER")); + public Member saveMember(String email, String username, String password, String timezone, String address) { + Member member = new Member(email, username, passwordEncoder.encode(password), Set.of("USER"), ZoneId.of(timezone), address); return memberRepository.save(member); } diff --git a/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java b/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java index 0b61b88..1ba1505 100644 --- a/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java +++ b/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java @@ -46,13 +46,13 @@ public class FriendshipControllerTest { @Autowired private ObjectMapper objectMapper; - private final String address = "1600 Amphitheatre Parkway, Mountain View, CA"; + private final String address = "1 Gwanghwamun Square, Jongno-gu, Seoul, South Korea"; @BeforeEach public void setup() { - memberRepository.save(new Member("test1@gmail.com", "test1", "test1", new HashSet<>())); - memberRepository.save(new Member("test2@gmail.com", "test2", "test2", new HashSet<>())); - memberRepository.save(new Member("test3@gmail.com", "test3", "test3", new HashSet<>())); + memberRepository.save(new Member("test1@gmail.com", "test1", "test1")); + memberRepository.save(new Member("test2@gmail.com", "test2", "test2")); + memberRepository.save(new Member("test3@gmail.com", "test3", "test3")); friendshipRepository.save(new Friendship(memberRepository.findByUsername("test1").get(), memberRepository.findByUsername("test3").get())); } diff --git a/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java b/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java index dfc762e..8ce7292 100644 --- a/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java +++ b/src/test/java/com/gdscys/cokepoke/controller/PokeControllerTest.java @@ -41,13 +41,13 @@ public class PokeControllerTest { @Autowired private ObjectMapper objectMapper; - private final String address = "1600 Amphitheatre Parkway, Mountain View, CA"; + private final String address = "1 Gwanghwamun Square, Jongno-gu, Seoul, South Korea"; @BeforeEach public void setup() { - memberRepository.save(new Member("test1@gmail.com", "test1", "test1", new HashSet<>())); - memberRepository.save(new Member("test2@gmail.com", "test2", "test2", new HashSet<>())); - memberRepository.save(new Member("test3@gmail.com", "test3", "test3", new HashSet<>())); + memberRepository.save(new Member("test1@gmail.com", "test1", "test1")); + memberRepository.save(new Member("test2@gmail.com", "test2", "test2")); + memberRepository.save(new Member("test3@gmail.com", "test3", "test3")); //test1 & test3 are friends friendshipService.createFriendship("test1", "test3", address); From 19207fbbdde55e044a8dfd520b3272bcf024ebc5 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 18:27:14 +0900 Subject: [PATCH 10/11] feat: can't be friends if too far away --- .../controller/FriendshipControllerTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java b/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java index 1ba1505..464fee9 100644 --- a/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java +++ b/src/test/java/com/gdscys/cokepoke/controller/FriendshipControllerTest.java @@ -92,6 +92,20 @@ public void reattempt_friendship() throws Exception { .andDo(print()); } + @Test + @DisplayName("멀면 친구 못함") + @WithMockUser(username = "test1", password = "test1") + public void far_friendship() throws Exception { + + String content = objectMapper.writeValueAsString(new FriendshipRequest("test2", "10 Downing Street, London SW1A 2AA, United Kingdom")); + mockMvc.perform(post("/friendship/create") + .content(content) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()) + .andDo(print()); + } + + From dff562cae04a690360e21892ab86bfc0d20a6443 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Wed, 11 Oct 2023 20:18:37 +0900 Subject: [PATCH 11/11] style --- build.gradle | 2 -- .../com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java | 1 - 2 files changed, 3 deletions(-) diff --git a/build.gradle b/build.gradle index b8bd3b6..7ab5311 100644 --- a/build.gradle +++ b/build.gradle @@ -46,10 +46,8 @@ dependencies { runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5' runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5' - implementation "com.querydsl:querydsl-jpa:5.0.0" annotationProcessor "com.querydsl:querydsl-apt:5.0.0" - } tasks.named('test') { diff --git a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java index 285e21b..1f545e4 100644 --- a/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java +++ b/src/main/java/com/gdscys/cokepoke/api/geocoding/GeocodingAPIService.java @@ -1,6 +1,5 @@ package com.gdscys.cokepoke.api.geocoding; -import org.geotools.geometry.jts.JTS; import org.geotools.referencing.GeodeticCalculator; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper;