From 35e0c121093399268b9135dbe52b023457d40d9e Mon Sep 17 00:00:00 2001 From: postmannen Date: Mon, 1 Mar 2021 17:08:40 +0100 Subject: [PATCH] removed the need for specifying the kind of event/command within a message. This is now picked from the generated subject --- example/toCentral-sayHello.json | 1 - example/toShip1.json | 1 - example/toShip1FromShip2.json | 1 - example/toShip1and2.json | 1 - example/toShip2.json | 1 - example/toShip2FromShip1.json | 1 - getmessagefromfile.go | 5 +- incommmingBuffer.db | Bin 32768 -> 32768 bytes message-and-subject.go | 2 - publisher-services.go | 9 +-- publisher.go | 4 +- ringbuffer.go | 2 +- server.go | 25 +++--- subscriberMethodTypes.go | 134 +++++++++++++++++++++++++------- 14 files changed, 130 insertions(+), 57 deletions(-) diff --git a/example/toCentral-sayHello.json b/example/toCentral-sayHello.json index 1959404..2037412 100644 --- a/example/toCentral-sayHello.json +++ b/example/toCentral-sayHello.json @@ -2,7 +2,6 @@ { "toNode": "central", "data": [""], - "commandOrEvent":"EventNACK", "method":"SayHello" } ] \ No newline at end of file diff --git a/example/toShip1.json b/example/toShip1.json index df8966d..757b2ab 100644 --- a/example/toShip1.json +++ b/example/toShip1.json @@ -3,7 +3,6 @@ "toNode": "ship1", "data": ["bash","-c","netstat -an|grep -i listen"], - "commandOrEvent":"CommandACK", "method":"CLICommand", "timeout":3, "retries":3 diff --git a/example/toShip1FromShip2.json b/example/toShip1FromShip2.json index df8966d..757b2ab 100644 --- a/example/toShip1FromShip2.json +++ b/example/toShip1FromShip2.json @@ -3,7 +3,6 @@ "toNode": "ship1", "data": ["bash","-c","netstat -an|grep -i listen"], - "commandOrEvent":"CommandACK", "method":"CLICommand", "timeout":3, "retries":3 diff --git a/example/toShip1and2.json b/example/toShip1and2.json index e576207..ca7f2e2 100644 --- a/example/toShip1and2.json +++ b/example/toShip1and2.json @@ -2,7 +2,6 @@ { "toNode": "*", "data": ["bash","-c","tree ../"], - "commandOrEvent":"CommandACK", "method":"CLICommand" } diff --git a/example/toShip2.json b/example/toShip2.json index 00602cc..f5533e6 100644 --- a/example/toShip2.json +++ b/example/toShip2.json @@ -2,7 +2,6 @@ { "toNode": "ship2", "data": ["bash","-c","tree ../"], - "commandOrEvent":"CommandACK", "method":"CLICommand" } diff --git a/example/toShip2FromShip1.json b/example/toShip2FromShip1.json index 6abeb6b..c0b67d6 100644 --- a/example/toShip2FromShip1.json +++ b/example/toShip2FromShip1.json @@ -3,7 +3,6 @@ "toNode": "ship2", "data": ["bash","-c","netstat -an|grep -i listen"], - "commandOrEvent":"CommandACK", "method":"CLICommand", "timeout":3, "retries":3 diff --git a/getmessagefromfile.go b/getmessagefromfile.go index a0b1d24..5cd7a78 100644 --- a/getmessagefromfile.go +++ b/getmessagefromfile.go @@ -67,13 +67,16 @@ func jsonFromFileData(b []byte) ([]subjectAndMessage, error) { } sam := []subjectAndMessage{} + // We need to create a tempory method type to look up the kind for the + // real method for the message. + var mt Method // Range over all the messages parsed from json, and create a subject for // each message. for _, m := range MsgSlice { s := Subject{ ToNode: string(m.ToNode), - CommandOrEvent: m.CommandOrEvent, + CommandOrEvent: mt.getHandler(m.Method).getKind(), Method: m.Method, } diff --git a/incommmingBuffer.db b/incommmingBuffer.db index 10585779c6adaf7419480e97b27e3493ec3ad4e6..463beb51bb23870ae72de8abf42129e8fcfb0809 100644 GIT binary patch delta 161 zcmZo@U}|V!n&2Q%!2kiFM;Ck2GB%uC?qJ0y!N|a1Y*4M_>7rz1Y%qDhg94-Bd&XLGqiC;y@V0{{!GH(vk% diff --git a/message-and-subject.go b/message-and-subject.go index 5d24d04..7f42513 100644 --- a/message-and-subject.go +++ b/message-and-subject.go @@ -16,8 +16,6 @@ type Message struct { // TODO: Change this to a slice instead...or maybe use an // interface type here to handle several data types ? Data []string `json:"data" yaml:"data"` - // The type of the message being sent - CommandOrEvent CommandOrEvent `json:"commandOrEvent" yaml:"commandOrEvent"` // method, what is this message doing, etc. CLI, syslog, etc. Method Method `json:"method" yaml:"method"` FromNode node diff --git a/publisher-services.go b/publisher-services.go index 337eaa8..06c46cf 100644 --- a/publisher-services.go +++ b/publisher-services.go @@ -47,11 +47,10 @@ func (s *sayHelloPublisher) createMsg(FromNode node) subjectAndMessage { Method: ErrorLog, }, Message: Message{ - ToNode: "errorCentral", - FromNode: FromNode, - Data: []string{m}, - CommandOrEvent: EventNACK, - Method: SayHello, + ToNode: "errorCentral", + FromNode: FromNode, + Data: []string{m}, + Method: SayHello, }, } diff --git a/publisher.go b/publisher.go index ae36b2e..2502489 100644 --- a/publisher.go +++ b/publisher.go @@ -49,8 +49,8 @@ func (s *server) processNewMessages(dbFileName string, newSAM chan []subjectAndM log.Printf("error: the method do not exist: %v\n", sam.Message.Method) continue } - if !s.commandOrEventAvailable.CheckIfExists(sam.Message.CommandOrEvent) { - log.Printf("error: the command or evnt do not exist: %v\n", sam.Message.CommandOrEvent) + if !s.commandOrEventAvailable.CheckIfExists(sam.Subject.CommandOrEvent) { + log.Printf("error: the command or evnt do not exist: %v\n", sam.Subject.CommandOrEvent) continue } diff --git a/ringbuffer.go b/ringbuffer.go index f27eb5b..2f9e9d7 100644 --- a/ringbuffer.go +++ b/ringbuffer.go @@ -110,7 +110,7 @@ func (r *ringBuffer) fillBuffer(inCh chan subjectAndMessage, samValueBucket stri for v := range inCh { // Check if the command or event exists in commandOrEvent.go - if !coeAvailable.CheckIfExists(v.Message.CommandOrEvent) { + if !coeAvailable.CheckIfExists(v.CommandOrEvent) { log.Printf("error: the event or command type do not exist, so this message will not be put on the buffer to be processed. Check the syntax used in the json file for the message. Allowed values are : %v\n", coeAvailableValues) fmt.Println() diff --git a/server.go b/server.go index 027c852..a416bb6 100644 --- a/server.go +++ b/server.go @@ -282,7 +282,7 @@ func (s *server) messageDeliverNats(proc process, message Message) { // If the message is an ACK type of message we must check that a // reply, and if it is not we don't wait here at all. fmt.Printf("---- MESSAGE : %v\n", message) - if message.CommandOrEvent == CommandACK || message.CommandOrEvent == EventACK { + if proc.subject.CommandOrEvent == CommandACK || proc.subject.CommandOrEvent == EventACK { // Wait up until 10 seconds for a reply, // continue and resend if to reply received. msgReply, err := subReply.NextMsg(time.Second * time.Duration(message.Timeout)) @@ -339,12 +339,12 @@ func (s *server) subscriberHandler(natsConn *nats.Conn, thisNode string, msg *na // that there was a problem like missing method to handle a specific // method etc. switch { - case message.CommandOrEvent == CommandACK || message.CommandOrEvent == EventACK: - log.Printf("info: subscriberHandler: message.CommandOrEvent received was = %v, preparing to call handler\n", message.CommandOrEvent) + case proc.subject.CommandOrEvent == CommandACK || proc.subject.CommandOrEvent == EventACK: + log.Printf("info: subscriberHandler: message.CommandOrEvent received was = %v, preparing to call handler\n", proc.subject.CommandOrEvent) mf, ok := s.methodsAvailable.CheckIfExists(message.Method) if !ok { // TODO: Check how errors should be handled here!!! - log.Printf("error: subscriberHandler: method type not available: %v\n", message.CommandOrEvent) + log.Printf("error: subscriberHandler: method type not available: %v\n", proc.subject.CommandOrEvent) } fmt.Printf("*** DEBUG: BEFORE CALLING HANDLER: ACK\n") @@ -386,12 +386,12 @@ func (s *server) subscriberHandler(natsConn *nats.Conn, thisNode string, msg *na err := fmt.Errorf("error: some testing error we want to send out") sendErrorLogMessage(s.newMessagesCh, node(thisNode), err) } - case message.CommandOrEvent == CommandNACK || message.CommandOrEvent == EventNACK: - log.Printf("info: subscriberHandler: message.CommandOrEvent received was = %v, preparing to call handler\n", message.CommandOrEvent) + case proc.subject.CommandOrEvent == CommandNACK || proc.subject.CommandOrEvent == EventNACK: + log.Printf("info: subscriberHandler: message.CommandOrEvent received was = %v, preparing to call handler\n", proc.subject.CommandOrEvent) mf, ok := s.methodsAvailable.CheckIfExists(message.Method) if !ok { // TODO: Check how errors should be handled here!!! - log.Printf("error: subscriberHandler: method type not available: %v\n", message.CommandOrEvent) + log.Printf("error: subscriberHandler: method type not available: %v\n", proc.subject.CommandOrEvent) } // since we don't send a reply for a NACK message, we don't care about the // out return when calling mf.handler @@ -403,7 +403,7 @@ func (s *server) subscriberHandler(natsConn *nats.Conn, thisNode string, msg *na log.Printf("error: subscriberHandler: failed to execute event: %v\n", err) } default: - log.Printf("info: did not find that specific type of command: %#v\n", message.CommandOrEvent) + log.Printf("info: did not find that specific type of command: %#v\n", proc.subject.CommandOrEvent) } } @@ -427,11 +427,10 @@ func createErrorMsgContent(FromNode node, theError error) subjectAndMessage { Method: ErrorLog, }, Message: Message{ - ToNode: "errorCentral", - FromNode: FromNode, - Data: []string{theError.Error()}, - CommandOrEvent: EventNACK, - Method: ErrorLog, + ToNode: "errorCentral", + FromNode: FromNode, + Data: []string{theError.Error()}, + Method: ErrorLog, }, } diff --git a/subscriberMethodTypes.go b/subscriberMethodTypes.go index 88b5d7b..b993ab4 100644 --- a/subscriberMethodTypes.go +++ b/subscriberMethodTypes.go @@ -1,8 +1,34 @@ -// NB: -// When adding new constants for the Method or CommandOrEvent -// types, make sure to also add them to the map -// Available since the this will be used -// to check if the message values are valid later on. +// The structure of how to add new method types to the system. +// ----------------------------------------------------------- +// All methods need 3 things: +// - A type definition +// - The type needs a getKind method +// - The type needs a handler method +// Overall structure example shown below. +// +// --- +// type methodCommandCLICommand struct { +// commandOrEvent CommandOrEvent +// } +// +// func (m methodCommandCLICommand) getKind() CommandOrEvent { +// return m.commandOrEvent +// } +// +// func (m methodCommandCLICommand) handler(s *server, message Message, node string) ([]byte, error) { +// ... +// ... +// outMsg := []byte(fmt.Sprintf("confirmed from node: %v: messageID: %v\n---\n%s---", node, message.ID, out)) +// return outMsg, nil +// } +// +// --- +// You also need to make a constant for the Method, and add +// that constant as the key in the map, where the value is +// the actual type you want to map it to with a handler method. +// You also specify if it is a Command or Event, and if it is +// ACK or NACK. +// Check out the existing code below for more examples. package steward @@ -15,24 +41,8 @@ import ( ) // ------------------------------------------------------------ - -// Method is used to specify the actual function/method that -// is represented in a typed manner. -type Method string - -func (m Method) GetMethodsAvailable() MethodsAvailable { - ma := MethodsAvailable{ - topics: map[Method]methodHandler{ - CLICommand: methodCommandCLICommand{}, - TextLogging: methodEventTextLogging{}, - SayHello: methodEventSayHello{}, - ErrorLog: methodEventErrorLog{}, - }, - } - - return ma -} - +// The constants that will be used throughout the system for +// when specifying what kind of Method to send or work with. const ( // Shell command to be executed via f.ex. bash CLICommand Method = "CLICommand" @@ -44,6 +54,49 @@ const ( ErrorLog Method = "ErrorLog" ) +// Method is used to specify the actual function/method that +// is represented in a typed manner. +type Method string + +// The mapping of all the method constants specified, what type +// it references, and the kind if it is an Event or Command, and +// if it is ACK or NACK. +// Allowed values for the commandOrEvent field are: +// - CommandACK +// - CommandNACK +// - EventACK +// - EventNack +func (m Method) GetMethodsAvailable() MethodsAvailable { + ma := MethodsAvailable{ + topics: map[Method]methodHandler{ + CLICommand: methodCommandCLICommand{ + commandOrEvent: CommandACK, + }, + TextLogging: methodEventTextLogging{ + commandOrEvent: EventACK, + }, + SayHello: methodEventSayHello{ + commandOrEvent: EventNACK, + }, + ErrorLog: methodEventErrorLog{ + commandOrEvent: EventACK, + }, + }, + } + + return ma +} + +// getHandler will check the methodsAvailable map, and return the +// method handler for the method given +// as input argument. +func (m Method) getHandler(method Method) methodHandler { + ma := m.GetMethodsAvailable() + mh := ma.topics[method] + + return mh +} + type MethodsAvailable struct { topics map[Method]methodHandler } @@ -68,9 +121,18 @@ func (ma MethodsAvailable) CheckIfExists(m Method) (methodHandler, bool) { type methodHandler interface { handler(server *server, message Message, node string) ([]byte, error) + getKind() CommandOrEvent } -type methodCommandCLICommand struct{} +// ----- + +type methodCommandCLICommand struct { + commandOrEvent CommandOrEvent +} + +func (m methodCommandCLICommand) getKind() CommandOrEvent { + return m.commandOrEvent +} func (m methodCommandCLICommand) handler(s *server, message Message, node string) ([]byte, error) { // Since the command to execute is at the first position in the @@ -91,7 +153,13 @@ func (m methodCommandCLICommand) handler(s *server, message Message, node string // ----- -type methodEventTextLogging struct{} +type methodEventTextLogging struct { + commandOrEvent CommandOrEvent +} + +func (m methodEventTextLogging) getKind() CommandOrEvent { + return m.commandOrEvent +} func (m methodEventTextLogging) handler(s *server, message Message, node string) ([]byte, error) { for _, d := range message.Data { @@ -104,7 +172,13 @@ func (m methodEventTextLogging) handler(s *server, message Message, node string) // ----- -type methodEventSayHello struct{} +type methodEventSayHello struct { + commandOrEvent CommandOrEvent +} + +func (m methodEventSayHello) getKind() CommandOrEvent { + return m.commandOrEvent +} func (m methodEventSayHello) handler(s *server, message Message, node string) ([]byte, error) { log.Printf("<--- Received hello from %v \n", message.FromNode) @@ -126,7 +200,13 @@ func (m methodEventSayHello) handler(s *server, message Message, node string) ([ // --- -type methodEventErrorLog struct{} +type methodEventErrorLog struct { + commandOrEvent CommandOrEvent +} + +func (m methodEventErrorLog) getKind() CommandOrEvent { + return m.commandOrEvent +} func (m methodEventErrorLog) handler(s *server, message Message, node string) ([]byte, error) { log.Printf("----------------------------------------------------------------------------..\n")