-
Notifications
You must be signed in to change notification settings - Fork 116
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
notification: store webhook and webhook delivery #413
Conversation
1a7883b
to
a76f6e1
Compare
a76f6e1
to
ee79970
Compare
ee79970
to
a418cb4
Compare
@sgotti can you do the review please? |
switch runWebhook.PayloadVersion { | ||
case 1: | ||
if err = json.Unmarshal([]byte(runWebhook.Payload), &webhook); err != nil { | ||
return sequence, errors.WithStack(err) | ||
} | ||
default: | ||
return sequence, errors.Errorf("unknown payload version: %d", runWebhook.PayloadVersion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you unmarshalling the payload?
|
||
err := n.d.Do(ctx, func(tx *sql.Tx) error { | ||
// start from last event | ||
runWebhookDelivery, err := n.d.GetLastRunWebhookDelivery(tx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you starting from the last sequence? What happens if previous deliveries haven't been handled?
a418cb4
to
b757e04
Compare
ce21951
to
ce4203d
Compare
dc68b82
to
02695bd
Compare
NotDelivered DeliveryStatus = "not_delivered" | ||
Delivered DeliveryStatus = "delivered" | ||
DeliveryError DeliveryStatus = "delivery_error" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeliveryStatusNotDelivered DeliveryStatus = "notDelivered"
DeliveryStatusDelivered DeliveryStatus = "delivered"
DeliveryStatusDeliveryError DeliveryStatus = "deliveryError"
@@ -0,0 +1,127 @@ | |||
// Copyright 2023 Sorint.lab |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no camel case in file names...
|
||
t.Logf("starting webhooks client") | ||
|
||
time.Sleep(1 * time.Second) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sleep is bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added sleep because the test was failing. I thought the webhookreceiver was not started and needed much time.
I try to remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
webhookreceiver should start and return after is has been started.
|
||
if n.c.WebhookSecret != "" { | ||
sig256 := hmac.New(sha256.New, []byte(n.c.WebhookSecret)) | ||
_, err = io.MultiWriter(sig256).Write(data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why io.multiwriter?
bebb0ac
to
e5f9b94
Compare
sig256 := hmac.New(sha256.New, []byte(n.c.WebhookSecret)) | ||
_, err = io.MultiWriter(sig256).Write([]byte(body)) | ||
if err != nil { | ||
if err := n.d.InsertOrUpdateRunWebhookDelivery(tx, runWebhookDelivery); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just an insert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sgotti I do not know what you mean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you're inserting a new entry, not updating an existing one. So use InsertBla and not InsertOrUpdateBla.
wh = types.NewRunWebhook(tx) | ||
wh.Payload = "payloadtest" | ||
|
||
if err := ns.d.InsertOrUpdateRunWebhook(tx, wh); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just an insert?
wd.DeliveryStatus = deliveryStatus | ||
wd.RunWebhookID = runWebhookID | ||
|
||
if err := ns.d.InsertOrUpdateRunWebhookDelivery(tx, wd); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just an insert?
runWebhookDelivery.Status = status | ||
runWebhookDelivery.StatusCode = statusCode | ||
|
||
if err = n.d.InsertOrUpdateRunWebhookDelivery(tx, runWebhookDelivery); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just an update?
if err != nil { | ||
return errors.WithStack(err) | ||
} | ||
if err := n.d.InsertOrUpdateRunWebhook(tx, wh); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just an insert?
@@ -0,0 +1,198 @@ | |||
// Copyright 2023 Sorint.lab |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
runwebhookdelivery.go
) | ||
|
||
const ( | ||
MaxRunWebhookDeliverysLimit = 40 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to use the plural form it's deliveries
func (d *DB) GetRunWebhookDeliveryByID(tx *sql.Tx, runWebhookDeliveryID string) (*types.RunWebhookDelivery, error) { | ||
q := runWebhookDeliverySelect() | ||
q.Where(q.E("id", runWebhookDeliveryID)) | ||
runWebhookDeliverys, _, err := d.fetchRunWebhookDeliverys(tx, q) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the generated functions could have the wrong plural forms (since it only adds an s) but the manually typed code should use the right plural form (deliveries)
e5f9b94
to
b5524cc
Compare
|
||
if n.c.WebhookSecret != "" { | ||
sig256 := hmac.New(sha256.New, []byte(n.c.WebhookSecret)) | ||
_, err = io.WriteString(sig256, webhookPayload) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use h256.Write
?
b5524cc
to
19b493d
Compare
|
||
func (d *DB) GetRunWebhookDeliveriesNotDeliveredAfterSequence(tx *sql.Tx, afterSequence uint64, limit int) ([]*types.RunWebhookDelivery, error) { | ||
q := runWebhookDeliverySelect().OrderBy("sequence").Asc() | ||
q.Where(q.E("delivery_status", types.DeliveryStatusNotDelivered)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This, in previous commits, was a query option to filter by delivery_status. Why was it removed and made fixed?
return s[0], nil | ||
} | ||
|
||
func (d *DB) GetRunWebhookDeliveries(tx *sql.Tx, limit int) ([]*types.RunWebhookDelivery, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't really useful. It's used only by tests, you could use just a single functions with an optional filter on status, startSequence and limit. See also next comment.
t.Logf("starting webhooks client") | ||
|
||
ns.c.WebhookURL = fmt.Sprintf("%s/%s", wr.exposedURL, "webhooks") | ||
ns.c.WebhookSecret = "secretkey" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a const
t.Fatalf("expected %s run webhook payload got: %s", runWebhooks[i].Payload, webhooks[i].payload) | ||
} | ||
|
||
h256 := hmac.New(sha256.New, []byte(ns.c.WebhookSecret)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a const var, not ns.c.WebhookSecret
type RunWebhook struct { | ||
sqlg.ObjectMeta | ||
|
||
Payload string `json:"payload,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no omitempty
type RunWebhookDelivery struct { | ||
sqlg.ObjectMeta | ||
|
||
Sequence uint64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing json tags
type RunWebhook struct { | ||
sqlg.ObjectMeta | ||
|
||
Payload string `json:"payload,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[]byte
} | ||
|
||
type webhook struct { | ||
payload string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[]byte
{Name: "DeliveryStatus", Type: "types.DeliveryStatus", BaseType: "string"}, | ||
{Name: "DeliveredAt", Type: "time.Time", Nullable: true}, | ||
{Name: "Duration", Type: "time.Duration", Nullable: true}, | ||
{Name: "Status", Type: "string"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Status really needed? Isn't StatusCode enough?
d2f067d
to
2ececfa
Compare
{Name: "RunWebhookID", Type: "string"}, | ||
{Name: "DeliveryStatus", Type: "types.DeliveryStatus", BaseType: "string"}, | ||
{Name: "DeliveredAt", Type: "time.Time", Nullable: true}, | ||
{Name: "Duration", Type: "time.Duration", Nullable: true}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duration is not really needed.
} | ||
|
||
func (n *NotificationService) sendRunWebhook(ctx context.Context, webhookPayload []byte, runWebhookUUID string) (*http.Response, *time.Duration, error) { | ||
c := &http.Client{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a new empty http client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should contain some data for TestCreate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is not related to this PR.
2ececfa
to
6ef35a1
Compare
} | ||
} | ||
|
||
func (n *NotificationService) handleRunWebhookDelivery(ctx context.Context, runWebhookDelivery *types.RunWebhookDelivery) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass runWebhookDeliveryID
31426dc
to
7abafed
Compare
7abafed
to
d48fff4
Compare
} | ||
|
||
if runWebhookDelivery.DeliveryStatus != types.DeliveryStatusNotDelivered { | ||
return errors.Errorf("run webhook delivery %q already delivered", runWebhookDeliveryID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to error, just return
return errors.WithStack(err) | ||
} | ||
if runWebhookDelivery.DeliveryStatus != types.DeliveryStatusNotDelivered { | ||
return errors.Errorf("run webhook delivery %q already delivered", runWebhookDeliveryID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to error, just return.
d48fff4
to
b111876
Compare
df88a58
to
966169e
Compare
966169e
to
d11006f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix the commit title (as the PR title that I have updated) and description (why notification:
at every line?).
add db schema add RunWebhook and RunWebhookDelivery type add header X-Agola-Delivery when send run webhooks
d11006f
to
ee0f10e
Compare
@sgotti I fixed the commit |
fix #417