Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EDGPATRON-149 Adding new GET endpoint to fetch patron details based on emailId #132

Merged
merged 8 commits into from
Oct 17, 2024
91 changes: 45 additions & 46 deletions ramls/edge-patron.raml
Original file line number Diff line number Diff line change
Expand Up @@ -622,50 +622,49 @@ types:
body:
text/plain:
example: internal server error, contact administrator
/patron-registration-status/{emailId}:
uriParameters:
emailId:
description: The email ID of the patron.
type: string
required: true
get:
description: Get the patron details by email ID
queryParameters:
apikey:
description: "API Key"
type: string
responses:
200:
description: patron information retrieved successfully
body:
application/json:
type: user
example: !include examples/user.json
400:
description: Validation error
body:
application/json:
type: user_error_400
example: !include examples/user_error.json
401:
description: Not authorized to perform requested action
body:
text/plain:
example: unable to get account -- unauthorized
403:
description: Access Denied
body:
text/plain:
example: Access Denied
404:
description: Validation error
body:
application/json:
type: user_error_404
example: !include examples/user_error.json
500:
description: Internal server error, e.g. due to misconfiguration
body:
text/plain:
example: internal server error, contact administrator
/registration-status/{emailId}:
get:
description: Get the patron details by email ID
queryParameters:
apikey:
description: "API Key"
type: string
emailId:
description: The email ID of the patron.
type: string
required: true
responses:
200:
description: patron information retrieved successfully
body:
application/json:
type: user
example: !include examples/user.json
400:
description: Validation error
body:
application/json:
type: user_error_400
example: !include examples/user_error.json
401:
description: Not authorized to perform requested action
body:
text/plain:
example: unable to get account -- unauthorized
403:
description: Access Denied
body:
text/plain:
example: Access Denied
404:
description: Validation error
body:
application/json:
type: user_error_404
example: !include examples/user_error.json
500:
description: Internal server error, e.g. due to misconfiguration
body:
text/plain:
example: internal server error, contact administrator

2 changes: 1 addition & 1 deletion ramls/staging_user.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "object",
"properties": {
"isEmailVerified": {
"description": "A boolean flag that indicates whether the patron has completed email verification. If this value is not provided when creating a new record, it will default to false. However, for Kiosk user registrations, this value should be sent true.",
"description": "A boolean flag that indicates whether the patron has completed email verification. If this value is not provided when creating a new record, it will default to false. However, for Kiosk user registrations, this value should be sent false.",
"type": "boolean"
},
"status": {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/folio/edge/patron/MainVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ public Router defineRoutes() {
router.route(HttpMethod.GET, "/patron/account/:patronId/external-patrons")
.handler(patronHandler::handleGetExtPatronsAccounts);

router.route(HttpMethod.GET, "/patron/account/:patronId/by-email/:emailId")
.handler(patronHandler::handleGetExtPatronAccountByEmail);

router.route(HttpMethod.PUT, "/patron/account/:patronId/by-email/:emailId")
.handler(patronHandler::handlePutExtPatronAccountByEmail);

Expand All @@ -84,6 +81,9 @@ public Router defineRoutes() {
router.route(HttpMethod.POST, "/patron/account/:patronId/hold/:holdId/cancel")
.handler(patronHandler::handleCancelHold);

router.route(HttpMethod.GET, "/patron/registration-status")
.handler(patronHandler::handleGetPatronRegistrationStatus);

return router;
}
}
86 changes: 76 additions & 10 deletions src/main/java/org/folio/edge/patron/PatronHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.folio.edge.patron.Constants.PARAM_SORT_BY;
import static org.folio.edge.patron.model.HoldCancellationValidator.validateCancelHoldRequest;

import com.amazonaws.util.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpHeaders;
Expand All @@ -33,6 +34,7 @@
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -42,6 +44,7 @@
import org.apache.logging.log4j.Logger;
import org.folio.edge.core.Handler;
import org.folio.edge.core.security.SecureStore;
import org.folio.edge.core.utils.Mappers;
import org.folio.edge.core.utils.OkapiClient;
import org.folio.edge.core.utils.OkapiClientFactory;
import org.folio.edge.patron.model.error.Error;
Expand Down Expand Up @@ -139,16 +142,6 @@ public void handleRenew(RoutingContext ctx) {

}

public void handleGetExtPatronAccountByEmail(RoutingContext ctx) {
handleCommon(ctx,
new String[] { PARAM_PATRON_ID, PARAM_EMAIL_ID },
new String[] {},
(client, params) -> ((PatronOkapiClient) client).getExtPatronAccountByEmail(
params.get(PARAM_EMAIL_ID),
resp -> handleProxyResponse(ctx, resp),
t -> handleProxyException(ctx, t)));
}

public void handlePutExtPatronAccountByEmail(RoutingContext ctx) {
if (ctx.body().asJsonObject() == null) {
badRequest(ctx, MSG_EXTERNAL_NOBODY);
Expand Down Expand Up @@ -260,6 +253,26 @@ public void handleGetAllowedServicePoints(RoutingContext ctx) {
t -> handleProxyException(ctx, t)));
}

public void handleGetPatronRegistrationStatus(RoutingContext ctx) {
logger.debug("handleGetPatronRegistrationStatus:: Fetching patron registration");
String emailId = ctx.request().getParam(PARAM_EMAIL_ID);
if(StringUtils.isNullOrEmpty(emailId)) {
logger.warn("handleGetPatronRegistrationStatus:: Missing or empty emailId");
ctx.response()
.setStatusCode(400)
.putHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON)
.end(getErrorMsg("EMAIL_NOT_PROVIDED", "emailId is missing in the request"));
return;
}
super.handleCommon(ctx, new String[]{}, new String[]{}, (client, params) -> {
String alternateTenantId = ctx.request().getParam("alternateTenantId", client.tenant);
final PatronOkapiClient patronClient = new PatronOkapiClient(client, alternateTenantId);
patronClient.getPatronRegistrationStatus(emailId,
resp -> handleRegistrationStatusResponse(ctx, resp),
t -> handleProxyException(ctx, t));
});
}

@Override
protected void invalidApiKey(RoutingContext ctx, String msg) {
accessDenied(ctx, msg);
Expand Down Expand Up @@ -332,6 +345,32 @@ protected void handleProxyResponse(RoutingContext ctx, HttpResponse<Buffer> resp
}
}

protected void handleRegistrationStatusResponse(RoutingContext ctx, HttpResponse<Buffer> resp) {
HttpServerResponse serverResponse = ctx.response();

int statusCode = resp.statusCode();
serverResponse.setStatusCode(statusCode);

String respBody = resp.bodyAsString();
if (logger.isDebugEnabled() ) {
logger.debug("handleRegistrationStatusResponse:: response {} ", respBody);
}

String contentType = resp.getHeader(HttpHeaders.CONTENT_TYPE.toString());

if (resp.statusCode() < 400 && Objects.nonNull(respBody)){
setContentType(serverResponse, contentType);
serverResponse.end(respBody); //not an error case, pass on the response body as received
}
else {
String errorMsg = (statusCode == 404 || statusCode == 400)
? getFormattedErrorMsg(statusCode, respBody)
: getStructuredErrorMessage(statusCode, respBody);
setContentType(serverResponse, APPLICATION_JSON);
serverResponse.end(errorMsg);
}
}

@Override
protected void handleProxyException(RoutingContext ctx, Throwable t) {
logger.error("Exception retrieving data from mod-patron:", t);
Expand Down Expand Up @@ -435,6 +474,33 @@ private String get422ErrorMsg(int statusCode, String respBody){
return errorMessage;
}

private String getFormattedErrorMsg(int statusCode, String respBody) {
logger.debug("getFormattedErrorMsg:: respBody {}", respBody);
String errorMessage = "";
try {
var errors = Json.decodeValue(respBody, Errors.class).getErrors();
if (errors != null && !errors.isEmpty()) {
var error = errors.get(0);
return getErrorMsg(error.getCode(), error.getMessage());
}
} catch (Exception ex) {
logger.warn(ex.getMessage());
errorMessage = getStructuredErrorMessage(statusCode, respBody);
}
return errorMessage;
}

private String getErrorMsg(String code, String errorMessage) {
Map<String, String> errorMap = new HashMap<>();
errorMap.put("errorMessage", errorMessage);
errorMap.put("code", code);
try {
return Mappers.jsonMapper.writeValueAsString(errorMap);
} catch (JsonProcessingException e) {
return getStructuredErrorMessage(500, "A problem encountered when extracting error message");
}
}

private String getErrorMessage(int statusCode, String respBody){

if (statusCode == 422)
Expand Down
18 changes: 7 additions & 11 deletions src/main/java/org/folio/edge/patron/utils/PatronOkapiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,6 @@ public void getAccount(String patronId, boolean includeLoans, boolean includeCha
exceptionHandler);
}

public void getExtPatronAccountByEmail(String email, Handler<HttpResponse<Buffer>> responseHandler,
Handler<Throwable> exceptionHandler) {
String url = String.format("%s/patron/account/by-email/%s", okapiURL, email);
get(
url,
tenant,
null,
responseHandler,
exceptionHandler);
}

public void getExtPatronAccounts(boolean expired, Handler<HttpResponse<Buffer>> responseHandler,
Handler<Throwable> exceptionHandler) {
String url = String.format("%s/patron/account?expired=%s", okapiURL, expired);
Expand Down Expand Up @@ -219,6 +208,13 @@ public void placeInstanceHold(String patronId, String instanceId, String request
exceptionHandler);
}

public void getPatronRegistrationStatus(String emailId,
Handler<HttpResponse<Buffer>> responseHandler, Handler<Throwable> exceptionHandler) {

get(String.format("%s/patron/registration-status/%s", okapiURL,
emailId), tenant, null, responseHandler, exceptionHandler);
}

private Hold createCancellationHoldRequest(JsonObject cancellationRequest, JsonObject baseRequest, String patronId) {
return Hold.builder()
.cancellationReasonId(cancellationRequest.getString(FIELD_CANCELLATION_REASON_ID))
Expand Down
Loading
Loading