Ft/hooker/removed cache (#85)

* Set sleep when errors

* Log interruption

* Interrupt

* Removed caches, fixed getting cart position

* Bump version

* Removed unused copy constructor

* Removed hashCode()
This commit is contained in:
Inal Arsanukaev 2019-07-11 18:32:32 +03:00 committed by GitHub
parent 0704c8ace6
commit ee94ab2084
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 22 additions and 322 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>hooker</artifactId> <artifactId>hooker</artifactId>
<version>2.0.30-SNAPSHOT</version> <version>2.0.31-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>hooker</name> <name>hooker</name>

View File

@ -3,13 +3,11 @@ package com.rbkmoney.hooker;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@ServletComponentScan @ServletComponentScan
@SpringBootApplication(scanBasePackages = {"com.rbkmoney.hooker"}) @SpringBootApplication(scanBasePackages = {"com.rbkmoney.hooker"})
@EnableScheduling @EnableScheduling
@EnableCaching
public class HookerApplication { public class HookerApplication {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {

View File

@ -21,7 +21,7 @@ public class DaoConfiguration {
@Bean @Bean
public InvoicingMessageDao messageDao(DataSource dataSource) { public InvoicingMessageDao messageDao(DataSource dataSource) {
return new CacheableInvoicingMessageDaoImpl(dataSource); return new InvoicingMessageDaoImpl(dataSource);
} }
@Bean @Bean
@ -46,7 +46,7 @@ public class DaoConfiguration {
@Bean @Bean
public InvoicingQueueDao invoicingQueueDao(DataSource dataSource) { public InvoicingQueueDao invoicingQueueDao(DataSource dataSource) {
return new CacheableInvoicingQueueDao(dataSource); return new InvoicingQueueDao(dataSource);
} }
@Bean @Bean

View File

@ -1,53 +0,0 @@
package com.rbkmoney.hooker.dao;
import com.rbkmoney.hooker.model.Message;
import com.rbkmoney.hooker.model.Queue;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Created by inalarsanukaev on 23.11.17.
*/
@Component
@RequiredArgsConstructor
public class CacheMng {
private static final String MESSAGES_BY_INVOICE = "messagesByInvoice";
private static final String MESSAGES_BY_IDS = "messagesById";
private static final String QUEUES = "queues";
private final CacheManager cacheMng;
public void putMessage(Message message){
cacheMng.getCache(MESSAGES_BY_IDS).put(message.getId(), message);
}
public void putMessage(String id, Message message){
cacheMng.getCache(MESSAGES_BY_INVOICE).put(id, message);
}
public <T extends Message> T getMessage(String id, Class<T> type) {
return cacheMng.getCache(MESSAGES_BY_INVOICE).get(id, type);
}
public <T extends Message> List<T> getMessages(Collection<Long> ids, Class<T> type) {
Cache cache = cacheMng.getCache(MESSAGES_BY_IDS);
return ids.stream().map(id -> cache.get(id, type)).filter(Objects::nonNull).collect(Collectors.toList());
}
public <T extends Queue> List<T> getQueues(Collection<Long> ids, Class<T> type){
Cache cache = cacheMng.getCache(QUEUES);
return ids.stream().map(id -> cache.get(id, type)).filter(Objects::nonNull).collect(Collectors.toList());
}
public void putQueues(Collection<? extends Queue> queues){
Cache cache = cacheMng.getCache(QUEUES);
queues.forEach(q -> cache.put(q.getId(), q));
}
}

View File

@ -1,81 +0,0 @@
package com.rbkmoney.hooker.dao.impl;
import com.rbkmoney.hooker.dao.CacheMng;
import com.rbkmoney.hooker.dao.DaoException;
import com.rbkmoney.hooker.model.InvoicingMessage;
import org.springframework.beans.factory.annotation.Autowired;
import javax.sql.DataSource;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CacheableInvoicingMessageDaoImpl extends InvoicingMessageDaoImpl {
@Autowired
CacheMng cacheMng;
public CacheableInvoicingMessageDaoImpl(DataSource dataSource) {
super(dataSource);
}
@Override
public void create(InvoicingMessage message) throws DaoException {
super.create(message);
putToCache(message);
}
@Override
public InvoicingMessage getInvoice(String invoiceId) throws DaoException {
InvoicingMessage message = cacheMng.getMessage(invoiceId, InvoicingMessage.class);
if (message != null) {
return message.copy();
}
InvoicingMessage result = super.getInvoice(invoiceId);
putToCache(result);
return result;
}
@Override
public InvoicingMessage getPayment(String invoiceId, String paymentId) throws DaoException {
InvoicingMessage message = cacheMng.getMessage(invoiceId + "_" + paymentId, InvoicingMessage.class);
if (message != null) {
return message.copy();
}
InvoicingMessage result = super.getPayment(invoiceId, paymentId);
putToCache(result);
return result;
}
@Override
public InvoicingMessage getRefund(String invoiceId, String paymentId, String refundId) throws DaoException {
InvoicingMessage message = cacheMng.getMessage(invoiceId + "_" + paymentId + "_" + refundId, InvoicingMessage.class);
if (message != null) {
return message.copy();
}
InvoicingMessage result = super.getRefund(invoiceId, paymentId, refundId);
putToCache(result);
return result;
}
@Override
public List<InvoicingMessage> getBy(Collection<Long> ids) throws DaoException {
List<InvoicingMessage> messages = cacheMng.getMessages(ids, InvoicingMessage.class);
if (messages.size() == ids.size()) {
return messages;
}
Set<Long> cacheIds = new HashSet<>(ids);
messages.forEach(m -> cacheIds.remove(m.getId()));
List<InvoicingMessage> messagesFromDb = super.getBy(cacheIds);
messagesFromDb.forEach(this::putToCache);
messages.addAll(messagesFromDb);
return messages;
}
private void putToCache(InvoicingMessage message){
if (message != null && message.getId() != null) {
cacheMng.putMessage(message);
cacheMng.putMessage(message.getInvoice().getId() + (message.isPayment() ? "_" + message.getPayment().getId() : "") + (message.isRefund() ? "_" + message.getPayment().getId() + "_" + message.getRefund().getId() : ""), message);
}
}
}

View File

@ -1,34 +0,0 @@
package com.rbkmoney.hooker.dao.impl;
import com.rbkmoney.hooker.dao.CacheMng;
import com.rbkmoney.hooker.model.InvoicingQueue;
import org.springframework.beans.factory.annotation.Autowired;
import javax.sql.DataSource;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CacheableInvoicingQueueDao extends InvoicingQueueDao {
@Autowired
CacheMng cacheMng;
public CacheableInvoicingQueueDao(DataSource dataSource) {
super(dataSource);
}
@Override
public List<InvoicingQueue> getWithPolicies(Collection<Long> ids) {
List<InvoicingQueue> queues = cacheMng.getQueues(ids, InvoicingQueue.class);
if (queues.size() == ids.size()) {
return queues;
}
Set<Long> cacheIds = new HashSet<>(ids);
queues.forEach(h -> cacheIds.remove(h.getId()));
List<InvoicingQueue> queuesFromDb = super.getWithPolicies(cacheIds);
cacheMng.putQueues(queuesFromDb);
queues.addAll(queuesFromDb);
return queues;
}
}

View File

@ -1,6 +1,5 @@
package com.rbkmoney.hooker.dao.impl; package com.rbkmoney.hooker.dao.impl;
import com.rbkmoney.hooker.dao.CacheMng;
import com.rbkmoney.hooker.dao.DaoException; import com.rbkmoney.hooker.dao.DaoException;
import com.rbkmoney.hooker.dao.InvoicingMessageDao; import com.rbkmoney.hooker.dao.InvoicingMessageDao;
import com.rbkmoney.hooker.model.Invoice; import com.rbkmoney.hooker.model.Invoice;
@ -30,9 +29,6 @@ import static com.rbkmoney.hooker.utils.PaymentToolUtils.getPaymentToolDetails;
@Slf4j @Slf4j
public class InvoicingMessageDaoImpl extends NamedParameterJdbcDaoSupport implements InvoicingMessageDao { public class InvoicingMessageDaoImpl extends NamedParameterJdbcDaoSupport implements InvoicingMessageDao {
@Autowired
CacheMng cacheMng;
@Autowired @Autowired
InvoicingQueueDao queueDao; InvoicingQueueDao queueDao;
@ -264,9 +260,7 @@ public class InvoicingMessageDaoImpl extends NamedParameterJdbcDaoSupport implem
.addValue(TYPE, type); .addValue(TYPE, type);
try { try {
result = getNamedParameterJdbcTemplate().queryForObject(sql, params, messageRowMapper); result = getNamedParameterJdbcTemplate().queryForObject(sql, params, messageRowMapper);
final String sqlCarts = "SELECT * FROM hook.cart_position WHERE message_id =:message_id"; List<InvoiceCartPosition> cart = getInvoiceCartPositions(result.getId());
MapSqlParameterSource paramsCarts = new MapSqlParameterSource("message_id", result.getId());
List<InvoiceCartPosition> cart = getNamedParameterJdbcTemplate().query(sqlCarts, paramsCarts, cartPositionRowMapper);
if (!cart.isEmpty()) { if (!cart.isEmpty()) {
result.getInvoice().setCart(cart); result.getInvoice().setCart(cart);
} }
@ -278,6 +272,12 @@ public class InvoicingMessageDaoImpl extends NamedParameterJdbcDaoSupport implem
return result; return result;
} }
private List<InvoiceCartPosition> getInvoiceCartPositions(Long messageId) {
final String sqlCarts = "SELECT * FROM hook.cart_position WHERE message_id =:message_id";
MapSqlParameterSource paramsCarts = new MapSqlParameterSource("message_id", messageId);
return getNamedParameterJdbcTemplate().query(sqlCarts, paramsCarts, cartPositionRowMapper);
}
private void saveCart(Long messageId, Collection<InvoiceCartPosition> cart) { private void saveCart(Long messageId, Collection<InvoiceCartPosition> cart) {
if (cart == null || cart.isEmpty()) return; if (cart == null || cart.isEmpty()) return;
int size = cart.size(); int size = cart.size();
@ -433,9 +433,15 @@ public class InvoicingMessageDaoImpl extends NamedParameterJdbcDaoSupport implem
final String sql = "SELECT * FROM hook.message WHERE id in (:ids)"; final String sql = "SELECT * FROM hook.message WHERE id in (:ids)";
try { try {
List<InvoicingMessage> messagesFromDb = getNamedParameterJdbcTemplate().query(sql, new MapSqlParameterSource("ids", messageIds), messageRowMapper); List<InvoicingMessage> messagesFromDb = getNamedParameterJdbcTemplate().query(sql, new MapSqlParameterSource("ids", messageIds), messageRowMapper);
messagesFromDb.forEach(m -> {
List<InvoiceCartPosition> positions = getInvoiceCartPositions(m.getId());
if (!positions.isEmpty()) {
m.getInvoice().setCart(positions);
}
});
log.debug("messagesFromDb {}", messagesFromDb); log.debug("messagesFromDb {}", messagesFromDb);
return messagesFromDb; return messagesFromDb;
} catch (NestedRuntimeException e) { } catch (NestedRuntimeException e) {
throw new DaoException("InvoicingMessageDaoImpl.getByIds error", e); throw new DaoException("InvoicingMessageDaoImpl.getByIds error", e);
} }
} }

View File

@ -24,26 +24,6 @@ public class InvoicingMessage extends Message {
private Payment payment; private Payment payment;
private Refund refund; private Refund refund;
public InvoicingMessage(InvoicingMessage other) {
setId(other.getId());
this.eventId = other.eventId;
this.sequenceId = other.sequenceId;
this.changeId = other.changeId;
this.eventTime = other.eventTime;
this.type = other.type;
this.partyId = other.partyId;
this.eventType = other.eventType;
if (other.invoice != null) {
this.invoice = new Invoice(other.invoice);
}
if (other.payment != null) {
this.payment = new Payment(other.payment);
}
if (other.refund != null) {
this.refund = new Refund(other.refund);
}
}
public boolean isInvoice() { public boolean isInvoice() {
return AbstractInvoiceEventHandler.INVOICE.equals(getType()); return AbstractInvoiceEventHandler.INVOICE.equals(getType());
} }
@ -56,16 +36,6 @@ public class InvoicingMessage extends Message {
return AbstractInvoiceEventHandler.REFUND.equals(getType()); return AbstractInvoiceEventHandler.REFUND.equals(getType());
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InvoicingMessage message = (InvoicingMessage) o;
return getId() == message.getId();
}
@Override @Override
public String toString() { public String toString() {
return "InvoicingMessage{" + return "InvoicingMessage{" +
@ -78,13 +48,4 @@ public class InvoicingMessage extends Message {
(isPayment() ? ", paymentStatus=" + payment.getStatus() : "") + (isPayment() ? ", paymentStatus=" + payment.getStatus() : "") +
'}'; '}';
} }
@Override
public int hashCode() {
return (int) (getId() ^ (getId() >>> 32));
}
public InvoicingMessage copy(){
return new InvoicingMessage(this);
}
} }

View File

@ -29,84 +29,4 @@ public class Payment {
private String ip; private String ip;
private String fingerprint; private String fingerprint;
private Payer payer; private Payer payer;
public Payment(Payment other) {
this.id = other.id;
this.createdAt = other.createdAt;
this.status = other.status;
if (other.error != null) {
this.error = new PaymentError();
this.error.setCode(other.error.getCode());
this.error.setMessage(other.error.getMessage());
this.error.setSubError(other.error.getSubError());
}
this.amount = other.amount;
this.currency = other.currency;
this.metadata = other.metadata;
this.paymentToolToken = other.paymentToolToken;
this.paymentSession = other.paymentSession;
this.contactInfo = new PaymentContactInfo(other.contactInfo);
this.ip = other.ip;
this.fingerprint = other.fingerprint;
//TODO copy constructor
if (other.payer instanceof CustomerPayer) {
this.payer = new CustomerPayer()
.customerID(((CustomerPayer) other.payer).getCustomerID());
} else if (other.payer instanceof RecurrentPayer) {
RecurrentPayer otherPayer = (RecurrentPayer) other.payer;
this.payer = new RecurrentPayer()
.contactInfo(new ContactInfo()
.email(otherPayer.getContactInfo().getEmail())
.phoneNumber(otherPayer.getContactInfo().getPhoneNumber()))
.recurrentParentPayment(new PaymentRecurrentParent()
.invoiceID(otherPayer.getRecurrentParentPayment().getInvoiceID())
.paymentID(otherPayer.getRecurrentParentPayment().getPaymentID()));
} else if (other.payer instanceof PaymentResourcePayer) {
PaymentResourcePayer otherPayer = (PaymentResourcePayer) other.payer;
PaymentResourcePayer copyPayer = new PaymentResourcePayer()
.paymentSession(otherPayer.getPaymentSession())
.paymentToolToken(otherPayer.getPaymentToolToken())
.clientInfo(new ClientInfo()
.ip(otherPayer.getClientInfo().getIp())
.fingerprint(otherPayer.getClientInfo().getFingerprint()))
.contactInfo(new ContactInfo()
.email(otherPayer.getContactInfo().getEmail())
.phoneNumber(otherPayer.getContactInfo().getPhoneNumber()));
this.payer = copyPayer;
PaymentToolDetails otherPayerPaymentToolDetails = otherPayer.getPaymentToolDetails();
if (otherPayerPaymentToolDetails instanceof PaymentToolDetailsBankCard) {
PaymentToolDetailsBankCard paymentToolDetails = (PaymentToolDetailsBankCard) otherPayerPaymentToolDetails;
copyPayer.setPaymentToolDetails(new PaymentToolDetailsBankCard()
.bin(paymentToolDetails.getBin())
.lastDigits(paymentToolDetails.getLastDigits())
.cardNumberMask(paymentToolDetails.getCardNumberMask())
.tokenProvider(paymentToolDetails.getTokenProvider())
.paymentSystem(paymentToolDetails.getPaymentSystem()));
} else if (otherPayerPaymentToolDetails instanceof PaymentToolDetailsPaymentTerminal) {
copyPayer.setPaymentToolDetails(new PaymentToolDetailsPaymentTerminal()
.provider(((PaymentToolDetailsPaymentTerminal) otherPayerPaymentToolDetails).getProvider()));
} else if (otherPayerPaymentToolDetails instanceof PaymentToolDetailsDigitalWalletWrapper) {
PaymentToolDetailsDigitalWalletWrapper otherPaymentToolDetailsWrapper = (PaymentToolDetailsDigitalWalletWrapper) otherPayerPaymentToolDetails;
PaymentToolDetailsDigitalWalletWrapper paymentToolDetails = new PaymentToolDetailsDigitalWalletWrapper();
DigitalWalletDetails.DigitalWalletDetailsTypeEnum digitalWalletDetailsType = otherPaymentToolDetailsWrapper.getDigitalWalletDetails().getDigitalWalletDetailsType();
switch (digitalWalletDetailsType) {
case DIGITALWALLETDETAILSQIWI:
DigitalWalletDetailsQIWI otehrDigitalWalletDetails = (DigitalWalletDetailsQIWI)otherPaymentToolDetailsWrapper.getDigitalWalletDetails();
paymentToolDetails.setDigitalWalletDetails(new DigitalWalletDetailsQIWI()
.phoneNumberMask(otehrDigitalWalletDetails.getPhoneNumberMask()));
break;
default:
throw new UnsupportedOperationException("Unknown digitalWalletDetailsType "+ digitalWalletDetailsType +"; must be one of these: "+ Arrays.toString(DigitalWalletDetails.DigitalWalletDetailsTypeEnum.values()));
}
paymentToolDetails.getDigitalWalletDetails().setDigitalWalletDetailsType(digitalWalletDetailsType);
copyPayer.setPaymentToolDetails(paymentToolDetails);
} else if (otherPayerPaymentToolDetails instanceof PaymentToolDetailsCryptoWallet) {
PaymentToolDetailsCryptoWallet paymentToolDetails = (PaymentToolDetailsCryptoWallet) otherPayerPaymentToolDetails;
copyPayer.setPaymentToolDetails(new PaymentToolDetailsCryptoWallet().cryptoCurrency(paymentToolDetails.getCryptoCurrency()));
}
copyPayer.getPaymentToolDetails().detailsType(otherPayerPaymentToolDetails.getDetailsType());
}
this.payer.payerType(other.payer.getPayerType());
}
} }

View File

@ -59,10 +59,6 @@ message:
scheduler.delay: 1000 scheduler.delay: 1000
sender.number: 10 sender.number: 10
spring.cache:
cache-names: messagesByInvoice,messagesById,queues
caffeine.spec: maximumSize=1000,expireAfterWrite=60s
management: management:
security: security:
flag: false flag: false

View File

@ -73,19 +73,6 @@ public class DataflowTest extends AbstractIntegrationTest {
} }
} }
@Test
public void testCache(){
final String invoceId = "asgsdhghdhtfugny78989";
final String partyId = new Random().nextInt() + "";
InvoicingMessage message1 = buildMessage(AbstractInvoiceEventHandler.INVOICE, invoceId, partyId, EventType.INVOICE_CREATED, "status");
messageDao.create(message1);
InvoicingMessage message2 = messageDao.getInvoice(invoceId);
InvoicingMessage message3 = messageDao.getInvoice(invoceId);
assertTrue(message1 != message2);
assertTrue(message2 != message3);
assertTrue(message1 != message3);
}
@Test @Test
public void testMessageSend() throws InterruptedException { public void testMessageSend() throws InterruptedException {
List<InvoicingMessage> sourceMessages = new ArrayList<>(); List<InvoicingMessage> sourceMessages = new ArrayList<>();

View File

@ -42,6 +42,6 @@ public class HookDeleteDaoTest extends AbstractIntegrationTest {
hookDao.delete(hookId2); hookDao.delete(hookId2);
assertNotEquals(queueDao.getWithPolicies(taskDao.getScheduled(new ArrayList<>()).keySet()).size(), 0); assertNotEquals(queueDao.getWithPolicies(taskDao.getScheduled(new ArrayList<>()).keySet()).size(), 0);
hookDao.delete(hookId); hookDao.delete(hookId);
assertEquals(queueDao.getWithPolicies(taskDao.getScheduled(new ArrayList<>()).keySet()).size(), 0); assertEquals(taskDao.getScheduled(new ArrayList<>()).keySet().size(), 0);
} }
} }

View File

@ -15,6 +15,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import static com.rbkmoney.hooker.utils.BuildUtils.buildMessage; import static com.rbkmoney.hooker.utils.BuildUtils.buildMessage;
import static com.rbkmoney.hooker.utils.BuildUtils.cart; import static com.rbkmoney.hooker.utils.BuildUtils.cart;
@ -67,7 +68,9 @@ public class InvoicingMessageDaoImplTest extends AbstractIntegrationTest {
assertEquals(message.getInvoice().getAmount(), 12235); assertEquals(message.getInvoice().getAmount(), 12235);
assertEquals(message.getInvoice().getCart().size(), 2); assertEquals(message.getInvoice().getCart().size(), 2);
assertEquals(1, messageDao.getBy(Arrays.asList(message.getId())).size()); List<InvoicingMessage> messages = messageDao.getBy(Arrays.asList(message.getId()));
assertEquals(1, messages.size());
assertFalse(messages.get(0).getInvoice().getCart().isEmpty());
InvoicingMessage payment = messageDao.getPayment("1236", "123"); InvoicingMessage payment = messageDao.getPayment("1236", "123");
assertTrue(payment.getPayment().getPayer() instanceof CustomerPayer); assertTrue(payment.getPayment().getPayer() instanceof CustomerPayer);

View File

@ -21,9 +21,6 @@ public class MessageJsonTest {
String json = InvoicingMessageJson.buildMessageJson(message); String json = InvoicingMessageJson.buildMessageJson(message);
System.out.println(json); System.out.println(json);
Assert.assertTrue(json.contains("\"kek\":\"lol\"")); Assert.assertTrue(json.contains("\"kek\":\"lol\""));
InvoicingMessage copy = message.copy();
message.getInvoice().setAmount(99988);
Assert.assertNotEquals(message.getInvoice().getAmount(), copy.getInvoice().getAmount());
} }
@Test @Test