mirror of
https://github.com/valitydev/hooker.git
synced 2024-11-06 00:05:17 +00:00
Add time check (#63)
Some checks failed
Deploy Docker Image / build-and-deploy (push) Has been cancelled
Some checks failed
Deploy Docker Image / build-and-deploy (push) Has been cancelled
This commit is contained in:
parent
2071f1b6e0
commit
572ff3bd71
@ -16,6 +16,7 @@ public class AllHookTablesRow {
|
||||
private String pubKey;
|
||||
private boolean enabled;
|
||||
private double availability;
|
||||
private String createdAt;
|
||||
private WebhookAdditionalFilter webhookAdditionalFilter;
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -37,6 +40,7 @@ public class HookDaoImpl implements HookDao {
|
||||
rs.getString("pub_key"),
|
||||
rs.getBoolean("enabled"),
|
||||
rs.getDouble("availability"),
|
||||
rs.getString("created_at"),
|
||||
new WebhookAdditionalFilter(EventType.valueOf(rs.getString("event_type")),
|
||||
rs.getString("invoice_shop_id"),
|
||||
rs.getString("invoice_status"),
|
||||
@ -57,6 +61,7 @@ public class HookDaoImpl implements HookDao {
|
||||
" w.enabled, " +
|
||||
" w.topic, " +
|
||||
" w.availability, " +
|
||||
" w.created_at, " +
|
||||
" k.pub_key, " +
|
||||
" wte.hook_id, " +
|
||||
" wte.event_type, " +
|
||||
@ -174,6 +179,7 @@ public class HookDaoImpl implements HookDao {
|
||||
hook.setPubKey(allHookTablesRow.getPubKey());
|
||||
hook.setEnabled(allHookTablesRow.isEnabled());
|
||||
hook.setAvailability(allHookTablesRow.getAvailability());
|
||||
hook.setCreatedAt(allHookTablesRow.getCreatedAt());
|
||||
hook.setFilters(rows.stream()
|
||||
.map(AllHookTablesRow::getWebhookAdditionalFilter)
|
||||
.collect(Collectors.toSet()));
|
||||
@ -192,6 +198,7 @@ public class HookDaoImpl implements HookDao {
|
||||
" w.enabled, " +
|
||||
" w.topic, " +
|
||||
" w.availability, " +
|
||||
" w.created_at, " +
|
||||
" k.pub_key, " +
|
||||
" wte.hook_id, " +
|
||||
" wte.event_type, " +
|
||||
@ -228,14 +235,16 @@ public class HookDaoImpl implements HookDao {
|
||||
String pubKey = createOrGetPubKey(hook.getPartyId());
|
||||
hook.setPubKey(pubKey);
|
||||
hook.setEnabled(true);
|
||||
|
||||
final String sql = "INSERT INTO hook.webhook(party_id, url, topic) " +
|
||||
"VALUES (:party_id, :url, CAST(:topic as hook.message_topic)) RETURNING ID";
|
||||
final String sql = "INSERT INTO hook.webhook(party_id, url, topic, created_at) " +
|
||||
"VALUES (:party_id, :url, CAST(:topic as hook.message_topic), :created_at) RETURNING ID";
|
||||
|
||||
MapSqlParameterSource params = new MapSqlParameterSource()
|
||||
.addValue("party_id", hook.getPartyId())
|
||||
.addValue("url", hook.getUrl())
|
||||
.addValue("topic", hook.getTopic());
|
||||
.addValue("topic", hook.getTopic())
|
||||
.addValue("created_at", new Timestamp(LocalDateTime.now()
|
||||
.toInstant(ZoneOffset.UTC).toEpochMilli()))
|
||||
;
|
||||
try {
|
||||
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
int updateCount = jdbcTemplate.update(sql, params, keyHolder);
|
||||
|
@ -47,21 +47,21 @@ public class InvoicingDaoImpl implements InvoicingMessageDao {
|
||||
"RETURNING id";
|
||||
|
||||
MapSqlParameterSource sqlParameterSources = new MapSqlParameterSource()
|
||||
.addValue(InvoicingRowMapper.EVENT_TIME, message.getEventTime())
|
||||
.addValue(InvoicingRowMapper.SEQUENCE_ID, message.getSequenceId())
|
||||
.addValue(InvoicingRowMapper.CHANGE_ID, message.getChangeId())
|
||||
.addValue(InvoicingRowMapper.TYPE, message.getType().getValue())
|
||||
.addValue(InvoicingRowMapper.PARTY_ID, message.getPartyId())
|
||||
.addValue(InvoicingRowMapper.EVENT_TYPE, message.getEventType().toString())
|
||||
.addValue(InvoicingRowMapper.INVOICE_ID, message.getSourceId())
|
||||
.addValue(InvoicingRowMapper.SHOP_ID, message.getShopId())
|
||||
.addValue(InvoicingRowMapper.INVOICE_STATUS, message.getInvoiceStatus().getValue())
|
||||
.addValue(InvoicingRowMapper.PAYMENT_ID, message.getPaymentId())
|
||||
.addValue(InvoicingRowMapper.PAYMENT_STATUS,
|
||||
message.getPaymentStatus() != null ? message.getPaymentStatus().getValue() : null)
|
||||
.addValue(InvoicingRowMapper.REFUND_ID, message.getRefundId())
|
||||
.addValue(InvoicingRowMapper.REFUND_STATUS,
|
||||
message.getRefundStatus() != null ? message.getRefundStatus().getValue() : null);
|
||||
.addValue(InvoicingRowMapper.EVENT_TIME, message.getEventTime())
|
||||
.addValue(InvoicingRowMapper.SEQUENCE_ID, message.getSequenceId())
|
||||
.addValue(InvoicingRowMapper.CHANGE_ID, message.getChangeId())
|
||||
.addValue(InvoicingRowMapper.TYPE, message.getType().getValue())
|
||||
.addValue(InvoicingRowMapper.PARTY_ID, message.getPartyId())
|
||||
.addValue(InvoicingRowMapper.EVENT_TYPE, message.getEventType().toString())
|
||||
.addValue(InvoicingRowMapper.INVOICE_ID, message.getSourceId())
|
||||
.addValue(InvoicingRowMapper.SHOP_ID, message.getShopId())
|
||||
.addValue(InvoicingRowMapper.INVOICE_STATUS, message.getInvoiceStatus().getValue())
|
||||
.addValue(InvoicingRowMapper.PAYMENT_ID, message.getPaymentId())
|
||||
.addValue(InvoicingRowMapper.PAYMENT_STATUS,
|
||||
message.getPaymentStatus() != null ? message.getPaymentStatus().getValue() : null)
|
||||
.addValue(InvoicingRowMapper.REFUND_ID, message.getRefundId())
|
||||
.addValue(InvoicingRowMapper.REFUND_STATUS,
|
||||
message.getRefundStatus() != null ? message.getRefundStatus().getValue() : null);
|
||||
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
jdbcTemplate.update(sql, sqlParameterSources, keyHolder);
|
||||
return keyHolder.getKey() == null ? null : keyHolder.getKey().longValue();
|
||||
@ -91,7 +91,7 @@ public class InvoicingDaoImpl implements InvoicingMessageDao {
|
||||
|
||||
@Override
|
||||
public List<WebhookMessageModel<InvoicingMessage>> getWebhookModels(Long messageId) {
|
||||
final String sql = "select m.*, w.id as hook_id, w.url, pk.priv_key" +
|
||||
final String sql = "select m.*, w.id as hook_id, w.url, pk.priv_key" +
|
||||
" from hook.message m" +
|
||||
" join hook.webhook w on m.party_id = w.party_id " +
|
||||
" and w.enabled and w.topic=CAST(:message_type as hook.message_topic)" +
|
||||
@ -111,12 +111,14 @@ public class InvoicingDaoImpl implements InvoicingMessageDao {
|
||||
|
||||
@Override
|
||||
public Long getParentId(Long hookId, String invoiceId, Long messageId) {
|
||||
final String sql = "select m.id" +
|
||||
log.info("hookId: {}, invoiceId: {}, messageId: {}", hookId, invoiceId, messageId);
|
||||
final String sql = "select m.id" +
|
||||
" from hook.message m " +
|
||||
" join hook.webhook w on w.id=:hook_id" +
|
||||
" join hook.webhook_to_events wte on wte.hook_id = w.id" +
|
||||
" where m.invoice_id =:invoice_id" +
|
||||
" and m.id <:id " +
|
||||
" and m.event_time::timestamp >= w.created_at" +
|
||||
" and m.event_type = wte.event_type " +
|
||||
" and (m.shop_id = wte.invoice_shop_id or wte.invoice_shop_id is null) " +
|
||||
" and (m.invoice_status = wte.invoice_status or wte.invoice_status is null) " +
|
||||
|
@ -23,4 +23,5 @@ public class Hook {
|
||||
private String privKey;
|
||||
private boolean enabled;
|
||||
private double availability;
|
||||
private String createdAt;
|
||||
}
|
||||
|
@ -2,13 +2,15 @@ package dev.vality.hooker.model;
|
||||
|
||||
import dev.vality.hooker.model.interaction.UserInteraction;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@ToString
|
||||
@ToString(callSuper = true)
|
||||
public class InvoicingMessage extends Message {
|
||||
|
||||
private InvoicingMessageEnum type;
|
||||
|
@ -2,9 +2,11 @@ package dev.vality.hooker.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class Message {
|
||||
private Long id;
|
||||
private Long sequenceId;
|
||||
|
@ -0,0 +1,5 @@
|
||||
ALTER TABLE hook.webhook ADD COLUMN IF NOT EXISTS created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
UPDATE hook.webhook SET created_at = NOW() - INTERVAL '2 DAYS';
|
||||
|
||||
ALTER TABLE hook.webhook_to_events ADD COLUMN IF NOT EXISTS created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
UPDATE hook.webhook_to_events SET created_at = NOW() - INTERVAL '2 DAYS';
|
@ -5,6 +5,7 @@ import dev.vality.hooker.dao.impl.InvoicingDaoImpl;
|
||||
import dev.vality.hooker.model.*;
|
||||
import dev.vality.hooker.utils.BuildUtils;
|
||||
import dev.vality.swag_webhook_events.model.Event;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -14,6 +15,7 @@ import java.util.Set;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
@Slf4j
|
||||
@PostgresqlSpringBootITest
|
||||
public class InvoicingDaoImplTest {
|
||||
|
||||
@ -37,27 +39,14 @@ public class InvoicingDaoImplTest {
|
||||
private Hook hook;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
hook = Hook.builder()
|
||||
.partyId(partyId)
|
||||
.topic(Event.TopicEnum.INVOICESTOPIC.getValue())
|
||||
.url("zzz")
|
||||
.filters(Set.of(
|
||||
WebhookAdditionalFilter.builder()
|
||||
.eventType(EventType.INVOICE_CREATED)
|
||||
.build(),
|
||||
WebhookAdditionalFilter.builder()
|
||||
.eventType(EventType.INVOICE_PAYMENT_STATUS_CHANGED)
|
||||
.invoicePaymentStatus("processed")
|
||||
.build(),
|
||||
WebhookAdditionalFilter.builder()
|
||||
.eventType(EventType.INVOICE_PAYMENT_STATUS_CHANGED)
|
||||
.invoicePaymentStatus("captured")
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
public void setUp() throws InterruptedException {
|
||||
hook = createHookModel();
|
||||
|
||||
hook = hookDao.create(hook);
|
||||
log.info("hookOld: {}", hookDao.getHookById(hook.getId()));
|
||||
|
||||
Thread.sleep(1000L); // Sleep for lag between create hook and events
|
||||
|
||||
hookDao.create(hook);
|
||||
messageIdOne = messageDao.save(BuildUtils.buildMessage(InvoicingMessageEnum.INVOICE.getValue(),
|
||||
invoiceOne, partyId, EventType.INVOICE_CREATED,
|
||||
InvoiceStatusEnum.UNPAID, null));
|
||||
@ -75,6 +64,27 @@ public class InvoicingDaoImplTest {
|
||||
InvoiceStatusEnum.PAID, null));
|
||||
}
|
||||
|
||||
private Hook createHookModel() {
|
||||
return Hook.builder()
|
||||
.partyId(partyId)
|
||||
.topic(Event.TopicEnum.INVOICESTOPIC.getValue())
|
||||
.url("zzz")
|
||||
.filters(Set.of(
|
||||
WebhookAdditionalFilter.builder()
|
||||
.eventType(EventType.INVOICE_CREATED)
|
||||
.build(),
|
||||
WebhookAdditionalFilter.builder()
|
||||
.eventType(EventType.INVOICE_PAYMENT_STATUS_CHANGED)
|
||||
.invoicePaymentStatus("processed")
|
||||
.build(),
|
||||
WebhookAdditionalFilter.builder()
|
||||
.eventType(EventType.INVOICE_PAYMENT_STATUS_CHANGED)
|
||||
.invoicePaymentStatus("captured")
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInvoicingMessage() {
|
||||
InvoicingMessage messageOne = messageDao.getInvoicingMessage(
|
||||
@ -153,4 +163,39 @@ public class InvoicingDaoImplTest {
|
||||
Long parentEventIdThree = messageDao.getParentId(hook.getId(), invoiceThree, messageIdThree);
|
||||
assertEquals(-1, parentEventIdThree);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetParentEventIdWithOldHook() throws InterruptedException {
|
||||
Hook hookOld = hookDao.create(createHookModel());
|
||||
log.info("hookOld: {}", hookDao.getHookById(hookOld.getId()));
|
||||
|
||||
Thread.sleep(1000L); // Sleep for lag between create hook and events
|
||||
|
||||
String newInvoiceId = "new_invoice";
|
||||
var oldMessageId = messageDao.save(BuildUtils.buildMessage(InvoicingMessageEnum.INVOICE.getValue(),
|
||||
newInvoiceId, partyId, EventType.INVOICE_CREATED,
|
||||
InvoiceStatusEnum.UNPAID, null, 1L, 1));
|
||||
|
||||
Long parentEventId = messageDao.getParentId(hookOld.getId(), newInvoiceId, oldMessageId);
|
||||
assertEquals(-1, parentEventId);
|
||||
|
||||
hookDao.delete(hookOld.getId());
|
||||
log.info("hookOld: {}", hookDao.getHookById(hookOld.getId()));
|
||||
|
||||
Thread.sleep(2000L);
|
||||
|
||||
Hook hookModel = createHookModel();
|
||||
hookModel.setCreatedAt(null);
|
||||
Hook hookNew = hookDao.create(hookModel);
|
||||
log.info("hookNew: {}", hookDao.getHookById(hookNew.getId()));
|
||||
|
||||
Thread.sleep(1000L);
|
||||
|
||||
var newMessageId = messageDao.save(BuildUtils.buildMessage(InvoicingMessageEnum.PAYMENT.getValue(),
|
||||
newInvoiceId, partyId, EventType.INVOICE_PAYMENT_STATUS_CHANGED,
|
||||
InvoiceStatusEnum.PAID, PaymentStatusEnum.CAPTURED, 1L, 2));
|
||||
|
||||
parentEventId = messageDao.getParentId(hookNew.getId(), newInvoiceId, newMessageId);
|
||||
assertEquals(-1, parentEventId);
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,15 @@ import dev.vality.geck.serializer.kit.tbase.TBaseHandler;
|
||||
import dev.vality.hooker.dao.WebhookAdditionalFilter;
|
||||
import dev.vality.hooker.model.*;
|
||||
import dev.vality.swag_webhook_events.model.Event;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class BuildUtils {
|
||||
private static int messageId = 1;
|
||||
|
||||
@ -29,7 +33,7 @@ public class BuildUtils {
|
||||
InvoiceStatusEnum invoiceStatus, PaymentStatusEnum paymentStatus,
|
||||
Long sequenceId, Integer changeId) {
|
||||
InvoicingMessage message = new InvoicingMessage();
|
||||
message.setEventTime("2016-03-22T06:12:27Z");
|
||||
message.setEventTime(LocalDateTime.now().toInstant(ZoneOffset.UTC).toString());
|
||||
message.setType(InvoicingMessageEnum.lookup(type));
|
||||
message.setPartyId(partyId);
|
||||
message.setEventType(eventType);
|
||||
@ -47,6 +51,7 @@ public class BuildUtils {
|
||||
}
|
||||
message.setSequenceId(sequenceId);
|
||||
message.setChangeId(changeId);
|
||||
log.info("Create message: {}", message);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user