Skip to content

Commit

Permalink
Merge branch 'Dev-backend' into feat/#105-debate-complete
Browse files Browse the repository at this point in the history
  • Loading branch information
yeonjy committed May 14, 2024
2 parents 05ba9a0 + 87893c6 commit 97fb416
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 1 deletion.
4 changes: 4 additions & 0 deletions backend/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'

testAnnotationProcessor "org.mapstruct:mapstruct-processor:1.5.5.Final"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}

tasks.named('bootBuildImage') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.rollthedice.backend.domain.debate.dto.request.DebateRoomRequest;
import com.rollthedice.backend.domain.debate.dto.response.DebateMessageResponse;
import com.rollthedice.backend.domain.debate.dto.response.DebateRoomResponse;
import com.rollthedice.backend.domain.debate.dto.response.DebateSummaryResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
Expand Down Expand Up @@ -104,6 +105,23 @@ List<DebateMessageResponse> getDebateMessages(
Long roomId
);

@Operation(
summary = "토론 요약",
description = "토론방의 토론 메세지들을 요약합니다.",
security = {@SecurityRequirement(name = "access_token")},
tags = {"debate_message"}
)
@ApiResponse(
responseCode = "200",
description = "OK"
)
DebateSummaryResponse getSummarizedDebate(
@Parameter(in = ParameterIn.PATH, description = "토론방 ID", required = true)
Long roomId
);





}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.rollthedice.backend.domain.debate.dto.request.DebateRoomRequest;
import com.rollthedice.backend.domain.debate.dto.response.DebateMessageResponse;
import com.rollthedice.backend.domain.debate.dto.response.DebateRoomResponse;
import com.rollthedice.backend.domain.debate.dto.response.DebateSummaryResponse;
import com.rollthedice.backend.domain.debate.service.DebateMessageService;
import com.rollthedice.backend.domain.debate.service.DebateRoomService;
import jakarta.validation.Valid;
Expand Down Expand Up @@ -62,4 +63,11 @@ public void saveAIDebateMessage(@PathVariable final Long roomId, @RequestBody fi
public List<DebateMessageResponse> getDebateMessages(@PathVariable final Long roomId) {
return debateMessageService.getDebateMessages(roomId);
}

@ResponseStatus(HttpStatus.OK)
@GetMapping("/summary/{roomId}")
@Override
public DebateSummaryResponse getSummarizedDebate(@PathVariable final Long roomId) {
return debateRoomService.summaryDebate(roomId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.rollthedice.backend.domain.debate.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DebateSummaryResponse {
Long roomId;

@Schema(description = "4문장의 요약된 토론 내용")
String summary;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;

@Getter
@Entity
Expand All @@ -17,6 +18,10 @@ public class DebateRoom extends BaseTimeEntity {
private Long id;

private String topic;
private String summary;

@ColumnDefault("false")
private boolean isClosed;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
Expand All @@ -27,4 +32,12 @@ public DebateRoom(Member member, String topic) {
this.member = member;
this.topic = topic;
}

public void closeDebate() {
this.isClosed = true;
}

public void updateSummary(String summary) {
this.summary = summary;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package com.rollthedice.backend.domain.debate.service;

import com.rollthedice.backend.global.error.ErrorCode;
import com.rollthedice.backend.global.error.exception.ExternalApiException;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;
import org.apache.tomcat.util.json.JSONParser;
import org.apache.tomcat.util.json.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;

@Slf4j
@Service
public class ClovaSummary {
private static final String KOREAN = "ko";
private static final int POLITE_TONE = 2;
private static final int SUMMARY_COUNT = 4;

private static final String API_URL = "https://naveropenapi.apigw.ntruss.com/text-summary/v1/summarize";


@Value("${clova.secret-key}")
private String SECRET;

@Value("${clova.client-id}")
private String CLIENT_ID;

public String summaryDebate(String messages) {
log.info("요약할 메세지: {}" ,messages);
try {
URL url = new URL(API_URL);
HttpURLConnection connection = createRequestHeader(url);
createRequestBody(connection, messages);

log.info("정상1");
StringBuilder response = getResponse(connection);
log.info("정상2");
return parseResponse(response);
} catch (Exception e) {
e.printStackTrace();
throw new ExternalApiException(ErrorCode.CLOVA_API_ERROR);
}
}

private HttpURLConnection createRequestHeader(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json;");
connection.setRequestProperty("X-NCP-APIGW-API-KEY-ID", CLIENT_ID);
connection.setRequestProperty("X-NCP-APIGW-API-KEY", SECRET);
return connection;
}

private void createRequestBody(HttpURLConnection connection, String content) throws IOException {
JSONObject document = new JSONObject();
document.put("content", content);

JSONObject option = new JSONObject();
option.put("language", KOREAN);
option.put("tone", POLITE_TONE);
option.put("summaryCount", SUMMARY_COUNT);

JSONObject requestObject = new JSONObject();
requestObject.put("document", document);
requestObject.put("option", option);

connection.connect();
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.write(requestObject.toString().getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}


private StringBuilder getResponse(HttpURLConnection connection) throws IOException {
BufferedReader reader = checkResponse(connection);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
return response;
}

private BufferedReader checkResponse(HttpURLConnection connection) throws IOException {
int responseCode = connection.getResponseCode();

return getResponseResult(connection, responseCode);
}

private BufferedReader getResponseResult(HttpURLConnection connection, int responseCode) throws IOException {
if (HttpStatusCode.valueOf(responseCode).is2xxSuccessful()) {
return new BufferedReader(new InputStreamReader(connection.getInputStream()));
}
log.error("Clova Api error response code: {}", responseCode);
return new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}


private String parseResponse(StringBuilder response) throws ParseException {
JSONParser parser = new JSONParser(response.toString());
LinkedHashMap<String, String> hashMap = (LinkedHashMap<String, String>) parser.parse();
JSONObject parsed = new JSONObject(hashMap);
return parsed.get("summary").toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

import com.rollthedice.backend.domain.debate.dto.request.DebateMessageRequest;
import com.rollthedice.backend.domain.debate.dto.response.DebateMessageResponse;
import com.rollthedice.backend.domain.debate.dto.response.DebateSummaryResponse;
import com.rollthedice.backend.domain.debate.entity.DebateRoom;
import com.rollthedice.backend.domain.debate.exception.DebateRoomNotFoundException;
import com.rollthedice.backend.domain.debate.mapper.DebateMessageMapper;
import com.rollthedice.backend.domain.debate.repository.DebateRoomRepository;
import com.rollthedice.backend.domain.news.repository.DebateMessageRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class DebateMessageService {
Expand Down Expand Up @@ -44,4 +47,11 @@ public List<DebateMessageResponse> getDebateMessages(Long roomId) {
.stream().map(debateMessageMapper::toResponse)
.collect(Collectors.toList());
}

public StringBuilder getAllMessages(Long roomId) {
StringBuilder sb = new StringBuilder();
getDebateMessages(roomId)
.forEach(message -> sb.append(message.getMessage()));
return sb;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.rollthedice.backend.domain.debate.dto.request.DebateRoomRequest;
import com.rollthedice.backend.domain.debate.dto.response.DebateRoomResponse;
import com.rollthedice.backend.domain.debate.dto.response.DebateSummaryResponse;
import com.rollthedice.backend.domain.debate.exception.DebateRoomNotFoundException;
import com.rollthedice.backend.domain.debate.mapper.DebateRoomMapper;
import com.rollthedice.backend.domain.debate.repository.DebateRoomRepository;
import com.rollthedice.backend.domain.member.entity.Member;
Expand All @@ -21,6 +23,7 @@ public class DebateRoomService {
private final DebateRoomMapper debateRoomMapper;
private final DebateRoomRepository debateRoomRepository;
private final DebateMessageService debateMessageService;
private final ClovaSummary clovaSummary;


@Transactional
Expand All @@ -42,4 +45,18 @@ public void deleteDebateRoom(Long roomId) {
debateMessageService.deleteAllDebateMessages(roomId);
debateRoomRepository.deleteById(roomId);
}

@Transactional
public DebateSummaryResponse summaryDebate(final Long roomId) {
StringBuilder sb = debateMessageService.getAllMessages(roomId);
String summary = clovaSummary.summaryDebate(sb.toString());
debateRoomRepository.findById(roomId).orElseThrow(DebateRoomNotFoundException::new)
.updateSummary(summary);

return DebateSummaryResponse.builder()
.roomId(roomId)
.summary(summary)
.build();
}

}
2 changes: 1 addition & 1 deletion backend/core/src/main/resources/scoop-core-config

0 comments on commit 97fb416

Please sign in to comment.