Skip to content

Commit

Permalink
adds async events
Browse files Browse the repository at this point in the history
  • Loading branch information
sebv committed Nov 6, 2023
1 parent 67467bc commit 24b351a
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 0 deletions.
165 changes: 165 additions & 0 deletions internal/imagerunner/async.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package imagerunner

import (
"encoding/json"
"fmt"
"log"

"github.com/santhosh-tekuri/jsonschema/v5"
)

var SCHEMA = `
{
"properties": {
"kind": {
"enum": [
"notice",
"log"
]
}
},
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "log"
}
}
},
"then": {
"properties": {
"lines": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
},
"additionalProperties": true
}
},
{
"if": {
"properties": {
"kind": {
"const": "notice"
}
}
},
"then": {
"properties": {
"logLines": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {
"enum": [
"info",
"warning",
"error"
]
},
"message": {
"type": "string"
}
}
}
}
},
"additionalProperties": true
}
}
],
"additionalProperties": true
}
`

const (
NOTICE = "notice"
LOG = "log"
)

type AsyncEventI interface {
GetKind() string
}

type AsyncEvent struct {
Kind string `json:"kind"`
}

func (a *AsyncEvent) GetKind() string {
return a.Kind
}

type LogLine struct {
Id string `json:"id"`
Message string `json:"message"`
}

type LogEvent struct {
AsyncEvent
Lines []LogLine `json:"lines"`
}

type Notice struct {
Message string `json:"message"`
}

type NoticeEvent struct {
AsyncEvent
Notices []Notice `json:"notices"`
}

type AsyncEventManager struct {
schema *jsonschema.Schema
}

func NewAsyncEventManager() (*AsyncEventManager, error) {
schema, err := jsonschema.CompileString("schema.json", SCHEMA)
if err != nil {
return nil, err
}

asyncEventManager := AsyncEventManager{
schema: schema,
}

return &asyncEventManager, nil
}

func (a *AsyncEventManager) ParseEvent(event string) (AsyncEventI, error) {
err := a.schema.Validate(event)
if err != nil {
return nil, err
}
v := AsyncEvent{}
if err := json.Unmarshal([]byte(event), &v); err != nil {
log.Fatal(err)
}

if v.GetKind() == LOG {
logEvent := LogEvent{}
if err := json.Unmarshal([]byte(event), &logEvent); err != nil {
log.Fatal(err)
}
return &logEvent, nil
} else if v.GetKind() == NOTICE {
noticeEvent := NoticeEvent{}
if err := json.Unmarshal([]byte(event), &noticeEvent); err != nil {
log.Fatal(err)
}
return &noticeEvent, nil
} else {
return nil, fmt.Errorf("unknown event type: %s", v.GetKind())
}
}
55 changes: 55 additions & 0 deletions internal/imagerunner/async_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package imagerunner

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestLogEvent(t *testing.T) {
manager, err := NewAsyncEventManager()
assert.NoError(t, err)

eventMsg := `{
"kind": "log",
"lines": [
{
"id": "1",
"message": "hello"
}
]
}`

event, err := manager.ParseEvent(eventMsg)
assert.NoError(t, err)
assert.Equal(t, "log", event.GetKind())

logEvent, ok := event.(*LogEvent)
assert.True(t, ok)
assert.Len(t, logEvent.Lines, 1)
assert.Equal(t, "1", logEvent.Lines[0].Id)
assert.Equal(t, "hello", logEvent.Lines[0].Message)
}

func TestNoticeEvent(t *testing.T) {
manager, err := NewAsyncEventManager()
assert.NoError(t, err)

eventMsg := `{
"kind": "notice",
"notices": [
{
"message": "hello"
}
]
}`

event, err := manager.ParseEvent(eventMsg)
assert.NoError(t, err)
assert.Equal(t, "notice", event.GetKind())

noticeEvent, ok := event.(*NoticeEvent)
assert.True(t, ok)
assert.Len(t, noticeEvent.Notices, 1)
assert.Equal(t, "hello", noticeEvent.Notices[0].Message)
}

0 comments on commit 24b351a

Please sign in to comment.