eventgrid

package
v0.0.0-...-23aaec9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2023 License: MIT Imports: 12 Imported by: 2

Documentation

Overview

Package eventgrid aims to provide a shim for easily working with Event Grid from a gobuffalo application. It will frequently be utilized by the code generated for extending your app to receive Event Grid Events.

Index

Examples

Constants

View Source
const CacheDefaultMaxDepth uint = 100000

CacheDefaultMaxDepth is the maximum number of Events that will be stored here, before they begin automatically removed.

View Source
const CacheDefaultTTL = time.Hour * 48

CacheDefaultTTL is the default length of time that each event will live in the cache before it is aut

View Source
const EventTypeWildcard = "all"

EventTypeWildcard is a special-case value that can be used when subscribing to an EventGrid topic.

View Source
const MaxEventSize = 64 * 1024

MaxEventSize is the largest number of bytes permitted for an individual Event Grid Event.

View Source
const MaxPayloadSize = 1024 * 1024

MaxPayloadSize is the largest number of bytes permitted in the body of a request sent to an Event Grid Topic.

Variables

This section is empty.

Functions

func ReceiveSubscriptionValidationRequest

func ReceiveSubscriptionValidationRequest(c buffalo.Context, e Event) error

ReceiveSubscriptionValidationRequest will echo the ValidateCode sent in the request back to the Event Grid Topic seeking subscription validation.

func RegisterSubscriber

func RegisterSubscriber(app *buffalo.App, route string, s Subscriber) *buffalo.App

RegisterSubscriber updates a `buffalo.App` to route requests to a particular subscriber. This method is the spiritual equivalent of `App.Resource`: https://godoc.org/github.com/gobuffalo/buffalo#App.Resource

func SubscriptionValidationMiddleware

func SubscriptionValidationMiddleware(next buffalo.Handler) buffalo.Handler

SubscriptionValidationMiddleware provides a `buffalo.Handler` which will triage all incoming requests to either submit it for event processing, or echo back the response the server expects to validate a subscription.

func SuccessStatusCodes

func SuccessStatusCodes() map[int]struct{}

SuccessStatusCodes returns an unordered list of HTTP Status Codes that should be considered having been handled correctly. Event Grid Topics will retry on any HTTP Status Code that is not in this list.

Types

type App

type App buffalo.App

App extends the functionality of a normal buffalo.App with actions specific to Event Grid. Specifically, it seeks to allow quick and easy register a Group of actions for processing and reasoning.

func (*App) Subscriber

func (a *App) Subscriber(p string, s Subscriber) *buffalo.App

Subscriber creates a group of mappings (*buffalo.App) between a Subscriber interface implementation and the appropriate REST paths.

type BaseSubscriber

type BaseSubscriber struct{}

BaseSubscriber will always respond to request by returning an HTTP 404 status.

func (BaseSubscriber) List

func (s BaseSubscriber) List(c buffalo.Context) error

List responds with an HTTP NotFound Status Code.

func (BaseSubscriber) New

New responds with an HTTP NotFound Status Code.

func (BaseSubscriber) Receive

func (s BaseSubscriber) Receive(c buffalo.Context) error

Receive responds with an HTTP NotFound Status Code.

func (BaseSubscriber) Show

func (s BaseSubscriber) Show(c buffalo.Context) error

Show responds with an HTTP NotFound Status Code.

type Cache

type Cache struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Cache will hold a set number of events for a short amount of time.

Example
package main

import (
	"fmt"

	"github.com/Azure/buffalo-azure/sdk/eventgrid"
)

func main() {
	myCache := &eventgrid.Cache{}

	myCache.Add(eventgrid.Event{
		EventType: "Contoso.Buffalo.CacheProd",
	})
	myCache.Add(eventgrid.Event{
		EventType: "Microsoft.Storage.BlobCreated",
	})

	fmt.Println(myCache.List())

	myCache.Clear()
	fmt.Println(myCache.List())
}
Output:

[{   [] Microsoft.Storage.BlobCreated   } {   [] Contoso.Buffalo.CacheProd   }]
[]

func (*Cache) Add

func (c *Cache) Add(e Event)

Add creates an entry in the `Cache`.

func (*Cache) Clear

func (c *Cache) Clear()

Clear removes all entries from the Event Cache.

func (*Cache) List

func (c *Cache) List() (results []Event)

List reads all of the Events in the cache at a particular moment.

func (*Cache) MaxDepth

func (c *Cache) MaxDepth() uint

MaxDepth gets the largest number of `Event` instances that this `Cache` will hold before automatically deleting the least recently arriving ones.

func (*Cache) SetMaxDepth

func (c *Cache) SetMaxDepth(depth uint)

SetMaxDepth changes the largest number of `Event` instances that this `Cache`. will hold.

Example
package main

import (
	"fmt"

	"github.com/Azure/buffalo-azure/sdk/eventgrid"
)

func main() {
	myCache := &eventgrid.Cache{}
	myCache.SetMaxDepth(2)

	fmt.Println(len(myCache.List()))
	myCache.Add(eventgrid.Event{})
	fmt.Println(len(myCache.List()))
	myCache.Add(eventgrid.Event{})
	fmt.Println(len(myCache.List()))
	myCache.Add(eventgrid.Event{})
	fmt.Println(len(myCache.List()))

}
Output:

0
1
2
2

func (*Cache) SetTTL

func (c *Cache) SetTTL(d time.Duration)

SetTTL sets the amount of time each event will last before being cleared from the `Cache`.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Azure/buffalo-azure/sdk/eventgrid"
)

func main() {
	myCache := &eventgrid.Cache{}
	myCache.SetTTL(time.Second)

	myCache.Add(eventgrid.Event{
		EventType: "Microsoft.Storage.BlobCreated",
	})
	fmt.Println(len(myCache.List()))

	<-time.After(2 * time.Second)
	fmt.Println(len(myCache.List()))

}
Output:

1
0

func (*Cache) TTL

func (c *Cache) TTL() time.Duration

TTL get the amount of time each event will last before being cleared from the `Cache`.

type Context

type Context struct {
	buffalo.Context
	// contains filtered or unexported fields
}

Context extends `buffalo.Context` to ease communication between a Request Handler and an Event Grid Topic.

Example
package main

import (
	"errors"
	"fmt"
	"net/http"
	"sync"

	"github.com/Azure/buffalo-azure/sdk/eventgrid"
	"github.com/gobuffalo/buffalo"
)

func main() {
	ctx := eventgrid.NewContext(&buffalo.DefaultContext{})

	var wg sync.WaitGroup

	succeed := func(c buffalo.Context) error {
		defer wg.Done()

		c.Response().WriteHeader(http.StatusOK)

		return nil
	}

	fail := func(c buffalo.Context) error {
		defer wg.Done()
		return c.Error(http.StatusInternalServerError, errors.New("unknown error"))
	}

	wg.Add(3)
	go succeed(ctx)
	go fail(ctx)
	go succeed(ctx)
	wg.Wait()

	fmt.Println(ctx.ResponseHasFailure())

}
Output:

true

func NewContext

func NewContext(parent buffalo.Context) (created *Context)

NewContext initializes a new `eventgrid.Context`.

func (*Context) Error

func (c *Context) Error(status int, err error) error

func (*Context) Flash

func (c *Context) Flash() *buffalo.Flash

Flash fetches an unused instance of Flash.

func (*Context) Redirect

func (c *Context) Redirect(status int, url string, args ...interface{}) error

Redirect informs the Event Grid Topic that an Event was unable to be handled.

func (*Context) Render

func (c *Context) Render(status int, r render.Renderer) error

Render discards the body that is populated by the renderer, but takes the status into consideration for how to communicate success or failue to an Event Grid Topic.

func (*Context) Response

func (c *Context) Response() http.ResponseWriter

Response fulfills Buffalo's requirement to allow folks to write a response, but it actually just throws away anything you write to it.

func (*Context) ResponseHasFailure

func (c *Context) ResponseHasFailure() bool

ResponseHasFailure indicates whether or not any Status Codes not indicating success to an Event Grid Topic were published to this Context's `ResponseWriter`.

type Event

type Event struct {
	ID              string          `json:"id"`
	Topic           string          `json:"topic"`
	Subject         string          `json:"subject"`
	Data            json.RawMessage `json:"data"`
	EventType       string          `json:"eventType"`
	EventTime       string          `json:"eventTime"`
	MetadataVersion string          `json:"metadataVersion"`
	DataVersion     string          `json:"dataVersion"`
}

Event allows for easy processing of Event Grid Events.

External documentation on Event Grid Events can be found here: https://docs.microsoft.com/en-us/azure/event-grid/event-schema

func (Event) UnmarshalData

func (e Event) UnmarshalData(v interface{}) error

UnmarshalData attempts to read the value associated with the "data" property into the value pointed to by v.

type EventHandler

type EventHandler func(buffalo.Context, Event) error

EventHandler extends the definition of buffalo.Handler to include an `Event`.

type ResponseWriter

type ResponseWriter struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ResponseWriter looks like an `http.ResponseWriter`, but

func NewResponseWriter

func NewResponseWriter() *ResponseWriter

NewResponseWriter initializes a ResponseWriter which will merge the responses of several Event Grid Handlers.

func (*ResponseWriter) HasFailure

func (w *ResponseWriter) HasFailure() bool

HasFailure evaluates whether or not any Status Headers have been written to this Context that are not in the result of calling `SuccessStatusCodes`.

func (*ResponseWriter) Header

func (w *ResponseWriter) Header() http.Header

Header gets the Headers associated with this Response writer.

func (*ResponseWriter) SetFailure

func (w *ResponseWriter) SetFailure()

SetFailure indicates that a Status Code outside of ones an Event Grid Topic accepts as meaning not to retry was present in one of Handlers writing to this ResponseWriter.

func (*ResponseWriter) Write

func (w *ResponseWriter) Write(x []byte) (int, error)

Write takes a message to write to a Response, and does nothing with it.

func (*ResponseWriter) WriteHeader

func (w *ResponseWriter) WriteHeader(s int)

WriteHeader takes an HTTP Status Code and informs the `Context` as to whether or not there was an error processing it.

type SimpleSubscriber

type SimpleSubscriber struct {
	Subscriber
	EventHandler
}

SimpleSubscriber only fulfills the "Receive" portion of the Subscriber interface. It is equivalent to creating a `TypeDispatchSubscriber` but only binding an `EventHandler` to the `EventTypeWildcard` type.

func (SimpleSubscriber) Receive

func (s SimpleSubscriber) Receive(c buffalo.Context) (err error)

Receive unmarshals the body of the request as an Event Grid Event, and hands it to the EventHandler for further processing.

type Subscriber

type Subscriber interface {
	List(buffalo.Context) error
	New(buffalo.Context) error
	Receive(buffalo.Context) error
	Show(buffalo.Context) error
}

Subscriber allows for quick implementation of RESTful actions while working with Event Grid events.

type SubscriptionValidationRequest

type SubscriptionValidationRequest struct {
	ValidationCode uuid.UUID `json:"validationCode,omitempty"`
}

SubscriptionValidationRequest allows for easy unmarshaling of the first event sent by an Event Grid Topic.

type TypeDispatchSubscriber

type TypeDispatchSubscriber struct {
	Subscriber
	// contains filtered or unexported fields
}

TypeDispatchSubscriber offers an indirection for calling a function when an Event Grid Event has a particular value for the property `eventType`. While the `EventHandler` interface does not itself has

func NewTypeDispatchSubscriber

func NewTypeDispatchSubscriber(parent Subscriber) (created *TypeDispatchSubscriber)

NewTypeDispatchSubscriber initializes a new empty TypeDispathSubscriber.

func (*TypeDispatchSubscriber) Bind

Bind ties together an Event Type identifier string and a function that knows how to handle it.

func (TypeDispatchSubscriber) Handler

func (s TypeDispatchSubscriber) Handler(eventType string) (handler EventHandler, ok bool)

Handler gets the EventHandler meant to process a particular Event Grid Event Type.

func (TypeDispatchSubscriber) NormalizeEventType

func (s TypeDispatchSubscriber) NormalizeEventType(eventType string) string

NormalizeEventType applies casing rules

func (TypeDispatchSubscriber) Receive

Receive is a `buffalo.Handler` which inspects a request sent from an Event Grid Topic, and triages each event in the batch by the "eventType" property in the Event metadata. If handler for an Event's type is present, the event will be passed to that Handler. Should no Handler be specifically bound to that Event Type string, a default Handler is called. When no Handler is found, even a default, an HTTP 400 Status Code is returned. Each Event is handed to exactly one Handler. If even one of those handlers returns a response code that is not an HTTP 200 OR 201, this handler will return an HTTP 500.

Example
var mySubscriber eventgrid.Subscriber
mySubscriber = eventgrid.BaseSubscriber{}
mySubscriber = eventgrid.NewTypeDispatchSubscriber(mySubscriber).Bind("Microsoft.Storage.BlobCreated", func(c buffalo.Context, e eventgrid.Event) (err error) {
	_, err = fmt.Println(e.ID)
	return
})

req, err := http.NewRequest(http.MethodPost, "localhost", bytes.NewReader([]byte(`[{
	"topic": "/subscriptions/{subscription-id}/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/xstoretestaccount",
	"subject": "/blobServices/default/containers/oc2d2817345i200097container/blobs/oc2d2817345i20002296blob",
	"eventType": "Microsoft.Storage.BlobCreated",
	"eventTime": "2017-06-26T18:41:00.9584103Z",
	"id": "831e1650-001e-001b-66ab-eeb76e069631",
	"data": {
		"api": "PutBlockList",
		"clientRequestId": "6d79dbfb-0e37-4fc4-981f-442c9ca65760",
		"requestId": "831e1650-001e-001b-66ab-eeb76e000000",
		"eTag": "0x8D4BCC2E4835CD0",
		"contentType": "application/octet-stream",
		"contentLength": 524288,
		"blobType": "BlockBlob",
		"url": "https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob",
		"sequencer": "00000000000004420000000000028963",
		"storageDiagnostics": {
		"batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"
		}
	},
	"dataVersion": "",
	"metadataVersion": "1"
}]`)))
if err != nil {
	fmt.Println(err)
	return
}
req.Header.Add("Content-Type", "application/json")

ctx := NewMockContext(req)

err = mySubscriber.Receive(ctx)
if err != nil {
	fmt.Println(err)
	return
}
Output:

831e1650-001e-001b-66ab-eeb76e069631

func (*TypeDispatchSubscriber) Unbind

Unbind removes the mapping between an Event Type string and the associated EventHandler, if such a mapping exists.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL