diff --git a/pkg/graph/constructor.go b/pkg/graph/constructor.go index 2fc6fb4e0d4..7e5430d7814 100644 --- a/pkg/graph/constructor.go +++ b/pkg/graph/constructor.go @@ -17,6 +17,8 @@ limitations under the License. package graph import ( + "fmt" + eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" duckv1 "knative.dev/pkg/apis/duck/v1" @@ -94,3 +96,53 @@ func (g *Graph) AddChannel(channel messagingv1.Channel) { v.AddEdge(to, dest, NoTransform) } + +func (g *Graph) AddTrigger(trigger eventingv1.Trigger) error { + brokerRef := &duckv1.KReference{ + Name: trigger.Spec.Broker, + Namespace: trigger.Namespace, + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + } + brokerDest := &duckv1.Destination{Ref: brokerRef} + broker, ok := g.vertices[makeComparableDestination(brokerDest)] + if !ok { + return fmt.Errorf("trigger refers to a non existent broker, can't add it to the graph") + } + + triggerRef := &duckv1.KReference{ + Name: trigger.Name, + Namespace: trigger.Namespace, + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + } + triggerDest := &duckv1.Destination{Ref: triggerRef} + + to, ok := g.vertices[makeComparableDestination(&trigger.Spec.Subscriber)] + if !ok { + to = &Vertex{ + self: &trigger.Spec.Subscriber, + } + g.vertices[makeComparableDestination(&trigger.Spec.Subscriber)] = to + } + + //TODO: the transform function should be set according to the trigger filter - there are multiple open issues to address this later + broker.AddEdge(to, triggerDest, NoTransform) + + if trigger.Spec.Delivery == nil || trigger.Spec.Delivery.DeadLetterSink == nil { + return nil + } + + dls, ok := g.vertices[makeComparableDestination(trigger.Spec.Delivery.DeadLetterSink)] + if !ok { + dls = &Vertex{ + self: trigger.Spec.Delivery.DeadLetterSink, + } + g.vertices[makeComparableDestination(trigger.Spec.Delivery.DeadLetterSink)] = dls + } + + broker.AddEdge(dls, triggerDest, NoTransform) + + return nil + +} diff --git a/pkg/graph/constructor_test.go b/pkg/graph/constructor_test.go index a54aa79b07b..c8f15f19eda 100644 --- a/pkg/graph/constructor_test.go +++ b/pkg/graph/constructor_test.go @@ -31,6 +31,7 @@ import ( var ( sampleUri, _ = apis.ParseURL("https://knative.dev") + secondUri, _ = apis.ParseURL("https://google.com") ) func TestAddBroker(t *testing.T) { @@ -129,6 +130,373 @@ func TestAddBroker(t *testing.T) { } } +func TestAddTrigger(t *testing.T) { + tests := []struct { + name string + brokers []eventingv1.Broker + triggers []eventingv1.Trigger + expected map[comparableDestination]*Vertex + wantErr bool + }{ + { + name: "One Trigger, One Broker, no DLS", + brokers: []eventingv1.Broker{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-broker", + Namespace: "default", + }, + }}, + triggers: []eventingv1.Trigger{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-trigger", + Namespace: "default", + }, + Spec: eventingv1.TriggerSpec{ + Broker: "my-broker", + Subscriber: duckv1.Destination{ + URI: sampleUri, + }, + }, + }}, + expected: map[comparableDestination]*Vertex{ + { + Ref: duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }: { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + outEdges: []*Edge{ + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-trigger", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: sampleUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + }, + }, + { + URI: *sampleUri, + }: { + self: &duckv1.Destination{ + URI: sampleUri, + }, + inEdges: []*Edge{ + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-trigger", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: sampleUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "One Trigger, One Broker, both with DLS", + brokers: []eventingv1.Broker{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-broker", + Namespace: "default", + }, + Spec: eventingv1.BrokerSpec{ + Delivery: &eventingduckv1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + URI: secondUri, + }, + }, + }, + }}, + triggers: []eventingv1.Trigger{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-trigger", + Namespace: "default", + }, + Spec: eventingv1.TriggerSpec{ + Broker: "my-broker", + Subscriber: duckv1.Destination{ + URI: sampleUri, + }, + Delivery: &eventingduckv1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + URI: secondUri, + }, + }, + }, + }}, + expected: map[comparableDestination]*Vertex{ + { + Ref: duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }: { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + outEdges: []*Edge{ + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-trigger", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: sampleUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-trigger", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: secondUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: secondUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + }, + }, + { + URI: *sampleUri, + }: { + self: &duckv1.Destination{ + URI: sampleUri, + }, + inEdges: []*Edge{ + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-trigger", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: sampleUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + }, + }, + { + URI: *secondUri, + }: { + self: &duckv1.Destination{ + URI: secondUri, + }, + inEdges: []*Edge{ + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-trigger", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Trigger", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: secondUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + { + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + to: &Vertex{ + self: &duckv1.Destination{ + URI: secondUri, + }, + }, + from: &Vertex{ + self: &duckv1.Destination{ + Ref: &duckv1.KReference{ + Name: "my-broker", + Namespace: "default", + APIVersion: "eventing.knative.dev/v1", + Kind: "Broker", + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "no broker", + brokers: []eventingv1.Broker{}, + triggers: []eventingv1.Trigger{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-trigger", + Namespace: "default", + }, + Spec: eventingv1.TriggerSpec{ + Broker: "my-broker", + }, + }, + }, + wantErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + g := NewGraph() + for _, broker := range test.brokers { + g.AddBroker(broker) + } + for _, trigger := range test.triggers { + err := g.AddTrigger(trigger) + if err != nil { + assert.True(t, test.wantErr) + return + } + } + checkTestResult(t, g.vertices, test.expected) + }) + } +} + func TestAddChannel(t *testing.T) { channelWithEdge := &Vertex{ self: &duckv1.Destination{