1/*
2   Copyright The containerd Authors.
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17package events
18
19import (
20	"context"
21	"time"
22
23	"github.com/containerd/typeurl"
24	"github.com/gogo/protobuf/types"
25)
26
27// Envelope provides the packaging for an event.
28type Envelope struct {
29	Timestamp time.Time
30	Namespace string
31	Topic     string
32	Event     *types.Any
33}
34
35// Field returns the value for the given fieldpath as a string, if defined.
36// If the value is not defined, the second value will be false.
37func (e *Envelope) Field(fieldpath []string) (string, bool) {
38	if len(fieldpath) == 0 {
39		return "", false
40	}
41
42	switch fieldpath[0] {
43	// unhandled: timestamp
44	case "namespace":
45		return e.Namespace, len(e.Namespace) > 0
46	case "topic":
47		return e.Topic, len(e.Topic) > 0
48	case "event":
49		decoded, err := typeurl.UnmarshalAny(e.Event)
50		if err != nil {
51			return "", false
52		}
53
54		adaptor, ok := decoded.(interface {
55			Field([]string) (string, bool)
56		})
57		if !ok {
58			return "", false
59		}
60		return adaptor.Field(fieldpath[1:])
61	}
62	return "", false
63}
64
65// Event is a generic interface for any type of event
66type Event interface{}
67
68// Publisher posts the event.
69type Publisher interface {
70	Publish(ctx context.Context, topic string, event Event) error
71}
72
73// Forwarder forwards an event to the underlying event bus
74type Forwarder interface {
75	Forward(ctx context.Context, envelope *Envelope) error
76}
77
78// Subscriber allows callers to subscribe to events
79type Subscriber interface {
80	Subscribe(ctx context.Context, filters ...string) (ch <-chan *Envelope, errs <-chan error)
81}
82