mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-05 11:02:05 +00:00
push milestones
This commit is contained in:
@@ -4,16 +4,15 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/user"
|
||||
)
|
||||
|
||||
func (n *NotificationQueries) IsAlreadyHandled(ctx context.Context, event eventstore.Event, data map[string]interface{}, eventTypes ...eventstore.EventType) (bool, error) {
|
||||
func (n *NotificationQueries) IsAlreadyHandled(ctx context.Context, event eventstore.Event, data map[string]interface{}, aggregateType eventstore.AggregateType, eventTypes ...eventstore.EventType) (bool, error) {
|
||||
events, err := n.es.Filter(
|
||||
ctx,
|
||||
eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
InstanceID(event.Aggregate().InstanceID).
|
||||
AddQuery().
|
||||
AggregateTypes(user.AggregateType).
|
||||
AggregateTypes(aggregateType).
|
||||
AggregateIDs(event.Aggregate().ID).
|
||||
SequenceGreater(event.Sequence()).
|
||||
EventTypes(eventTypes...).
|
||||
|
||||
@@ -68,7 +68,7 @@ func (u *quotaNotifier) reduceNotificationDue(event eventstore.Event) (*handler.
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-DLxdE", "reduce.wrong.event.type %s", quota.NotificationDueEventType)
|
||||
}
|
||||
ctx := HandlerContext(event.Aggregate())
|
||||
alreadyHandled, err := u.queries.IsAlreadyHandled(ctx, event, map[string]interface{}{"dueEventID": e.ID}, quota.NotifiedEventType)
|
||||
alreadyHandled, err := u.queries.IsAlreadyHandled(ctx, event, map[string]interface{}{"dueEventID": e.ID}, quota.AggregateType, quota.NotifiedEventType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
113
internal/notification/handlers/telemetrypusher.go
Normal file
113
internal/notification/handlers/telemetrypusher.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/repository/milestone"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
|
||||
_ "github.com/zitadel/zitadel/internal/notification/statik"
|
||||
"github.com/zitadel/zitadel/internal/notification/types"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
)
|
||||
|
||||
const (
|
||||
TelemetryProjectionTable = "projections.telemetry"
|
||||
)
|
||||
|
||||
type TelemetryPusherConfig struct {
|
||||
Enabled bool
|
||||
Endpoints []string
|
||||
}
|
||||
|
||||
type telemetryPusher struct {
|
||||
cfg TelemetryPusherConfig
|
||||
crdb.StatementHandler
|
||||
commands *command.Commands
|
||||
queries *NotificationQueries
|
||||
metricSuccessfulDeliveriesJSON string
|
||||
metricFailedDeliveriesJSON string
|
||||
}
|
||||
|
||||
func NewTelemetryPusher(
|
||||
ctx context.Context,
|
||||
telemetryCfg TelemetryPusherConfig,
|
||||
handlerCfg crdb.StatementHandlerConfig,
|
||||
commands *command.Commands,
|
||||
queries *NotificationQueries,
|
||||
metricSuccessfulDeliveriesJSON,
|
||||
metricFailedDeliveriesJSON string,
|
||||
) *telemetryPusher {
|
||||
p := new(telemetryPusher)
|
||||
handlerCfg.ProjectionName = TelemetryProjectionTable
|
||||
handlerCfg.Reducers = p.reducers()
|
||||
p.cfg = telemetryCfg
|
||||
p.StatementHandler = crdb.NewStatementHandler(ctx, handlerCfg)
|
||||
p.commands = commands
|
||||
p.queries = queries
|
||||
p.metricSuccessfulDeliveriesJSON = metricSuccessfulDeliveriesJSON
|
||||
p.metricFailedDeliveriesJSON = metricFailedDeliveriesJSON
|
||||
projection.TelemetryPusherProjection = p
|
||||
return p
|
||||
}
|
||||
|
||||
func (t *telemetryPusher) reducers() []handler.AggregateReducer {
|
||||
if !t.cfg.Enabled {
|
||||
return nil
|
||||
}
|
||||
return []handler.AggregateReducer{
|
||||
{
|
||||
Aggregate: milestone.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: milestone.ReachedEventType,
|
||||
Reduce: t.reduceTelemetryPushDue,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *telemetryPusher) reduceTelemetryPushDue(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*milestone.ReachedEvent)
|
||||
if !ok {
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-UjA3E", "reduce.wrong.event.type %s", milestone.ReachedEventType)
|
||||
}
|
||||
ctx := HandlerContext(event.Aggregate())
|
||||
alreadyHandled, err := t.queries.IsAlreadyHandled(ctx, event, nil, milestone.AggregateType, milestone.PushedEventType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if alreadyHandled {
|
||||
return crdb.NewNoOpStatement(e), nil
|
||||
}
|
||||
for _, endpoint := range t.cfg.Endpoints {
|
||||
if err = types.SendJSON(
|
||||
ctx,
|
||||
webhook.Config{
|
||||
CallURL: endpoint,
|
||||
Method: http.MethodPost,
|
||||
},
|
||||
t.queries.GetFileSystemProvider,
|
||||
t.queries.GetLogProvider,
|
||||
e,
|
||||
e,
|
||||
t.metricSuccessfulDeliveriesJSON,
|
||||
t.metricFailedDeliveriesJSON,
|
||||
).WithoutTemplate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = t.commands.TelemetryPushed(ctx, e, t.cfg.Endpoints)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return crdb.NewNoOpStatement(e), nil
|
||||
}
|
||||
@@ -2,8 +2,13 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/repository/project"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
@@ -106,11 +111,67 @@ func (u *userNotifier) reducers() []handler.AggregateReducer {
|
||||
Event: user.HumanPasswordChangedType,
|
||||
Reduce: u.reducePasswordChanged,
|
||||
},
|
||||
{
|
||||
Event: user.UserTokenAddedType,
|
||||
Reduce: u.reduceUserTokenAdded,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Aggregate: instance.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: instance.InstanceAddedEventType,
|
||||
Reduce: u.reduceInstanceAdded,
|
||||
},
|
||||
{
|
||||
Event: instance.InstanceRemovedEventType,
|
||||
Reduce: u.reduceInstanceRemoved,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Aggregate: project.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: project.ProjectAddedType,
|
||||
Reduce: u.reduceProjectAdded,
|
||||
},
|
||||
{
|
||||
Event: project.ApplicationAddedType,
|
||||
Reduce: u.reduceApplicationAdded,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceInstanceAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
fmt.Println("reduceInstanceAdded")
|
||||
return crdb.NewNoOpStatement(event), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceProjectAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
// ignore instance.ProjectSetEventType
|
||||
fmt.Println("reduceProjectAdded")
|
||||
return crdb.NewNoOpStatement(event), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceApplicationAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
fmt.Println("reduceApplicationAdded")
|
||||
return crdb.NewNoOpStatement(event), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceUserTokenAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
fmt.Println("reduceUserTokenAdded")
|
||||
return crdb.NewNoOpStatement(event), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceInstanceRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
fmt.Println("reduceInstanceRemoved")
|
||||
return crdb.NewNoOpStatement(event), nil
|
||||
}
|
||||
|
||||
func (u *userNotifier) reduceInitCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*user.HumanInitialCodeAddedEvent)
|
||||
if !ok {
|
||||
@@ -334,7 +395,7 @@ func (u *userNotifier) reduceDomainClaimed(event eventstore.Event) (*handler.Sta
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Drh5w", "reduce.wrong.event.type %s", user.UserDomainClaimedType)
|
||||
}
|
||||
ctx := HandlerContext(event.Aggregate())
|
||||
alreadyHandled, err := u.queries.IsAlreadyHandled(ctx, event, nil,
|
||||
alreadyHandled, err := u.queries.IsAlreadyHandled(ctx, event, nil, user.AggregateType,
|
||||
user.UserDomainClaimedType, user.UserDomainClaimedSentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -462,7 +523,7 @@ func (u *userNotifier) reducePasswordChanged(event eventstore.Event) (*handler.S
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Yko2z8", "reduce.wrong.event.type %s", user.HumanPasswordChangedType)
|
||||
}
|
||||
ctx := HandlerContext(event.Aggregate())
|
||||
alreadyHandled, err := u.queries.IsAlreadyHandled(ctx, event, nil, user.HumanPasswordChangeSentType)
|
||||
alreadyHandled, err := u.queries.IsAlreadyHandled(ctx, event, nil, user.AggregateType, user.HumanPasswordChangeSentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -591,5 +652,5 @@ func (u *userNotifier) checkIfCodeAlreadyHandledOrExpired(ctx context.Context, e
|
||||
if event.CreationDate().Add(expiry).Before(time.Now().UTC()) {
|
||||
return true, nil
|
||||
}
|
||||
return u.queries.IsAlreadyHandled(ctx, event, data, eventTypes...)
|
||||
return u.queries.IsAlreadyHandled(ctx, event, data, user.AggregateType, eventTypes...)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user