환경 변수 등록

KAKAO_API_KEY=카카오 개발자 센터에서 발급 받은 REST API KEY

HubRouteEstimator.java

../domain/HubRouteEstimator.java

package org.spartahub.hubservice.domain;

import java.util.List;

/**
 * 허브 다중 경유 총 거리 및 소요 시간 계산
 * - 소요 시간은 hour 단위, 거리는 km 단위로 계산
 * - 0번째는 거리 1번째는 소요시간
 */
public interface HubRouteEstimator {
    double[] estimate(List<Hub> hubs);
}

KakaoHubRouteEstimator.java

../infrastructure/api/KakaoHubRouteEstimator.java

package org.spartahub.hubservice.infrastructure.api;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.spartahub.hubservice.domain.Hub;
import org.spartahub.hubservice.domain.HubRouteEstimator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class KakaoHubRouteEstimator implements HubRouteEstimator {

    @Value("${kakao.restapi.key}")
    private String apiKey;

    @Override
    public double[] estimate(List<Hub> hubs) {
        if (hubs == null || hubs.isEmpty() || hubs.size() < 2) {
            return null;
        }

        Map<String, Object> params = new HashMap<>();
        Hub departure = hubs.getFirst(); // 출발지 허브
        Hub arrival = hubs.getLast(); // 도착지 허브

        // 출발지
        params.put("origin", Map.of("name", departure.getHubName(), "x", departure.getLocation().getLongitude(), "y", departure.getLocation().getLatitude()));

        // 도착지
        params.put("destination", Map.of("name", arrival.getHubName(), "x", arrival.getLocation().getLongitude(), "y", arrival.getLocation().getLatitude()));

        // 경유지
        if (hubs.size() > 2) {
            List<Map<String, Object>> waypoints = hubs.subList(1, hubs.size() - 1)
                    .stream()
                    .map(hub -> {
                        Map<String, Object> item = new HashMap<>();
                        item.put("name", hub.getHubName());
                        item.put("x", hub.getLocation().getLongitude());
                        item.put("y", hub.getLocation().getLatitude());
                        return item;
                    }).toList();
            params.put("waypoints", waypoints);
        }

        ResponseEntity<JsonNode> response = RestClient.builder()
                .baseUrl("<https://apis-navi.kakaomobility.com/v1/waypoints/directions>")
                .build()
                .post()
                .contentType(MediaType.APPLICATION_JSON)
                .header("Authorization", "KakaoAK " + apiKey
                )
                .body(params)
                .retrieve()
                .toEntity(JsonNode.class);

        if (response.getStatusCode().is2xxSuccessful()) {
            double distance = 0.0, duration = 0.0;
            try {
                JsonNode nodes = response.getBody();
                JsonNode routes = nodes.get("routes");
                if (routes != null && routes.isArray()) {
                    for (JsonNode route : routes) {
                        distance += route.get("summary").get("distance").asDouble(0.0);
                        duration += route.get("summary").get("duration").asDouble(0.0);

                    }
                }
                return new double[] {distance / 1000.0, duration / 1000.0};
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }
}

테스트 하기

src/test/…/KakaoHubRouteEstimatorTest.java

package org.spartahub.hubservice.infrastructure.api;

import org.junit.jupiter.api.Test;
import org.spartahub.hubservice.domain.Hub;
import org.spartahub.hubservice.domain.HubRepository;
import org.spartahub.hubservice.domain.HubRouteEstimator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.util.Arrays;
import java.util.List;

@SpringBootTest
@ActiveProfiles("test")
public class KakaoHubRouteEstimatorTest {
    @Autowired
    HubRepository repository;

    @Autowired
    HubRouteEstimator estimator;

    @Test
    void hubRouteEstimatorTest() {
        List<Hub> hubs = repository.findAll();

        double[] item = estimator.estimate(hubs);
        System.out.println("결과: " + Arrays.toString(item));
    }
}

정상 계산이 되었다면