Skip to content

Commit 721f566

Browse files
authored
Merge pull request #45 from codef-io/develop
release: v2.0.0-beta-005
2 parents dcbcb9d + 7fec056 commit 721f566

11 files changed

+260
-203
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<p align="center">
2626
<a href="https://github.com/codef-io/easycodef-java-v2/actions?query=branch%3Amaster"><img align="center" src="https://img.shields.io/github/actions/workflow/status/codef-io/easycodef-java-v2/publish.yml?style=for-the-badge&logo=gradle&color=02303A" alt="Build Status"/></a>
2727
<a href="https://github.com/codef-io/easycodef-java-v2"><img align="center" src="https://img.shields.io/github/last-commit/codef-io/easycodef-java-v2/master?style=for-the-badge&label=LAST%20BUILD&logo=Github&color=181717" alt="Last Commit"/></a>
28-
<a href="https://central.sonatype.com/artifact/io.codef.api/easycodef-java-v2/2.0.0-beta-004"><img align="center" src="https://img.shields.io/maven-central/v/io.codef.api/easycodef-java-v2.svg?style=for-the-badge&label=Maven%20Central&logo=apache-maven&color=C71A36" alt="Maven Central"/></a>
28+
<a href="https://central.sonatype.com/artifact/io.codef.api/easycodef-java-v2/2.0.0-beta-005"><img align="center" src="https://img.shields.io/maven-central/v/io.codef.api/easycodef-java-v2.svg?style=for-the-badge&label=Maven%20Central&logo=apache-maven&color=C71A36" alt="Maven Central"/></a>
2929
</p>
3030

3131
<br><br>

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010

1111

1212
group = "io.codef.api"
13-
version = "2.0.0-beta-004"
13+
version = "2.0.0-beta-005"
1414

1515
signing {
1616
useInMemoryPgpKeys(

src/main/java/io/codef/api/CodefExecutorManager.java

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,21 @@
66
import java.util.concurrent.CompletableFuture;
77
import java.util.concurrent.Executor;
88
import java.util.concurrent.Executors;
9-
import java.util.concurrent.ScheduledExecutorService;
10-
import java.util.concurrent.TimeUnit;
119

12-
// 실행기 관리를 위한 클래스
13-
public class CodefExecutorManager implements AutoCloseable {
14-
private final ScheduledExecutorService scheduler;
10+
public class CodefExecutorManager {
11+
1512
private final Executor virtualThreadExecutor;
1613

17-
private CodefExecutorManager(ScheduledExecutorService scheduler, Executor virtualThreadExecutor) {
18-
this.scheduler = scheduler;
14+
private CodefExecutorManager(Executor virtualThreadExecutor) {
1915
this.virtualThreadExecutor = virtualThreadExecutor;
2016
}
2117

2218
public static CodefExecutorManager create() {
2319
return new CodefExecutorManager(
24-
Executors.newScheduledThreadPool(1),
25-
Executors.newThreadPerTaskExecutor(Thread.ofVirtual().factory())
26-
);
27-
}
28-
29-
public CompletableFuture<EasyCodefResponse> scheduleRequest(
30-
EasyCodefRequest request,
31-
long delayMs,
32-
SingleReqFacade facade
33-
) {
34-
return scheduleDelayedExecution(delayMs)
35-
.thenComposeAsync(
36-
ignored -> executeRequest(request, facade),
37-
virtualThreadExecutor
38-
);
39-
}
40-
41-
private CompletableFuture<Void> scheduleDelayedExecution(long delayMs) {
42-
CompletableFuture<Void> future = new CompletableFuture<>();
43-
scheduler.schedule(
44-
() -> future.complete(null),
45-
delayMs,
46-
TimeUnit.MILLISECONDS
47-
);
48-
return future;
20+
Executors.newThreadPerTaskExecutor(Thread.ofVirtual().factory()));
4921
}
5022

51-
private CompletableFuture<EasyCodefResponse> executeRequest(
23+
public CompletableFuture<EasyCodefResponse> executeRequest(
5224
EasyCodefRequest request,
5325
SingleReqFacade facade
5426
) {
@@ -57,9 +29,4 @@ private CompletableFuture<EasyCodefResponse> executeRequest(
5729
virtualThreadExecutor
5830
);
5931
}
60-
61-
@Override
62-
public void close() {
63-
scheduler.shutdown();
64-
}
6532
}

src/main/java/io/codef/api/EasyCodef.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
import io.codef.api.storage.MultipleRequestStorage;
1010
import io.codef.api.storage.SimpleAuthStorage;
1111
import io.codef.api.util.RsaUtil;
12-
import java.security.PublicKey;
13-
import java.util.List;
1412
import org.slf4j.Logger;
1513
import org.slf4j.LoggerFactory;
1614

15+
import java.security.PublicKey;
16+
import java.util.List;
17+
1718
public class EasyCodef {
1819

1920
private static final Logger log = LoggerFactory.getLogger(EasyCodef.class);
@@ -83,7 +84,7 @@ private void logInitializeSuccessfully() {
8384
| `---.\\ '-' |.-' `) \\ ' ' '--'\\' '-' '\\ `-' \\ --.| .-'\s
8485
`------' `--`--'`----'.-' / `-----' `---' `---' `----'`--' \s
8586
86-
> EasyCodef v2.0.0-beta-004 Successfully Initialized! Hello worlds!
87+
> EasyCodef v2.0.0-beta-005 Successfully Initialized! Hello worlds!
8788
"""
8889
);
8990
}
Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,83 @@
11
package io.codef.api;
22

3-
import static io.codef.api.dto.EasyCodefRequest.ACCESS_TOKEN;
4-
import static io.codef.api.dto.EasyCodefResponse.DATA;
5-
import static io.codef.api.dto.EasyCodefResponse.RESULT;
6-
73
import com.alibaba.fastjson2.JSON;
84
import com.alibaba.fastjson2.JSONObject;
5+
import io.codef.api.constants.CodefResponseCode;
96
import io.codef.api.dto.EasyCodefResponse;
107
import io.codef.api.error.CodefError;
118
import io.codef.api.error.CodefException;
9+
import org.apache.hc.core5.http.ClassicHttpResponse;
10+
import org.apache.hc.core5.http.HttpStatus;
11+
import org.apache.hc.core5.http.ParseException;
12+
import org.apache.hc.core5.http.io.entity.EntityUtils;
13+
1214
import java.io.IOException;
1315
import java.net.URLDecoder;
1416
import java.nio.charset.StandardCharsets;
17+
import java.util.List;
1518
import java.util.Optional;
1619
import java.util.function.Function;
17-
import org.apache.hc.core5.http.ClassicHttpResponse;
18-
import org.apache.hc.core5.http.HttpStatus;
19-
import org.apache.hc.core5.http.ParseException;
20-
import org.apache.hc.core5.http.io.entity.EntityUtils;
20+
21+
import static io.codef.api.dto.EasyCodefRequest.ACCESS_TOKEN;
22+
import static io.codef.api.dto.EasyCodefResponse.DATA;
23+
import static io.codef.api.dto.EasyCodefResponse.RESULT;
2124

2225
public class ResponseHandler {
26+
2327
private static final String UTF_8 = StandardCharsets.UTF_8.toString();
2428

29+
public static boolean isSuccessResponse(EasyCodefResponse response) {
30+
return CodefResponseCode.CF_00000.equals(response.code());
31+
}
32+
33+
public static boolean isAddAuthResponse(EasyCodefResponse response) {
34+
return CodefResponseCode.CF_03002.equals(response.code());
35+
}
36+
37+
public static boolean isAddAuthExceedResponse(EasyCodefResponse response) {
38+
return CodefResponseCode.CF_12872.equals(response.code());
39+
}
40+
41+
public static boolean isFailureResponse(EasyCodefResponse response) {
42+
return !isSuccessResponse(response) && !isAddAuthResponse(response);
43+
}
44+
2545
/**
2646
* 토큰 응답 처리
2747
*/
2848
public String handleTokenResponse(ClassicHttpResponse response) throws CodefException {
2949
return handleHttpResponse(
30-
response,
31-
this::parseAccessToken,
32-
CodefError.OAUTH_UNAUTHORIZED,
33-
CodefError.OAUTH_INTERNAL_ERROR,
34-
false
50+
response,
51+
this::parseAccessToken,
52+
CodefError.OAUTH_UNAUTHORIZED,
53+
CodefError.OAUTH_INTERNAL_ERROR,
54+
false
3555
);
3656
}
3757

3858
/**
3959
* 상품 응답 처리
4060
*/
41-
public EasyCodefResponse handleProductResponse(ClassicHttpResponse response) throws CodefException {
61+
public EasyCodefResponse handleProductResponse(ClassicHttpResponse response)
62+
throws CodefException {
4263
return handleHttpResponse(
43-
response,
44-
this::parseProductResponse,
45-
CodefError.CODEF_API_UNAUTHORIZED,
46-
CodefError.CODEF_API_SERVER_ERROR,
47-
true
64+
response,
65+
this::parseProductResponse,
66+
CodefError.CODEF_API_UNAUTHORIZED,
67+
CodefError.CODEF_API_SERVER_ERROR,
68+
true
4869
);
4970
}
5071

5172
/**
5273
* 공통 HTTP 응답 처리 로직
5374
*/
5475
private <T> T handleHttpResponse(
55-
ClassicHttpResponse response,
56-
Function<String, T> parser,
57-
CodefError unauthorizedError,
58-
CodefError defaultError,
59-
boolean requireUrlDecoding
76+
ClassicHttpResponse response,
77+
Function<String, T> parser,
78+
CodefError unauthorizedError,
79+
CodefError defaultError,
80+
boolean requireUrlDecoding
6081
) throws CodefException {
6182
String responseBody = extractResponseBody(response, requireUrlDecoding);
6283

@@ -70,7 +91,8 @@ private <T> T handleHttpResponse(
7091
/**
7192
* HTTP 응답 본문 추출
7293
*/
73-
private String extractResponseBody(ClassicHttpResponse response, boolean requiresDecoding) throws CodefException {
94+
private String extractResponseBody(ClassicHttpResponse response, boolean requiresDecoding)
95+
throws CodefException {
7496
try {
7597
String responseBody = EntityUtils.toString(response.getEntity());
7698
return requiresDecoding ? URLDecoder.decode(responseBody, UTF_8) : responseBody;
@@ -99,17 +121,38 @@ private EasyCodefResponse parseProductResponse(String responseBody) throws Codef
99121
try {
100122
JSONObject jsonResponse = JSON.parseObject(responseBody);
101123

102-
EasyCodefResponse.Result result = Optional.ofNullable(jsonResponse.getJSONObject(RESULT))
124+
EasyCodefResponse.Result result = parseResult(jsonResponse);
125+
Object data = parseData(jsonResponse);
126+
127+
return new EasyCodefResponse(result, data);
128+
} catch (Exception exception) {
129+
throw CodefException.of(CodefError.PARSE_ERROR, exception);
130+
}
131+
}
132+
133+
private EasyCodefResponse.Result parseResult(JSONObject jsonResponse) throws CodefException {
134+
return Optional.ofNullable(jsonResponse.getJSONObject(RESULT))
103135
.map(object -> object.to(EasyCodefResponse.Result.class))
104136
.orElseThrow(() -> CodefException.from(CodefError.PARSE_ERROR));
137+
}
105138

106-
Object data = Optional.ofNullable(jsonResponse.getJSONObject(DATA))
139+
private Object parseData(JSONObject jsonResponse) throws CodefException {
140+
try {
141+
return parseObjectData(jsonResponse);
142+
} catch (Exception e) {
143+
return parseArrayData(jsonResponse);
144+
}
145+
}
146+
147+
private Object parseObjectData(JSONObject jsonResponse) throws CodefException {
148+
return Optional.ofNullable(jsonResponse.getJSONObject(DATA))
107149
.map(obj -> obj.to(Object.class))
108150
.orElseThrow(() -> CodefException.from(CodefError.PARSE_ERROR));
151+
}
109152

110-
return new EasyCodefResponse(result, data);
111-
} catch (Exception e) {
112-
throw CodefException.of(CodefError.PARSE_ERROR, e);
113-
}
153+
private List<?> parseArrayData(JSONObject jsonResponse) throws CodefException {
154+
return Optional.ofNullable(jsonResponse.getJSONArray(DATA))
155+
.map(obj -> obj.to(List.class))
156+
.orElseThrow(() -> CodefException.from(CodefError.PARSE_ERROR));
114157
}
115158
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package io.codef.api;
2+
3+
import com.alibaba.fastjson2.JSON;
4+
import io.codef.api.dto.EasyCodefResponse;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
import java.util.List;
9+
import java.util.Optional;
10+
11+
import static io.codef.api.constants.CodefResponseCode.*;
12+
13+
public class ResponseLogger {
14+
private static final Logger log = LoggerFactory.getLogger(ResponseLogger.class);
15+
16+
private ResponseLogger() {
17+
}
18+
19+
20+
public static void logResponseStatus(EasyCodefResponse response) {
21+
logBasicInfo(response);
22+
23+
switch (response.code()) {
24+
case CF_00000:
25+
logSuccessResponse();
26+
break;
27+
28+
case CF_03002:
29+
logAddAuthRequired(response);
30+
break;
31+
32+
case CF_12872:
33+
logAuthExceeded();
34+
break;
35+
36+
default:
37+
logError(response);
38+
break;
39+
}
40+
}
41+
42+
public static void logStatusSummary(List<EasyCodefResponse> responses) {
43+
long successCount = responses.stream().filter(ResponseHandler::isSuccessResponse).count();
44+
long addAuthCount = responses.stream().filter(ResponseHandler::isAddAuthResponse).count();
45+
long failureCount = responses.stream().filter(ResponseHandler::isFailureResponse).count();
46+
47+
log.info("Total Responses Count = {}\n", responses.size());
48+
logStatus(successCount, addAuthCount, failureCount);
49+
}
50+
51+
private static void logBasicInfo(EasyCodefResponse response) {
52+
log.info("Response Status Code : {}", response.code());
53+
log.info("Transaction Id : {}", response.transactionId());
54+
}
55+
56+
private static void logSuccessResponse() {
57+
log.info("Successfully returned Value from Codef API\n");
58+
}
59+
60+
private static void logAddAuthRequired(EasyCodefResponse response) {
61+
Object data = response.data();
62+
String addAuthMethod = JSON.parseObject(data.toString()).getString("method");
63+
log.warn("Additional authentication required | method : {}\n", addAuthMethod);
64+
}
65+
66+
private static void logAuthExceeded() {
67+
log.error("Retry limit for additional authentication exceeded. "
68+
+ "Please restart the process from the initial request.\n");
69+
}
70+
71+
private static void logError(EasyCodefResponse response) {
72+
log.error("Failed to get proper scrapping response. Check the Error errorMessage And StatusCode");
73+
log.error("> message : {}", response.result().message());
74+
log.error("> extraMessage : {}", response.result().extraMessage());
75+
}
76+
77+
private static void logStatus(
78+
long successCount,
79+
long addAuthCount,
80+
long failureCount
81+
) {
82+
Optional.of(successCount)
83+
.filter(ResponseLogger::isExist)
84+
.ifPresent(count -> log.info("Success Response Status [ {} ] Count : {}", CF_00000, count));
85+
86+
Optional.of(addAuthCount)
87+
.filter(ResponseLogger::isExist)
88+
.ifPresent(count -> log.info("AddAuth Response Status [ {} ] Count : {}", CF_03002, count));
89+
90+
Optional.of(failureCount)
91+
.filter(ResponseLogger::isExist)
92+
.ifPresentOrElse(
93+
count -> log.warn("Failure Response Status [ Else ] Count : {}\n", count),
94+
() -> log.info("No Failure Responses\n")
95+
);
96+
}
97+
98+
private static boolean isExist(Long count) {
99+
return count > 0;
100+
}
101+
}

0 commit comments

Comments
 (0)