Skip to content

Commit 416ad99

Browse files
committed
feat: Google Distance Matrix API 클라이언트 및 응답 파서 구현
1 parent 2060cfa commit 416ad99

4 files changed

Lines changed: 146 additions & 9 deletions

File tree

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.ODG.ODG_back.external.google;
22

3-
import java.math.BigDecimal;
3+
import com.ODG.ODG_back.domain.enums.TransportType;
4+
45
import java.util.List;
56

67
public interface GoogleMatrixApiClient {
7-
int[][] getTimeMatrix(List<List<BigDecimal>> origins, List<List<BigDecimal>> destinations);
8+
int[][] getTimeMatrix(List<String> origins, List<String> destinations, TransportType transport);
89
}
Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,55 @@
11
package com.ODG.ODG_back.external.google;
22

3+
import com.ODG.ODG_back.domain.enums.TransportType;
34
import org.springframework.beans.factory.annotation.Value;
45
import org.springframework.stereotype.Component;
5-
import org.springframework.web.client.RestTemplate;
6+
import org.springframework.web.reactive.function.client.WebClient;
67

7-
import java.math.BigDecimal;
88
import java.util.List;
9+
import java.util.Map;
10+
11+
import static com.ODG.ODG_back.external.google.parser.GoogleMatrixResponseParser.parseTimeMatrix;
912

1013
@Component("googleMatrixApiClient")
1114
public class GoogleMatrixApiClientImpl implements GoogleMatrixApiClient {
1215

13-
@Value("{google.api.key}")
14-
private String googleApiKey;
16+
private final String googleApiKey;
17+
private final WebClient webClient;
1518

16-
private final RestTemplate restTemplate = new RestTemplate();
19+
public GoogleMatrixApiClientImpl(WebClient.Builder builder, @Value("${google.api.key}") String googleApiKey) {
20+
this.webClient = builder.build();
21+
this.googleApiKey = googleApiKey;
22+
}
1723

1824
@Override
19-
public int[][] getTimeMatrix(List<List<BigDecimal>> origins, List<List<BigDecimal>> destinations) {
20-
return new int[0][];
25+
public int[][] getTimeMatrix(List<String> origins, List<String> destinations, TransportType transport) {
26+
27+
String url = buildUrl(origins, destinations, transport);
28+
Map<String, Object> response = fetchApiResponse(url);
29+
30+
return parseTimeMatrix(response, origins.size(), destinations.size());
31+
}
32+
33+
private String buildUrl(List<String> origins, List<String> destinations, TransportType transport) {
34+
35+
String originsParam = String.join("|", origins);
36+
String destinationsParam = String.join("|", destinations);
37+
String mode = transport == TransportType.CAR ? "driving" : "transit";
38+
39+
String url = String.format(
40+
"https://maps.googleapis.com/maps/api/distancematrix/json?" +
41+
"origins=%s&destinations=%s&mode=%s&key=%s",
42+
originsParam, destinationsParam, mode, googleApiKey
43+
);
44+
45+
return url;
46+
}
47+
48+
private Map<String, Object> fetchApiResponse(String url) {
49+
return webClient.get()
50+
.uri(url)
51+
.retrieve()
52+
.bodyToMono(Map.class)
53+
.block();
2154
}
2255
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.ODG.ODG_back.external.google.parser;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public class GoogleMatrixResponseParser {
7+
public static int[][] parseTimeMatrix(Map<String, Object> response, int originSize, int destinationSize) {
8+
List<Map<String, Object>> rows = (List<Map<String, Object>>) response.get("rows");
9+
10+
int[][] timeMatrix = new int[originSize][destinationSize];
11+
12+
for (int i = 0; i < originSize; i++) {
13+
Map<String, Object> row = rows.get(i);
14+
List<Map<String, Object>> elements = (List<Map<String, Object>>) row.get("elements");
15+
16+
for (int j = 0; j < destinationSize; j++) {
17+
Map<String, Object> element = elements.get(j);
18+
Map<String, Object> duration = (Map<String, Object>) element.get("duration");
19+
20+
if (duration != null) {
21+
timeMatrix[i][j] = (int) duration.get("value");
22+
} else {
23+
timeMatrix[i][j] = Integer.MAX_VALUE; // unreachable destination
24+
}
25+
}
26+
}
27+
return timeMatrix;
28+
}
29+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.ODG.ODG_back.external.google;
2+
3+
import com.ODG.ODG_back.domain.enums.TransportType;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.ExtendWith;
8+
import org.mockito.*;
9+
import org.mockito.junit.jupiter.MockitoExtension;
10+
import org.springframework.web.reactive.function.client.WebClient;
11+
import reactor.core.publisher.Mono;
12+
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
import static org.junit.jupiter.api.Assertions.*;
17+
import static org.mockito.ArgumentMatchers.anyString;
18+
import static org.mockito.Mockito.*;
19+
20+
@ExtendWith(MockitoExtension.class)
21+
class GoogleMatrixApiClientImplTest {
22+
23+
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
24+
private WebClient mockWebClient;
25+
26+
@Mock
27+
private WebClient.Builder mockBuilder;
28+
29+
private GoogleMatrixApiClientImpl client;
30+
31+
@BeforeEach
32+
void setUp() {
33+
when(mockBuilder.build()).thenReturn(mockWebClient);
34+
client = new GoogleMatrixApiClientImpl(mockBuilder, "fake-api-key");
35+
}
36+
37+
@Test
38+
@DisplayName("Google API - 예상 소요 시간 행렬 반환")
39+
void testGetTimeMatrix() {
40+
41+
// given
42+
List<String> origins = List.of("37.5665, 126.9780", "37.5596,126.9900");
43+
List<String> destinations = List.of("37.5700,126.9780", "37.5651,126.9895");
44+
45+
Map<String, Object> fakeResponse = Map.of(
46+
"rows", List.of(
47+
Map.of("elements", List.of(
48+
Map.of("duration", Map.of("value", 1000)),
49+
Map.of("duration", Map.of("value", 1200))
50+
)),
51+
Map.of("elements", List.of(
52+
Map.of("duration", Map.of("value", 1300)),
53+
Map.of("duration", Map.of("value", 1500))
54+
))
55+
)
56+
);
57+
58+
when(mockWebClient.get()
59+
.uri(anyString())
60+
.retrieve()
61+
.bodyToMono(Map.class))
62+
.thenReturn(Mono.just(fakeResponse));
63+
64+
// when
65+
int[][] matrix = client.getTimeMatrix(origins, destinations, TransportType.PUBLIC);
66+
67+
// then
68+
assertEquals(2, matrix.length);
69+
assertEquals(2, matrix[0].length);
70+
assertEquals(1000, matrix[0][0]);
71+
assertEquals(1200, matrix[0][1]);
72+
}
73+
74+
}

0 commit comments

Comments
 (0)