Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<p align="center">
<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>
<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>
<a href="https://central.sonatype.com/artifact/io.codef.api/easycodef-java-v2/2.0.0-beta-002"><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>
<a href="https://central.sonatype.com/artifact/io.codef.api/easycodef-java-v2/2.0.0-beta-003"><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>
</p>

<br><br>
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {


group = "io.codef.api"
version = "2.0.0-beta-002"
version = "2.0.0-beta-003"

signing {
useInMemoryPgpKeys(
Expand Down
72 changes: 53 additions & 19 deletions src/main/java/io/codef/api/EasyCodef.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,44 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EasyCodef {

private static final long REQUEST_DELAY_MS = 700L;
private static final Logger log = LoggerFactory.getLogger(EasyCodef.class);

private final SimpleAuthStorage simpleAuthStorage;
private final MultipleRequestStorage multipleRequestStorage;
private final PublicKey publicKey;
private final CodefClientType clientType;
private final EasyCodefToken easyCodefToken;

protected EasyCodef(
EasyCodefBuilder builder,
EasyCodefToken easyCodefToken
) {
protected EasyCodef(EasyCodefBuilder builder) {

this.publicKey = RsaUtil.generatePublicKey(builder.getPublicKey());
log.info("EasyCodef RSA public key successfully initialized.");

this.clientType = builder.getClientType();
this.easyCodefToken = easyCodefToken;
log.info("Your Codef clientType {} is successfully initialized.", clientType);

this.easyCodefToken = new EasyCodefToken(builder);
this.simpleAuthStorage = new SimpleAuthStorage();
this.multipleRequestStorage = new MultipleRequestStorage();

log.info("==================================================");
log.info("Your EasyCodef Entity is successfully initialized!");
log.info("==================================================\n");
}

private List<EasyCodefResponse> returnFirstErrorResponse(
EasyCodefResponse firstResponse,
String transactionId
) {
log.info("Result Status Code : {}", firstResponse.code());

return List.of(firstResponse);
}

/**
Expand All @@ -53,10 +71,10 @@ public EasyCodefResponse requestProduct(EasyCodefRequest request) throws CodefEx
String requestUrl = buildRequestUrl(request);
EasyCodefToken validToken = easyCodefToken.validateAndRefreshToken();

EasyCodefResponse response = EasyCodefConnector.requestProduct(request, validToken,
requestUrl);
simpleAuthStorage.storeIfRequired(request, response, requestUrl);
EasyCodefResponse response =
EasyCodefConnector.requestProduct(request, validToken, requestUrl);

simpleAuthStorage.storeIfRequired(request, response, requestUrl);
return response;
}

Expand All @@ -66,9 +84,11 @@ public EasyCodefResponse requestProduct(EasyCodefRequest request) throws CodefEx
public EasyCodefResponse requestMultipleProduct(List<EasyCodefRequest> requests)
throws CodefException {
validateRequests(requests);
easyCodefToken.validateAndRefreshToken();
assignSsoId(requests, UUID.randomUUID().toString());

var executors = createExecutors();

try {
return processMultipleRequests(requests, executors);
} finally {
Expand All @@ -82,6 +102,7 @@ public EasyCodefResponse requestMultipleProduct(List<EasyCodefRequest> requests)
public EasyCodefResponse requestSimpleAuthCertification(String transactionId)
throws CodefException {
CodefSimpleAuth simpleAuth = simpleAuthStorage.get(transactionId);
easyCodefToken.validateAndRefreshToken();

EasyCodefRequest enrichedRequest = enrichRequestWithTwoWayInfo(simpleAuth);
EasyCodefResponse response = executeSimpleAuthRequest(enrichedRequest,
Expand All @@ -94,6 +115,8 @@ public EasyCodefResponse requestSimpleAuthCertification(String transactionId)
transactionId
);

log.info("Result Status Code : {}", response.code());

return response;
}

Expand All @@ -103,10 +126,11 @@ public EasyCodefResponse requestSimpleAuthCertification(String transactionId)
public List<EasyCodefResponse> requestMultipleSimpleAuthCertification(String transactionId)
throws CodefException {
CodefSimpleAuth simpleAuth = simpleAuthStorage.get(transactionId);
easyCodefToken.validateAndRefreshToken();

EasyCodefRequest enrichedRequest = enrichRequestWithTwoWayInfo(simpleAuth);
EasyCodefResponse firstResponse = executeSimpleAuthRequest(enrichedRequest,
simpleAuth.requestUrl());
EasyCodefResponse firstResponse =
executeSimpleAuthRequest(enrichedRequest, simpleAuth.requestUrl());

simpleAuthStorage.updateIfRequired(
simpleAuth.requestUrl(),
Expand All @@ -116,8 +140,8 @@ public List<EasyCodefResponse> requestMultipleSimpleAuthCertification(String tra
);

return isSuccessful(firstResponse)
? combineWithRemainingResponses(firstResponse, transactionId)
: List.of(firstResponse);
? combineWithRemainingResponses(firstResponse, transactionId) // Case CF-00000
: returnFirstErrorResponse(firstResponse, transactionId);
}

// Private helper methods
Expand Down Expand Up @@ -153,10 +177,20 @@ private List<EasyCodefResponse> combineWithRemainingResponses(
EasyCodefResponse firstResponse,
String transactionId
) throws CodefException {
List<EasyCodefResponse> remainingResponses = multipleRequestStorage.getRemainingResponses(
transactionId);

log.info("remainingResponses called By transactionId `{}`", transactionId);

List<EasyCodefResponse> remainingResponses =
multipleRequestStorage.getRemainingResponses(transactionId);

log.info("Await Response Count = {}", remainingResponses.size());
List<EasyCodefResponse> allResponses = new ArrayList<>(remainingResponses);
allResponses.add(firstResponse);

log.info("Total Response Count = {}", allResponses.size());
log.info("Result Status Codes : {}",
allResponses.stream().map(EasyCodefResponse::code).toList());

return allResponses;
}

Expand All @@ -180,12 +214,12 @@ private EasyCodefResponse processMultipleRequests(
List<EasyCodefRequest> requests,
CodefExecutors codefExecutors
) throws CodefException {
List<CompletableFuture<EasyCodefResponse>> futures = scheduleRequests(requests,
codefExecutors);
List<CompletableFuture<EasyCodefResponse>> futures =
scheduleRequests(requests, codefExecutors);

CompletableFuture<EasyCodefResponse> firstCompleted = CompletableFuture.anyOf(
futures.toArray(new CompletableFuture[0])
).thenApply(result -> (EasyCodefResponse) result);
CompletableFuture<EasyCodefResponse> firstCompleted =
CompletableFuture.anyOf(futures.toArray(new CompletableFuture[0]))
.thenApply(result -> (EasyCodefResponse) result);

EasyCodefResponse result = firstCompleted.join();
multipleRequestStorage.store(result.transactionId(), futures);
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/io/codef/api/EasyCodefBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ public EasyCodefBuilder clientType(CodefClientType clientType) {

public EasyCodef build() {
validatePropertyArguments();
EasyCodefToken easyCodefToken = new EasyCodefToken(this);

return new EasyCodef(this, easyCodefToken);
return new EasyCodef(this);
}

private void validatePropertyArguments() {
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/io/codef/api/EasyCodefConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@
import io.codef.api.dto.EasyCodefResponse;
import io.codef.api.error.CodefError;
import io.codef.api.error.CodefException;
import io.codef.api.logger.JsonLogUtil;
import io.codef.api.util.HttpClientUtil;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EasyCodefConnector {

private static final Logger log = LoggerFactory.getLogger(EasyCodefConnector.class);
private static final ResponseHandler responseHandler = new ResponseHandler();

private EasyCodefConnector() {
Expand Down Expand Up @@ -74,7 +78,19 @@ private static <T> T executeRequest(
ResponseProcessor<T> processor
) {
try (var httpClient = HttpClientUtil.createClient()) {
return httpClient.execute(request, processor::process);
log.info("[{}] Codef API Request", request.hashCode());
log.info("> Request Host : {}://{}", request.getScheme(),
request.getAuthority().toString());
log.info("> Requset Uri : {}\n", request.getRequestUri());

return httpClient.execute(request, response -> {
log.info("[{}] Codef API Response", request.hashCode());
log.info("> Response Status : {}", response.getCode());
T result = processor.process(response);
log.info("> Response →\n{}\n", JsonLogUtil.toPrettyJson(result));

return result;
});
} catch (IOException exception) {
throw CodefException.of(CodefError.IO_ERROR, exception);
}
Expand Down
31 changes: 29 additions & 2 deletions src/main/java/io/codef/api/EasyCodefToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,67 @@
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EasyCodefToken {

private static final Logger log = LoggerFactory.getLogger(EasyCodefToken.class);

private final String oauthToken;
private String accessToken;
private LocalDateTime expiresAt;

protected EasyCodefToken(EasyCodefBuilder builder) {

final int VALIDITY_PERIOD_DAYS = 7;
final String DELIMITER = ":";

String combinedKey = String.join(DELIMITER, builder.getClientId().toString(),
builder.getClientSecret().toString());

this.oauthToken = Base64.getEncoder().encodeToString(combinedKey.getBytes());
log.info("Codef OAuth Token : {}", oauthToken);
log.info("Codef OAuth Token successfully initialized.\n");

this.accessToken = EasyCodefConnector.requestToken(oauthToken);
log.info("Codef API AccessToken : {}", accessToken);

this.expiresAt = LocalDateTime.now().plusDays(VALIDITY_PERIOD_DAYS);

log.info(
"Codef API AccessToken expiry at {} but, EasyCodef will handle automatic renewal",
expiresAt
);
log.info("Codef API AccessToken successfully initialized.\n");
}

public EasyCodefToken validateAndRefreshToken() {
Optional.of(expiresAt)
.filter(this::isTokenExpiringSoon)
Optional.of(expiresAt).filter(this::isTokenExpiringSoon)
.ifPresent(expiry -> refreshToken());

return this;
}

private boolean isTokenExpiringSoon(LocalDateTime expiry) {
return expiry.isBefore(LocalDateTime.now().plusHours(24));

}

private void refreshToken() {
log.info(
"Codef API AccessToken expiry at {} so EasyCodef refresh token",
expiresAt
);
this.accessToken = EasyCodefConnector.requestToken(oauthToken);
log.info("Codef API AccessToken : {}", accessToken);

this.expiresAt = LocalDateTime.now().plusDays(7);

log.info(
"AccessToken Refresh completed. Now, Codef accessToken expiry at {}.",
expiresAt
);
}

public String getAccessToken() {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/io/codef/api/constants/CodefReferenceUrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ public enum CodefReferenceUrl {
public String getUrl() {
return String.format(MESSAGE_FORMAT, url);
}

public String getRawUrl() {
return url;
}
}
12 changes: 11 additions & 1 deletion src/main/java/io/codef/api/dto/EasyCodefRequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EasyCodefRequestBuilder {

private static final Logger log = LoggerFactory.getLogger(EasyCodefRequestBuilder.class);

private final HashMap<String, Object> generalRequestBody;
private final HashMap<String, String> secureRequestBody;
private String path;
Expand Down Expand Up @@ -80,7 +84,13 @@ public EasyCodefRequest build() {
this.requestBody(EASY_CODEF_JAVA_FLAG, true);
this.generalRequestBody.putAll(secureRequestBody);

return new EasyCodefRequest(path, generalRequestBody);
EasyCodefRequest easyCodefRequest = new EasyCodefRequest(path, generalRequestBody);

// log.info("[EasyCodef] request object has been successfully built [ {} ]");
// log.info(">> path = {}", path);
// log.info(">> requestBody = {}", generalRequestBody);

return easyCodefRequest;
}

private void encryptSecureRequestBody() {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/io/codef/api/error/CodefError.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,12 @@ public enum CodefError {
public String getMessage() {
return String.format(MESSAGE_FORMAT, message, referenceUrl.getUrl());
}

public String getRawMessage() {
return message;
}

public CodefReferenceUrl getReferenceUrl() {
return referenceUrl;
}
}
12 changes: 12 additions & 0 deletions src/main/java/io/codef/api/error/CodefException.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.codef.api.error;

import java.io.Serial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CodefException extends RuntimeException {

@Serial
private static final long serialVersionUID = 1L;

private static final Logger log = LoggerFactory.getLogger(CodefException.class);
private static final String LOG_WITH_CAUSE_FORMAT = "%s\n→ %s\n\n";

private final CodefError codefError;
Expand All @@ -21,18 +24,27 @@ private CodefException(CodefError codefError, Exception exception) {
exception
);
this.codefError = codefError;

log.error(codefError.getMessage());
log.error(exception.getMessage());
}

private CodefException(
CodefError codefError,
String extraMessage
) {
super(codefError.getMessage() + '\n' + extraMessage);
log.error(codefError.getMessage());
log.error(extraMessage);
this.codefError = codefError;
}

private CodefException(CodefError codefError) {
super(codefError.getMessage() + '\n');

log.error("{}", codefError.getRawMessage());
log.error("{}", codefError.getReferenceUrl().getRawUrl());

this.codefError = codefError;
}

Expand Down
Loading