Reworked serialization to split type/value serilization/deserialization
parent
8a973c38b5
commit
84aee24a21
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,111 @@
|
|||||||
|
package graphvent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EventExt struct {
|
||||||
|
Name string `"name"`
|
||||||
|
State string `"state"`
|
||||||
|
Parent *NodeID `"parent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventExt(parent *NodeID, name string) *EventExt {
|
||||||
|
return &EventExt{
|
||||||
|
Name: name,
|
||||||
|
State: "init",
|
||||||
|
Parent: parent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventStateSignal struct {
|
||||||
|
SignalHeader
|
||||||
|
Source NodeID
|
||||||
|
State string
|
||||||
|
Time time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (signal EventStateSignal) Permission() Tree {
|
||||||
|
return Tree{
|
||||||
|
SerializedType(StatusType): nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (signal EventStateSignal) String() string {
|
||||||
|
return fmt.Sprintf("EventStateSignal(%s, %s, %s, %+v)", signal.SignalHeader, signal.Source, signal.State, signal.Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventStateSignal(source NodeID, state string, t time.Time) *EventStateSignal {
|
||||||
|
return &EventStateSignal{
|
||||||
|
SignalHeader: NewSignalHeader(Up),
|
||||||
|
Source: source,
|
||||||
|
State: state,
|
||||||
|
Time: t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventControlSignal struct {
|
||||||
|
SignalHeader
|
||||||
|
Command string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventControlSignal(command string) *EventControlSignal {
|
||||||
|
return &EventControlSignal{
|
||||||
|
NewSignalHeader(Direct),
|
||||||
|
command,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (signal EventControlSignal) Permission() Tree {
|
||||||
|
return Tree{
|
||||||
|
SerializedType(EventControlSignalType): {
|
||||||
|
Hash("command", signal.Command): nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var transitions = map[string]struct{
|
||||||
|
from_state string
|
||||||
|
to_state string
|
||||||
|
}{
|
||||||
|
"start": {
|
||||||
|
"init",
|
||||||
|
"running",
|
||||||
|
},
|
||||||
|
"stop": {
|
||||||
|
"running",
|
||||||
|
"init",
|
||||||
|
},
|
||||||
|
"finish": {
|
||||||
|
"running",
|
||||||
|
"done",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ext *EventExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) (Messages, Changes) {
|
||||||
|
var messages Messages = nil
|
||||||
|
var changes Changes = nil
|
||||||
|
|
||||||
|
if signal.Direction() == Up && ext.Parent != nil {
|
||||||
|
messages = messages.Add(ctx, *ext.Parent, node, nil, signal)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch sig := signal.(type) {
|
||||||
|
case *EventControlSignal:
|
||||||
|
info, exists := transitions[sig.Command]
|
||||||
|
if exists == true {
|
||||||
|
if ext.State == info.from_state {
|
||||||
|
ext.State = info.to_state
|
||||||
|
messages = messages.Add(ctx, source, node, nil, NewSuccessSignal(sig.Id))
|
||||||
|
node.QueueSignal(time.Now(), NewEventStateSignal(node.ID, ext.State, time.Now()))
|
||||||
|
} else {
|
||||||
|
messages = messages.Add(ctx, source, node, nil, NewErrorSignal(sig.Id, "bad_state"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
messages = messages.Add(ctx, source, node, nil, NewErrorSignal(sig.Id, "bad_command"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages, changes
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package graphvent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEvent(t *testing.T) {
|
||||||
|
ctx := logTestContext(t, []string{"event", "listener"})
|
||||||
|
event_listener := NewListenerExt(100)
|
||||||
|
_, err := NewNode(ctx, nil, BaseNodeType, 100, nil, NewEventExt(nil, "Test Event"), event_listener)
|
||||||
|
fatalErr(t, err)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package graphvent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AuthInfo struct {
|
||||||
|
// The Node that issued the authorization
|
||||||
|
Identity ed25519.PublicKey
|
||||||
|
|
||||||
|
// Time the authorization was generated
|
||||||
|
Start time.Time
|
||||||
|
|
||||||
|
// Signature of Start + Principal with Identity private key
|
||||||
|
Signature []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorizationToken struct {
|
||||||
|
AuthInfo
|
||||||
|
|
||||||
|
// The private key generated by the client, encrypted with the servers public key
|
||||||
|
KeyEncrypted []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientAuthorization struct {
|
||||||
|
AuthInfo
|
||||||
|
|
||||||
|
// The private key generated by the client
|
||||||
|
Key ed25519.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authorization structs can be passed in a message that originated from a different node than the sender
|
||||||
|
type Authorization struct {
|
||||||
|
AuthInfo
|
||||||
|
|
||||||
|
// The public key generated for this authorization
|
||||||
|
Key ed25519.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Dest NodeID
|
||||||
|
Source ed25519.PublicKey
|
||||||
|
|
||||||
|
Authorization *Authorization
|
||||||
|
|
||||||
|
Signal Signal
|
||||||
|
Signature []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Messages []*Message
|
||||||
|
func (msgs Messages) Add(ctx *Context, dest NodeID, source *Node, authorization *ClientAuthorization, signal Signal) Messages {
|
||||||
|
msg, err := NewMessage(ctx, dest, source, authorization, signal)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
} else {
|
||||||
|
msgs = append(msgs, msg)
|
||||||
|
}
|
||||||
|
return msgs
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMessages(ctx *Context, dest NodeID, source *Node, authorization *ClientAuthorization, signals... Signal) Messages {
|
||||||
|
messages := Messages{}
|
||||||
|
for _, signal := range(signals) {
|
||||||
|
messages = messages.Add(ctx, dest, source, authorization, signal)
|
||||||
|
}
|
||||||
|
return messages
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMessage(ctx *Context, dest NodeID, source *Node, authorization *ClientAuthorization, signal Signal) (*Message, error) {
|
||||||
|
signal_ser, err := SerializeAny(ctx, signal)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ser, err := signal_ser.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_ser, err := dest.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
source_ser, err := source.ID.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sig_data := append(dest_ser, source_ser...)
|
||||||
|
sig_data = append(sig_data, ser...)
|
||||||
|
var message_auth *Authorization = nil
|
||||||
|
if authorization != nil {
|
||||||
|
sig_data = append(sig_data, authorization.Signature...)
|
||||||
|
message_auth = &Authorization{
|
||||||
|
authorization.AuthInfo,
|
||||||
|
authorization.Key.Public().(ed25519.PublicKey),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := source.Key.Sign(rand.Reader, sig_data, crypto.Hash(0))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Message{
|
||||||
|
Dest: dest,
|
||||||
|
Source: source.Key.Public().(ed25519.PublicKey),
|
||||||
|
Authorization: message_auth,
|
||||||
|
Signal: signal,
|
||||||
|
Signature: sig,
|
||||||
|
}, nil
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue