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

Enhancement/outbound delivery notify #83

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
121 changes: 60 additions & 61 deletions src/main/java/in/handyman/raven/lib/OutboundDeliveryNotifyAction.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
package in.handyman.raven.lib;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import in.handyman.raven.exception.HandymanException;
import in.handyman.raven.lambda.access.ResourceAccess;
import in.handyman.raven.lambda.action.ActionExecution;
import in.handyman.raven.lambda.action.IActionExecution;
import in.handyman.raven.lambda.doa.audit.ActionExecutionAudit;
import in.handyman.raven.lib.agadia.outbound.delivery.adapters.OutboundAdapter;
import in.handyman.raven.lib.agadia.outbound.delivery.adapters.OutboundAdapterProduct;
import in.handyman.raven.lib.agadia.outbound.delivery.entity.TableInputQuerySet;
import in.handyman.raven.lib.model.OutboundDeliveryNotify;
import in.handyman.raven.util.InstanceUtil;
import in.handyman.raven.util.CommonQueryUtil;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.pdfbox.util.Hex;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.result.ResultIterable;
import org.jdbi.v3.core.statement.Query;
import org.slf4j.Logger;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
* Auto Generated By Raven
Expand All @@ -40,6 +41,9 @@ public class OutboundDeliveryNotifyAction implements IActionExecution {
String deliveryNotifyUrl;
String appId;
String appKeyId;
private final OutboundAdapter outboundAdapter;
private final OutboundAdapterProduct outboundAdapterProduct;
private final ObjectMapper objectMapper = new ObjectMapper();

public OutboundDeliveryNotifyAction(final ActionExecutionAudit action, final Logger log,
final Object outboundDeliveryNotify) {
Expand All @@ -49,71 +53,66 @@ public OutboundDeliveryNotifyAction(final ActionExecutionAudit action, final Log
this.appId = action.getContext().get("agadia.appId");
this.appKeyId = action.getContext().get("agadia.appKeyId");
this.deliveryNotifyUrl = action.getContext().get("doc.delivery.notify.url");
this.outboundAdapter = new OutboundAdapter(log, objectMapper, action);
this.outboundAdapterProduct = new OutboundAdapterProduct(log, objectMapper, action);
this.aMarker = MarkerFactory.getMarker(" OutboundDeliveryNotify:" + this.outboundDeliveryNotify.getName());
}

@Override
public void execute() throws Exception {
try {
log.info(aMarker, "Outbound Delivery Notification Action has been started {}", outboundDeliveryNotify);
final OkHttpClient httpclient = InstanceUtil.createOkHttpClient();
final ObjectNode objectNode = MAPPER.createObjectNode();
String agadiaSecretKey = action.getContext().get("agadia.secretKey");
objectNode.put("documentId", outboundDeliveryNotify.getDocumentId());
objectNode.put("inticsZipUri", outboundDeliveryNotify.getInticsZipUri());
objectNode.put("checksum", outboundDeliveryNotify.getZipChecksum());
String signature = getSignature(MAPPER.writeValueAsString(objectNode), agadiaSecretKey);

RequestBody requestBody = RequestBody.create(objectNode.toString(), MediaTypeJSON);
Request request = new Request.Builder()
.url(deliveryNotifyUrl)
.addHeader("x-hmac-signature", signature)
.post(requestBody)
.build();

log.info(aMarker, "Request for document {} is {}", outboundDeliveryNotify.getDocumentId(), request);
try (Response response = httpclient.newCall(request).execute()) {
String responseBody = Objects.requireNonNull(response.body()).string();
log.info(aMarker, "Response body for document {} is {}", outboundDeliveryNotify.getDocumentId(), responseBody);
if (response.isSuccessful()) {
log.info(aMarker, "Sent response for the document {} for Outbound Delivery Notification Action", outboundDeliveryNotify.getDocumentId());
} else {
log.error(aMarker, "Error in response for Outbound Delivery Notification Action {}", responseBody);
throw new HandymanException(responseBody);
}
} catch (Exception exception) {
log.error(aMarker, "Error occurred for document id {} for Outbound Delivery Notification Action", outboundDeliveryNotify.getDocumentId(), exception);
throw new HandymanException("Error occurred for document for Outbound Delivery Notification Action", exception, action);
}
log.info(aMarker, "Outbound Delivery Notification Action has been completed {}", outboundDeliveryNotify);

final Jdbi jdbi = ResourceAccess.rdbmsJDBIConn(outboundDeliveryNotify.getResourceConn());
final List<TableInputQuerySet> tableInfos = new ArrayList<>();

jdbi.useTransaction(handle -> {
final List<String> formattedQuery = CommonQueryUtil.getFormattedQuery(outboundDeliveryNotify.getQuerySet());
AtomicInteger i = new AtomicInteger(0);
formattedQuery.forEach(sqlToExecute -> {
log.info(aMarker, "executing query {} from index {}", sqlToExecute, i.getAndIncrement());
Query query = handle.createQuery(sqlToExecute);
ResultIterable<TableInputQuerySet> resultIterable = query.mapToBean(TableInputQuerySet.class);
List<TableInputQuerySet> detailList = resultIterable.stream().collect(Collectors.toList());
tableInfos.addAll(detailList);
log.info(aMarker, "executed query from index {}", i.get());
});
});


tableInfos.forEach(tableInputQuerySet -> {

String response = doOutboundApiCall(tableInputQuerySet.getOutboundCondition(), tableInputQuerySet);
log.info("Response {} for Outbound Delivery Notification Action", response);


});

} catch (Exception ex) {
log.error(aMarker, "Error in execute method for Outbound Delivery Notification Action", ex);
throw new HandymanException("Error in execute method for Outbound Delivery Notification Action", ex, action);

}
}

private String getSignature(String objectNode, String secretKey) {
log.info("Initialization for Signature Generation");
byte[] payloadFormatted = objectNode.getBytes(StandardCharsets.UTF_8);
byte[] res = secretKey.getBytes(StandardCharsets.UTF_8);
String signature = null;
try {
String algorithm = "HmacSHA256";
Mac sha256Hmac = Mac.getInstance(algorithm);
SecretKeySpec secretKeySpec = new SecretKeySpec(res, algorithm);
sha256Hmac.init(secretKeySpec);
byte[] hmacBytes = sha256Hmac.doFinal(payloadFormatted);
signature = Hex.getString(hmacBytes).toLowerCase();
log.info("Generated Signature for object:" + objectNode + " -- " + signature);
} catch (Throwable e) {
log.error("Error Signature creation: " + e.getMessage());
}
return signature;
}

@Override
public boolean executeIf() throws Exception {
return outboundDeliveryNotify.getCondition();
}

public String doOutboundApiCall(final String outboundCondition, TableInputQuerySet tableInputQuerySet) {
String response = null;
switch (outboundCondition) {
case "Agadia":
response = this.outboundAdapter.requestApiCaller(tableInputQuerySet);
break;
case "Product":
response = this.outboundAdapterProduct.requestApiCaller(tableInputQuerySet);
break;

}
return response;

}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package in.handyman.raven.lib.agadia.outbound.delivery.adapters;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import in.handyman.raven.exception.HandymanException;
import in.handyman.raven.lambda.doa.audit.ActionExecutionAudit;
import in.handyman.raven.lib.agadia.outbound.delivery.entity.TableInputQuerySet;
import in.handyman.raven.lib.agadia.outbound.delivery.interfaces.OutboundInterface;
import in.handyman.raven.util.InstanceUtil;
import okhttp3.*;
import org.apache.pdfbox.util.Hex;
import org.slf4j.Logger;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

public class OutboundAdapter implements OutboundInterface {

private final Logger log;
private final ObjectMapper objectMapper;
private static final MediaType MediaTypeJSON = MediaType
.parse("application/json; charset=utf-8");

private final ActionExecutionAudit actionExecutionAudit;

public OutboundAdapter(final Logger log, ObjectMapper objectMapper, ActionExecutionAudit actionExecutionAudit) {
this.log = log;
this.objectMapper = objectMapper;
this.actionExecutionAudit = actionExecutionAudit;
}

@Override
public String requestApiCaller(final TableInputQuerySet tableInputQuerySet) {


String responseBody;
log.info("Outbound Delivery Notification Action has been started for document id - {}", tableInputQuerySet.getDocumentId());
final OkHttpClient httpclient = InstanceUtil.createOkHttpClient();
String agadiaSecretKey = tableInputQuerySet.getAppSecretKey();
ObjectNode objectNode = this.outboundFileOptions(tableInputQuerySet);


String signature;
try {
signature = getSignature(objectMapper.writeValueAsString(objectNode), agadiaSecretKey);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}

RequestBody requestBody = RequestBody.create(objectNode.toString(), MediaTypeJSON);
Request request = new Request.Builder()
.url(tableInputQuerySet.getEndpoint())
.addHeader("x-hmac-signature", signature)
.post(requestBody)
.build();

log.info("Request for document {} is {}", tableInputQuerySet.getDocumentId(), request);
try (Response response = httpclient.newCall(request).execute()) {
responseBody = Objects.requireNonNull(response.body()).string();
log.info("Response body for document {} is {}", tableInputQuerySet.getDocumentId(), responseBody);
if (response.isSuccessful()) {
log.info("Sent response for the document {} for Outbound Delivery Notification Action", tableInputQuerySet.getDocumentId());
} else {
log.error("Error in response for Outbound Delivery Notification Action {}", responseBody);
throw new HandymanException(responseBody);
}
} catch (Exception exception) {
log.error("Error occurred for document id {} for Outbound Delivery Notification Action", tableInputQuerySet.getDocumentId(), exception);
throw new HandymanException("Error occurred for document for Outbound Delivery Notification Action", exception, actionExecutionAudit);
}
log.info("Outbound Delivery Notification Action has been completed {}", tableInputQuerySet);
return responseBody;
}

@Override
public ObjectNode outboundFileOptions(TableInputQuerySet tableInputQuerySet) {
final ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("documentId", tableInputQuerySet.getDocumentId());
objectNode.put("inticsZipUri", tableInputQuerySet.getFileUri());
objectNode.put("checksum", tableInputQuerySet.getZipFileCheckSum());
return objectNode;
}

private String getSignature(String objectNode, String secretKey) {
log.info("Initialization for Signature Generation");
byte[] payloadFormatted = objectNode.getBytes(StandardCharsets.UTF_8);
byte[] res = secretKey.getBytes(StandardCharsets.UTF_8);
String signature = null;
try {
String algorithm = "HmacSHA256";
Mac sha256Hmac = Mac.getInstance(algorithm);
SecretKeySpec secretKeySpec = new SecretKeySpec(res, algorithm);
sha256Hmac.init(secretKeySpec);
byte[] hmacBytes = sha256Hmac.doFinal(payloadFormatted);
signature = Hex.getString(hmacBytes).toLowerCase();
log.info("Generated Signature for object:" + objectNode + " -- " + signature);
} catch (Throwable e) {
log.error("Error Signature creation: " + e.getMessage());
}
return signature;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package in.handyman.raven.lib.agadia.outbound.delivery.adapters;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import in.handyman.raven.exception.HandymanException;
import in.handyman.raven.lambda.doa.audit.ActionExecutionAudit;
import in.handyman.raven.lib.agadia.outbound.delivery.entity.TableInputQuerySet;
import in.handyman.raven.lib.agadia.outbound.delivery.interfaces.OutboundInterface;
import in.handyman.raven.util.InstanceUtil;
import okhttp3.*;
import org.slf4j.Logger;

import java.io.IOException;
import java.time.Clock;
import java.time.LocalDateTime;
import java.util.Objects;

public class OutboundAdapterProduct implements OutboundInterface {

private final Logger log;
private final ObjectMapper objectMapper;
private static final MediaType MediaTypeJSON = MediaType
.parse("application/json; charset=utf-8");

private final ActionExecutionAudit actionExecutionAudit;

public OutboundAdapterProduct(final Logger log, ObjectMapper objectMapper, ActionExecutionAudit actionExecutionAudit) {
this.log = log;
this.objectMapper = objectMapper;
this.actionExecutionAudit = actionExecutionAudit;
}

@Override
public String requestApiCaller(final TableInputQuerySet tableInputQuerySet) {


String responseBody;
log.info("Outbound Delivery Notification Action has been started for document id - {}", tableInputQuerySet.getDocumentId());
final OkHttpClient httpclient = InstanceUtil.createOkHttpClient();
ObjectNode payloadJson = objectMapper.createObjectNode();
final ObjectNode objectNode = outboundFileOptions(tableInputQuerySet);
payloadJson.put("payload", objectNode);
if (objectNode.isObject()) {
payloadJson.put("success", true);
} else {
payloadJson.put("success", false);
}

payloadJson.put("responseTimeStamp", String.valueOf(LocalDateTime.now(Clock.systemDefaultZone())));


RequestBody requestBody = RequestBody.create(payloadJson.toString(), MediaTypeJSON);
Request request = new Request.Builder()
.url(tableInputQuerySet.getEndpoint())
.post(requestBody)
.build();

log.info("Request for document {} is {}", tableInputQuerySet.getDocumentId(), request);
try (Response response = httpclient.newCall(request).execute()) {
responseBody = Objects.requireNonNull(response.body()).string();
log.info("Response body for document {} is {}", tableInputQuerySet.getDocumentId(), responseBody);
if (response.isSuccessful()) {
log.info("Sent response for the document {} for Outbound Delivery Notification Action", tableInputQuerySet.getDocumentId());
} else {
log.error("Error in response for Outbound Delivery Notification Action {}", responseBody);
throw new HandymanException(responseBody);
}
} catch (Exception exception) {
log.error("Error occurred for document id {} for Outbound Delivery Notification Action", tableInputQuerySet.getDocumentId(), exception);
throw new HandymanException("Error occurred for document for Outbound Delivery Notification Action", exception, actionExecutionAudit);
}
log.info("Outbound Delivery Notification Action has been completed {}", tableInputQuerySet);
return responseBody;
}

@Override
public ObjectNode outboundFileOptions(TableInputQuerySet tableInputQuerySet) {

ObjectNode outputJson = objectMapper.createObjectNode();

try {
outputJson = readJsonFileToString(tableInputQuerySet.getOutboundJson());
} catch (IOException e) {
HandymanException handymanException = new HandymanException(e);
HandymanException.insertException("exception in handling the input json file", handymanException, actionExecutionAudit);

}
return outputJson;

}

public static ObjectNode readJsonFileToString(String Outboundjson) throws IOException {
// Read all bytes from the file and convert to string
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(Outboundjson);

if (jsonNode.isObject()) {
return (ObjectNode) jsonNode;
} else {
return objectMapper.createObjectNode();
}
// Read JSON content from file and parse into JsonNode
}


}
Loading