Skip to content
Snippets Groups Projects
Commit cdef60de authored by zidane-itb's avatar zidane-itb
Browse files

add caching for payment history

parent 3f062286
Branches
Tags
No related merge requests found
package com.kms.handler;
import com.kms.handler.helper.SoapFaultHelper;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
public class CacheHandler implements SOAPHandler<SOAPMessageContext> {
private static final JedisPool jedisPool = new JedisPool("localhost", 6379);
private static final int DEFAULT_CACHE_TTL = 300;
@Override
public Set<QName> getHeaders() {
return null;
}
@Override
public boolean handleMessage(SOAPMessageContext context) {
final boolean messageHandled =
(boolean) context.getOrDefault("messageHandled", false);
if (!messageHandled)
return true;
final boolean cacheResponse =
(boolean) context.getOrDefault("cacheResponse", false);
if (cacheResponse) {
final String cacheKey = (String) context.getOrDefault("cacheKey", null);
if (cacheKey == null)
return true;
try (Jedis jedis = jedisPool.getResource()) {
OutputStream responseTextOStream = new ByteArrayOutputStream();
context.getMessage().writeTo(responseTextOStream);
jedis.set(cacheKey, responseTextOStream.toString());
jedis.expire(cacheKey, DEFAULT_CACHE_TTL);
System.out.println("Response cached with key: " + cacheKey);
} catch (SOAPException | IOException ignored) {
}
return true;
}
final boolean returnFromCache =
(boolean) context.getOrDefault("returnFromCache", false);
if (!returnFromCache)
return true;
final String cacheKey = (String) context.getOrDefault("cacheKey", null);
if (cacheKey == null) {
SoapFaultHelper.throwFault("Error", "Unexpected error has happened.");
}
try (Jedis jedis = jedisPool.getResource()) {
String response = jedis.get(cacheKey);
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
soapMessage.getSOAPPart().setContent(new StreamSource(new java.io.StringReader(response)));
context.setMessage(soapMessage);
System.out.println("Return from cache with key: "+cacheKey);
} catch (SOAPException ignored) {
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
@Override
public void close(MessageContext context) {
}
}
......@@ -2,25 +2,32 @@ package com.kms.service;
import com.j256.ormlite.dao.Dao;
import com.kms.dto.EmailReq;
import com.kms.dto.PaymentHistoryResp;
import com.kms.dto.payment.PaymentHistoryResp;
import com.kms.model.Payment;
import com.kms.service.helper.PaymentHistoryCacheHelper;
import com.kms.util.PdfUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import lombok.RequiredArgsConstructor;
import javax.annotation.Resource;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import java.io.IOException;
import java.io.StringWriter;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@WebService
......@@ -28,6 +35,9 @@ import java.util.stream.Collectors;
@HandlerChain(file = "handlers.xml")
public class PaymentHistoryService {
@Resource
private WebServiceContext context;
private final Dao<Payment,Integer> paymentDao;
private static final Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
......@@ -38,10 +48,24 @@ public class PaymentHistoryService {
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
}
@WebMethod
public List<PaymentHistoryResp> getPaymentHistory(@WebParam(name = "initiatorId") String initiatorId,
@WebParam(name = "sendMail") boolean sendMail,
@WebParam(name = "mailData") EmailReq emailReq) {
MessageContext messageContext = context.getMessageContext();
String cacheKey = PaymentHistoryCacheHelper.checkForHistoryCacheAvailability(initiatorId);
if (!cacheKey.isEmpty()) {
messageContext.put("returnFromCache", true);
messageContext.put("cacheKey", cacheKey);
if (sendMail && emailReq != null)
EmailService.send(emailReq.getRecipient(), emailReq.getCc(),
"Cache: KMS Payment History", "sda");
return null;
}
try {
Payment filter = Payment.builder()
.initiatorId(initiatorId)
......@@ -50,21 +74,35 @@ public class PaymentHistoryService {
List<Payment> payments = paymentDao.queryForMatching(filter);
if (sendMail && emailReq != null) {
EmailService.send(emailReq.getRecipient(), emailReq.getCc(),
"KMS Payment History", formHistoryMailBody(payments));
String html = constructHistoryHtml(payments);
EmailService.send(emailReq.getRecipient(), emailReq.getCc(),
"KMS Payment History", html);
}
cacheKey = PaymentHistoryCacheHelper.formHistoryCacheKey(initiatorId);
messageContext.put("cacheResponse", true);
messageContext.put("cacheKey", cacheKey);
return payments.stream()
.map(el -> new PaymentHistoryResp(el.getPaymentInitTime().toString(), el.getPaymentPaidTime().toString(),
el.getAmount(), el.getDescription()))
.filter(el -> !(el.getPaymentInitTime() == null || el.getPaymentPaidTime() == null))
.map(el -> {
String initTime = Optional.of(el.getPaymentInitTime())
.orElseGet(() -> new Timestamp(0))
.toString(),
paidTime = Optional.of(el.getPaymentPaidTime())
.orElseGet(() -> new Timestamp(0))
.toString();
return new PaymentHistoryResp(initTime, paidTime, el.getAmount(), el.getDescription());
})
.collect(Collectors.toList());
} catch (SQLException | TemplateException | IOException e) {
throw new RuntimeException(e);
return null;
}
}
private String formHistoryMailBody(List<Payment> payments) throws IOException, TemplateException {
private String constructHistoryHtml(List<Payment> payments) throws IOException, TemplateException {
Template template = cfg.getTemplate("history.ftl");
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("payments", payments);
......
package com.kms.service.helper;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class PaymentHistoryCacheHelper {
private static final JedisPool jedisPool = new JedisPool("localhost", 6379);
/**
*
* @param initiatorId initiator id for cache key
* @return cache key, empty if cache is not available
*/
public static String checkForHistoryCacheAvailability(String initiatorId) {
String cacheKey = formHistoryCacheKey(initiatorId);
try (Jedis jedis = jedisPool.getResource()) {
boolean keyExists = jedis.exists(cacheKey);
if (!keyExists)
return "";
long ttlSeconds = jedis.ttl(cacheKey);
if (ttlSeconds < 3) {
jedis.expire(cacheKey, 3);
}
return cacheKey;
}
}
public static String formHistoryCacheKey(String initiatorId) {
System.out.println("CACHE KEY: " + "payment-history:"+initiatorId);
return "payment-history:"+initiatorId;
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment