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