2021-03-01 16:08:40 +00:00
|
|
|
// 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) {
|
|
|
|
// ...
|
|
|
|
// ...
|
2021-03-11 05:34:36 +00:00
|
|
|
// ackMsg := []byte(fmt.Sprintf("confirmed from node: %v: messageID: %v\n---\n%s---", node, message.ID, out))
|
|
|
|
// return ackMsg, nil
|
2021-03-01 16:08:40 +00:00
|
|
|
// }
|
|
|
|
//
|
|
|
|
// ---
|
|
|
|
// 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.
|
2021-02-11 14:39:19 +00:00
|
|
|
|
|
|
|
package steward
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
2021-03-02 12:46:02 +00:00
|
|
|
"os"
|
2021-02-11 14:39:19 +00:00
|
|
|
"os/exec"
|
2021-03-02 12:46:02 +00:00
|
|
|
"path/filepath"
|
2021-03-11 11:07:09 +00:00
|
|
|
"time"
|
2021-02-11 14:39:19 +00:00
|
|
|
)
|
|
|
|
|
2021-03-11 16:14:43 +00:00
|
|
|
// Method is used to specify the actual function/method that
|
|
|
|
// is represented in a typed manner.
|
|
|
|
type Method string
|
|
|
|
|
2021-02-11 14:39:19 +00:00
|
|
|
// ------------------------------------------------------------
|
2021-03-01 16:08:40 +00:00
|
|
|
// The constants that will be used throughout the system for
|
|
|
|
// when specifying what kind of Method to send or work with.
|
|
|
|
const (
|
2021-03-11 16:14:43 +00:00
|
|
|
// Execute a CLI command in for example bash or cmd.
|
|
|
|
// This is a command type, so the output of the command executed
|
|
|
|
// will directly showed in the ACK message received.
|
|
|
|
// The data field is a slice of strings where the first string
|
|
|
|
// value should be the command, and the following the arguments.
|
2021-03-01 16:08:40 +00:00
|
|
|
CLICommand Method = "CLICommand"
|
2021-03-11 16:14:43 +00:00
|
|
|
// Execute a CLI command in for example bash or cmd.
|
|
|
|
// This is an event type, where a message will be sent to a
|
|
|
|
// node with the command to execute and an ACK will be replied
|
|
|
|
// if it was delivered succesfully. The output of the command
|
|
|
|
// ran will be delivered back to the node where it was initiated
|
|
|
|
// as a new message.
|
|
|
|
// The data field is a slice of strings where the first string
|
|
|
|
// value should be the command, and the following the arguments.
|
2021-03-11 11:07:09 +00:00
|
|
|
CLICommandRequest Method = "CLICommandRequest"
|
2021-03-11 16:14:43 +00:00
|
|
|
// Execute a CLI command in for example bash or cmd.
|
|
|
|
// This is an event type, where a message will be sent to a
|
|
|
|
// node with the command to execute and an ACK will be replied
|
|
|
|
// if it was delivered succesfully. The output of the command
|
|
|
|
// ran will be delivered back to the node where it was initiated
|
|
|
|
// as a new message.
|
2021-03-11 11:07:09 +00:00
|
|
|
// The NOSEQ method will process messages as they are recived,
|
|
|
|
// and the reply back will be sent as soon as the process is
|
|
|
|
// done. No order are preserved.
|
2021-03-11 16:14:43 +00:00
|
|
|
// The data field is a slice of strings where the first string
|
|
|
|
// value should be the command, and the following the arguments.
|
2021-03-11 11:07:09 +00:00
|
|
|
CLICommandRequestNOSEQ Method = "CLICommandRequestNOSEQ"
|
2021-03-11 16:14:43 +00:00
|
|
|
// Will generate a reply for a CLICommandRequest.
|
|
|
|
// This type is normally not used by the user when creating
|
|
|
|
// a message. It is used in creating the reply message with
|
|
|
|
// request messages. It is also used when defining a process to
|
|
|
|
// start up for receiving the CLICommand request messages.
|
|
|
|
// The data field is a slice of strings where the first string
|
|
|
|
// value should be the command, and the following the arguments.
|
2021-03-11 11:07:09 +00:00
|
|
|
CLICommandReply Method = "CLICommandReply"
|
2021-03-11 16:14:43 +00:00
|
|
|
// Send text logging to some host.
|
|
|
|
// A file with the full subject+hostName will be created on
|
|
|
|
// the receiving end.
|
|
|
|
// The data field is a slice of strings where the values of the
|
|
|
|
// slice will be written to the log file.
|
2021-03-01 16:08:40 +00:00
|
|
|
TextLogging Method = "TextLogging"
|
2021-03-11 16:14:43 +00:00
|
|
|
// Send Hello I'm here message.
|
2021-03-01 16:08:40 +00:00
|
|
|
SayHello Method = "SayHello"
|
2021-03-11 16:14:43 +00:00
|
|
|
// Error log methods to centralError node.
|
2021-03-01 16:08:40 +00:00
|
|
|
ErrorLog Method = "ErrorLog"
|
2021-03-11 05:34:36 +00:00
|
|
|
// Echo request will ask the subscriber for a
|
2021-03-11 16:14:43 +00:00
|
|
|
// reply generated as a new message, and sent back to where
|
|
|
|
// the initial request was made.
|
2021-03-11 05:34:36 +00:00
|
|
|
ECHORequest Method = "ECHORequest"
|
2021-03-11 11:07:09 +00:00
|
|
|
// Will generate a reply for a ECHORequest
|
2021-03-11 05:34:36 +00:00
|
|
|
ECHOReply Method = "ECHOReply"
|
2021-03-01 16:08:40 +00:00
|
|
|
)
|
2021-02-11 14:39:19 +00:00
|
|
|
|
2021-03-01 16:08:40 +00:00
|
|
|
// 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
|
2021-02-11 14:39:19 +00:00
|
|
|
func (m Method) GetMethodsAvailable() MethodsAvailable {
|
|
|
|
ma := MethodsAvailable{
|
2021-03-05 12:10:46 +00:00
|
|
|
methodhandlers: map[Method]methodHandler{
|
2021-03-11 11:51:16 +00:00
|
|
|
CLICommand: methodCLICommand{
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent: CommandACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
CLICommandRequest: methodCLICommandRequest{
|
2021-03-11 11:07:09 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
CLICommandRequestNOSEQ: methodCLICommandRequestNOSEQ{
|
2021-03-11 11:07:09 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
CLICommandReply: methodCLICommandReply{
|
2021-03-11 11:07:09 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
TextLogging: methodTextLogging{
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
SayHello: methodSayHello{
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent: EventNACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
ErrorLog: methodErrorLog{
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
ECHORequest: methodEchoRequest{
|
2021-03-11 05:34:36 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-03-11 11:51:16 +00:00
|
|
|
ECHOReply: methodEchoReply{
|
2021-03-11 05:34:36 +00:00
|
|
|
commandOrEvent: EventACK,
|
|
|
|
},
|
2021-02-11 14:39:19 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
return ma
|
|
|
|
}
|
|
|
|
|
2021-03-01 16:08:40 +00:00
|
|
|
// 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()
|
2021-03-05 12:10:46 +00:00
|
|
|
mh := ma.methodhandlers[method]
|
2021-03-01 16:08:40 +00:00
|
|
|
|
|
|
|
return mh
|
|
|
|
}
|
2021-02-11 14:39:19 +00:00
|
|
|
|
2021-03-11 16:14:43 +00:00
|
|
|
// The structure that works as a reference for all the methods and if
|
|
|
|
// they are of the command or event type, and also if it is a ACK or
|
|
|
|
// NACK message.
|
2021-02-11 14:39:19 +00:00
|
|
|
type MethodsAvailable struct {
|
2021-03-05 12:10:46 +00:00
|
|
|
methodhandlers map[Method]methodHandler
|
2021-02-11 14:39:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if exists will check if the Method is defined. If true the bool
|
|
|
|
// value will be set to true, and the methodHandler function for that type
|
|
|
|
// will be returned.
|
|
|
|
func (ma MethodsAvailable) CheckIfExists(m Method) (methodHandler, bool) {
|
2021-03-05 12:10:46 +00:00
|
|
|
mFunc, ok := ma.methodhandlers[m]
|
2021-02-11 14:39:19 +00:00
|
|
|
if ok {
|
2021-02-16 03:57:54 +00:00
|
|
|
// fmt.Printf("******THE TOPIC EXISTS: %v******\n", m)
|
2021-02-11 14:39:19 +00:00
|
|
|
return mFunc, true
|
|
|
|
} else {
|
2021-02-16 03:57:54 +00:00
|
|
|
// fmt.Printf("******THE TOPIC DO NOT EXIST: %v******\n", m)
|
2021-02-11 14:39:19 +00:00
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-18 13:27:53 +00:00
|
|
|
// ------------------------------------------------------------
|
|
|
|
// Subscriber method handlers
|
2021-02-11 14:39:19 +00:00
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
|
|
type methodHandler interface {
|
2021-03-08 13:09:14 +00:00
|
|
|
handler(proc process, message Message, node string) ([]byte, error)
|
2021-03-01 16:08:40 +00:00
|
|
|
getKind() CommandOrEvent
|
2021-02-11 14:39:19 +00:00
|
|
|
}
|
|
|
|
|
2021-03-01 16:08:40 +00:00
|
|
|
// -----
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodCLICommand struct {
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommand) getKind() CommandOrEvent {
|
2021-03-01 16:08:40 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
2021-02-11 14:39:19 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommand) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-02-11 14:39:19 +00:00
|
|
|
c := message.Data[0]
|
|
|
|
a := message.Data[1:]
|
|
|
|
cmd := exec.Command(c, a...)
|
|
|
|
//cmd.Stdout = os.Stdout
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("error: execution of command failed: %v\n", err)
|
|
|
|
}
|
|
|
|
|
2021-03-11 05:34:36 +00:00
|
|
|
ackMsg := []byte(fmt.Sprintf("confirmed from node: %v: messageID: %v\n---\n%s---", node, message.ID, out))
|
|
|
|
return ackMsg, nil
|
2021-02-11 14:39:19 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 13:27:53 +00:00
|
|
|
// -----
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodTextLogging struct {
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodTextLogging) getKind() CommandOrEvent {
|
2021-03-01 16:08:40 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
2021-02-11 14:39:19 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodTextLogging) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-02 12:46:02 +00:00
|
|
|
sub := Subject{
|
|
|
|
ToNode: string(message.ToNode),
|
|
|
|
CommandOrEvent: proc.subject.CommandOrEvent,
|
|
|
|
Method: message.Method,
|
|
|
|
}
|
|
|
|
|
2021-03-08 13:09:14 +00:00
|
|
|
logFile := filepath.Join(proc.configuration.SubscribersDataFolder, string(sub.name())+"-"+string(message.FromNode))
|
2021-03-02 12:46:02 +00:00
|
|
|
f, err := os.OpenFile(logFile, os.O_APPEND|os.O_RDWR|os.O_CREATE, os.ModeAppend)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("error: methodEventTextLogging.handler: failed to open file: %v\n", err)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
2021-02-11 14:39:19 +00:00
|
|
|
for _, d := range message.Data {
|
2021-03-02 12:46:02 +00:00
|
|
|
_, err := f.Write([]byte(d))
|
|
|
|
f.Sync()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("error: methodEventTextLogging.handler: failed to write to file: %v\n", err)
|
|
|
|
}
|
2021-02-11 14:39:19 +00:00
|
|
|
}
|
|
|
|
|
2021-03-11 05:34:36 +00:00
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
2021-02-11 14:39:19 +00:00
|
|
|
}
|
2021-02-18 13:27:53 +00:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodSayHello struct {
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodSayHello) getKind() CommandOrEvent {
|
2021-03-01 16:08:40 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
2021-02-18 13:27:53 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodSayHello) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-09 03:55:51 +00:00
|
|
|
|
2021-03-05 12:10:46 +00:00
|
|
|
log.Printf("<--- Received hello from %#v\n", message.FromNode)
|
2021-03-04 15:27:55 +00:00
|
|
|
|
|
|
|
// send the message to the procFuncCh which is running alongside the process
|
|
|
|
// and can hold registries and handle special things for an individual process.
|
|
|
|
proc.procFuncCh <- message
|
|
|
|
|
2021-03-11 05:34:36 +00:00
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
2021-02-18 13:27:53 +00:00
|
|
|
}
|
2021-02-24 14:43:31 +00:00
|
|
|
|
|
|
|
// ---
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodErrorLog struct {
|
2021-03-01 16:08:40 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodErrorLog) getKind() CommandOrEvent {
|
2021-03-01 16:08:40 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
2021-02-24 14:43:31 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodErrorLog) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-02 12:46:02 +00:00
|
|
|
log.Printf("<--- Received error from: %v, containing: %v", message.FromNode, message.Data)
|
2021-02-24 14:43:31 +00:00
|
|
|
return nil, nil
|
|
|
|
}
|
2021-03-11 05:34:36 +00:00
|
|
|
|
|
|
|
// ---
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodEchoRequest struct {
|
2021-03-11 05:34:36 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodEchoRequest) getKind() CommandOrEvent {
|
2021-03-11 05:34:36 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodEchoRequest) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-11 05:34:36 +00:00
|
|
|
log.Printf("<--- ECHO REQUEST received from: %v, containing: %v", message.FromNode, message.Data)
|
|
|
|
|
|
|
|
// Create a new message for the reply, and put it on the
|
|
|
|
// ringbuffer to be published.
|
|
|
|
newMsg := Message{
|
|
|
|
ToNode: message.FromNode,
|
|
|
|
Data: []string{""},
|
|
|
|
Method: ECHOReply,
|
|
|
|
Timeout: 3,
|
|
|
|
Retries: 3,
|
|
|
|
}
|
|
|
|
proc.newMessagesCh <- []subjectAndMessage{newSAM(newMsg)}
|
|
|
|
|
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodEchoReply struct {
|
2021-03-11 05:34:36 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodEchoReply) getKind() CommandOrEvent {
|
2021-03-11 05:34:36 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodEchoReply) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-11 05:34:36 +00:00
|
|
|
log.Printf("<--- ECHO Reply received from: %v, containing: %v", message.FromNode, message.Data)
|
|
|
|
|
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
|
|
|
}
|
2021-03-11 11:07:09 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
// ---
|
2021-03-11 11:07:09 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodCLICommandRequest struct {
|
2021-03-11 11:07:09 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommandRequest) getKind() CommandOrEvent {
|
2021-03-11 11:07:09 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommandRequest) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-11 11:07:09 +00:00
|
|
|
log.Printf("<--- CLICommand REQUEST received from: %v, containing: %v", message.FromNode, message.Data)
|
|
|
|
|
|
|
|
c := message.Data[0]
|
|
|
|
a := message.Data[1:]
|
|
|
|
cmd := exec.Command(c, a...)
|
|
|
|
//cmd.Stdout = os.Stdout
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("error: execution of command failed: %v\n", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
time.Sleep(time.Second * time.Duration(message.MethodTimeout))
|
|
|
|
|
|
|
|
// Create a new message for the reply, and put it on the
|
|
|
|
// ringbuffer to be published.
|
|
|
|
newMsg := Message{
|
|
|
|
ToNode: message.FromNode,
|
|
|
|
Data: []string{string(out)},
|
|
|
|
Method: CLICommandReply,
|
|
|
|
Timeout: 3,
|
|
|
|
Retries: 3,
|
|
|
|
}
|
|
|
|
fmt.Printf("** %#v\n", newMsg)
|
|
|
|
proc.newMessagesCh <- []subjectAndMessage{newSAM(newMsg)}
|
|
|
|
|
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
// --- methodCLICommandRequestNOSEQ
|
2021-03-11 11:07:09 +00:00
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodCLICommandRequestNOSEQ struct {
|
2021-03-11 11:07:09 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommandRequestNOSEQ) getKind() CommandOrEvent {
|
2021-03-11 11:07:09 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
// The NOSEQ method will process messages as they are recived,
|
|
|
|
// and the reply back will be sent as soon as the process is
|
|
|
|
// done. No order are preserved.
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommandRequestNOSEQ) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-11 11:07:09 +00:00
|
|
|
log.Printf("<--- CLICommand REQUEST received from: %v, containing: %v", message.FromNode, message.Data)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
|
|
|
c := message.Data[0]
|
|
|
|
a := message.Data[1:]
|
|
|
|
cmd := exec.Command(c, a...)
|
|
|
|
//cmd.Stdout = os.Stdout
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("error: execution of command failed: %v\n", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
time.Sleep(time.Second * time.Duration(message.MethodTimeout))
|
|
|
|
|
|
|
|
// Create a new message for the reply, and put it on the
|
|
|
|
// ringbuffer to be published.
|
|
|
|
newMsg := Message{
|
|
|
|
ToNode: message.FromNode,
|
|
|
|
Data: []string{string(out)},
|
|
|
|
Method: CLICommandReply,
|
|
|
|
Timeout: 3,
|
|
|
|
Retries: 3,
|
|
|
|
}
|
|
|
|
fmt.Printf("** %#v\n", newMsg)
|
|
|
|
proc.newMessagesCh <- []subjectAndMessage{newSAM(newMsg)}
|
|
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
type methodCLICommandReply struct {
|
2021-03-11 11:07:09 +00:00
|
|
|
commandOrEvent CommandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommandReply) getKind() CommandOrEvent {
|
2021-03-11 11:07:09 +00:00
|
|
|
return m.commandOrEvent
|
|
|
|
}
|
|
|
|
|
2021-03-11 11:51:16 +00:00
|
|
|
func (m methodCLICommandReply) handler(proc process, message Message, node string) ([]byte, error) {
|
2021-03-11 11:07:09 +00:00
|
|
|
fmt.Printf("### %v\n", message.Data)
|
|
|
|
|
|
|
|
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
|
|
|
|
return ackMsg, nil
|
|
|
|
}
|