Fix: redis 설정 및 저장 형식 수정
This commit is contained in:
parent
20a9ba9257
commit
e138d9d047
@ -144,37 +144,40 @@ public class ExternalPlatformAdapter implements ExternalPlatformPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 카카오 응답 파싱 및 Redis 저장 (실제 응답 구조에 맞게 완전 수정)
|
* 카카오 응답 파싱 및 Redis 저장 (단순화된 안정적인 방식)
|
||||||
*/
|
*/
|
||||||
private int parseAndStoreToRedis(Long storeId, String platform, String responseBody) {
|
private int parseAndStoreToRedis(Long storeId, String platform, String responseBody) {
|
||||||
try {
|
try {
|
||||||
log.info("카카오 API 응답: {}", responseBody);
|
log.info("카카오 API 응답: {}", responseBody);
|
||||||
|
|
||||||
// JSON 파싱
|
if (responseBody == null || responseBody.trim().isEmpty()) {
|
||||||
JsonNode rootNode = objectMapper.readTree(responseBody);
|
log.warn("카카오 응답이 비어있음: storeId={}", storeId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 🔥 실제 카카오 크롤링 서비스 응답 구조 체크
|
JsonNode root = objectMapper.readTree(responseBody);
|
||||||
if (!rootNode.has("success") || !rootNode.get("success").asBoolean()) {
|
|
||||||
|
// 🔥 실제 카카오 응답 구조에 맞는 파싱
|
||||||
|
if (!root.has("success") || !root.get("success").asBoolean()) {
|
||||||
log.warn("카카오 API 응답 실패: {}", responseBody);
|
log.warn("카카오 API 응답 실패: {}", responseBody);
|
||||||
updateSyncStatus(storeId, platform, "FAILED", 0);
|
updateSyncStatus(storeId, platform, "FAILED", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode reviewsNode = rootNode.get("reviews");
|
JsonNode reviewsNode = root.get("reviews");
|
||||||
if (reviewsNode == null || !reviewsNode.isArray()) {
|
if (reviewsNode == null || !reviewsNode.isArray()) {
|
||||||
log.warn("카카오 응답에 reviews 배열이 없음");
|
log.warn("카카오 응답에 reviews 배열이 없음");
|
||||||
updateSyncStatus(storeId, platform, "SUCCESS", 0);
|
updateSyncStatus(storeId, platform, "SUCCESS", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔥 실제 카카오 응답 구조에 맞는 리뷰 데이터 변환
|
// 리뷰 데이터 파싱
|
||||||
List<Map<String, Object>> parsedReviews = new ArrayList<>();
|
List<Map<String, Object>> reviews = new ArrayList<>();
|
||||||
for (JsonNode reviewNode : reviewsNode) {
|
for (JsonNode reviewNode : reviewsNode) {
|
||||||
Map<String, Object> review = new HashMap<>();
|
Map<String, Object> review = new HashMap<>();
|
||||||
|
|
||||||
// 🔑 기본 리뷰 정보 (실제 필드명 사용)
|
// 기본 정보
|
||||||
review.put("reviewId", generateReviewId(reviewNode));
|
review.put("reviewId", generateReviewId(reviewNode));
|
||||||
review.put("content", reviewNode.path("content").asText(""));
|
review.put("content", reviewNode.path("content").asText(""));
|
||||||
review.put("rating", reviewNode.path("rating").asDouble(0.0));
|
review.put("rating", reviewNode.path("rating").asDouble(0.0));
|
||||||
@ -182,67 +185,41 @@ public class ExternalPlatformAdapter implements ExternalPlatformPort {
|
|||||||
review.put("createdAt", reviewNode.path("date").asText(""));
|
review.put("createdAt", reviewNode.path("date").asText(""));
|
||||||
review.put("platform", platform);
|
review.put("platform", platform);
|
||||||
|
|
||||||
// 🏷️ 카카오 특화 정보
|
// 카카오 특화 정보
|
||||||
review.put("reviewerLevel", reviewNode.path("reviewer_level").asText(""));
|
review.put("reviewerLevel", reviewNode.path("reviewer_level").asText(""));
|
||||||
review.put("likes", reviewNode.path("likes").asInt(0));
|
review.put("likes", reviewNode.path("likes").asInt(0));
|
||||||
review.put("photoCount", reviewNode.path("photo_count").asInt(0));
|
review.put("photoCount", reviewNode.path("photo_count").asInt(0));
|
||||||
review.put("hasPhotos", reviewNode.path("has_photos").asBoolean(false));
|
review.put("hasPhotos", reviewNode.path("has_photos").asBoolean(false));
|
||||||
|
|
||||||
// 📊 리뷰어 통계 (있는 경우만)
|
// 배지 정보
|
||||||
if (reviewNode.has("reviewer_stats")) {
|
|
||||||
JsonNode stats = reviewNode.get("reviewer_stats");
|
|
||||||
Map<String, Object> reviewerStats = new HashMap<>();
|
|
||||||
reviewerStats.put("reviews", stats.path("reviews").asInt(0));
|
|
||||||
reviewerStats.put("averageRating", stats.path("average_rating").asDouble(0.0));
|
|
||||||
reviewerStats.put("followers", stats.path("followers").asInt(0));
|
|
||||||
review.put("reviewerStats", reviewerStats);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🏆 배지 (있는 경우만)
|
|
||||||
if (reviewNode.has("badges") && reviewNode.get("badges").isArray()) {
|
if (reviewNode.has("badges") && reviewNode.get("badges").isArray()) {
|
||||||
List<String> badges = new ArrayList<>();
|
List<String> badges = new ArrayList<>();
|
||||||
for (JsonNode badge : reviewNode.get("badges")) {
|
reviewNode.get("badges").forEach(badge -> badges.add(badge.asText()));
|
||||||
badges.add(badge.asText());
|
|
||||||
}
|
|
||||||
review.put("badges", badges);
|
review.put("badges", badges);
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedReviews.add(review);
|
reviews.add(review);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parsedReviews.isEmpty()) {
|
log.info("파싱된 리뷰 수: {}", reviews.size());
|
||||||
// 🔥 Redis에 저장
|
|
||||||
log.info("Redis에 리뷰 데이터 저장 진행 중");
|
|
||||||
String redisKey = String.format("external:reviews:pending:%d:%s:%d",
|
|
||||||
storeId, platform, System.currentTimeMillis());
|
|
||||||
|
|
||||||
Map<String, Object> cacheData = new HashMap<>();
|
// Redis 저장 (단순한 방식)
|
||||||
cacheData.put("storeId", storeId);
|
saveToRedis(storeId, platform, reviews);
|
||||||
cacheData.put("platform", platform);
|
|
||||||
cacheData.put("reviews", parsedReviews);
|
|
||||||
cacheData.put("status", "PENDING");
|
|
||||||
cacheData.put("timestamp", System.currentTimeMillis());
|
|
||||||
cacheData.put("retryCount", 0);
|
|
||||||
|
|
||||||
redisTemplate.opsForValue().set(redisKey, cacheData, Duration.ofDays(1));
|
// 동기화 상태 업데이트
|
||||||
|
updateSyncStatus(storeId, platform, "SUCCESS", reviews.size());
|
||||||
|
|
||||||
log.info("Redis에 리뷰 데이터 저장 완료: key={}, count={}", redisKey, parsedReviews.size());
|
return reviews.size();
|
||||||
|
|
||||||
// 🔥 동기화 상태 업데이트
|
|
||||||
updateSyncStatus(storeId, platform, "SUCCESS", parsedReviews.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsedReviews.size();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("카카오 응답 파싱 및 Redis 저장 실패: storeId={}, error={}", storeId, e.getMessage());
|
log.error("카카오 응답 파싱 및 Redis 저장 실패: storeId={}, error={}", storeId, e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
updateSyncStatus(storeId, platform, "FAILED", 0);
|
updateSyncStatus(storeId, platform, "FAILED", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 🔥 누락된 generateReviewId 메서드 추가
|
* 🔥 누락된 generateReviewId 메서드 추가
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -29,6 +29,13 @@ spring:
|
|||||||
host: ${REDIS_HOST:localhost}
|
host: ${REDIS_HOST:localhost}
|
||||||
port: ${REDIS_PORT:6379}
|
port: ${REDIS_PORT:6379}
|
||||||
password: ${REDIS_PASSWORD:}
|
password: ${REDIS_PASSWORD:}
|
||||||
|
timeout: 2000ms
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 8
|
||||||
|
max-wait: -1ms
|
||||||
|
max-idle: 8
|
||||||
|
min-idle: 0
|
||||||
|
|
||||||
external-api:
|
external-api:
|
||||||
naver:
|
naver:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user