Skip to content

Commit

Permalink
Merge pull request #83 from zucisystems-dev/enhancement/outbound-deli…
Browse files Browse the repository at this point in the history
…very-notify

Enhancement/outbound delivery notify
  • Loading branch information
Manikandan-Thangaraj-ZS0321 authored Feb 24, 2024
2 parents cd5f647 + 769e57c commit 01fcda0
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 71 deletions.
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

0 comments on commit 01fcda0

Please sign in to comment.