Added more ICCC commands
+ Added ICCC command for register a host + Added ICCC command for register a command i.e. listener + Added ICCC command for getting a number from NumGen
This commit is contained in:
parent
326eb9ba7a
commit
6e111b7517
45
ICCC/ICCCRegisterCommand.go
Normal file
45
ICCC/ICCCRegisterCommand.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package ICCC
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/SommerEngineering/Ocean/ICCC/SystemMessages"
|
||||||
|
"github.com/SommerEngineering/Ocean/Log"
|
||||||
|
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The receiver function for the ICCC message, that registers a command.
|
||||||
|
func ICCCRegisterCommand(data map[string][]string) (result map[string][]string) {
|
||||||
|
|
||||||
|
// Recover from errors:
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityUnknown, LM.ImpactUnknown, LM.MessageNamePARSE, fmt.Sprintf("Was not able to execute the ICCC register command message. %s", err))
|
||||||
|
result = make(map[string][]string, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Converts the HTTP form data into an object:
|
||||||
|
_, _, obj := Data2Message(SystemMessages.ICCCRegisterListener{}, data)
|
||||||
|
|
||||||
|
// Was it possible to convert the data?
|
||||||
|
if obj != nil {
|
||||||
|
// Cast the object to the right type:
|
||||||
|
messageData := obj.(SystemMessages.ICCCRegisterListener)
|
||||||
|
|
||||||
|
// Provide a log entry:
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Should register another command.`, `channel=`+messageData.Channel, `command=`+messageData.Command, `IPAddressPort=`+messageData.IPAddressPort, fmt.Sprintf(`isActive=%v`, messageData.IsActive))
|
||||||
|
|
||||||
|
// Execute the command:
|
||||||
|
registerCommand2Database(messageData.Channel, messageData.Command, messageData.IPAddressPort, messageData.IsActive)
|
||||||
|
|
||||||
|
// An answer is necessary:
|
||||||
|
return Message2Data(``, ``, SystemMessages.AnswerACK)
|
||||||
|
} else {
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Was not able to create the message.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// In any other error case:
|
||||||
|
result = make(map[string][]string, 0)
|
||||||
|
return
|
||||||
|
}
|
45
ICCC/ICCCRegisterHost.go
Normal file
45
ICCC/ICCCRegisterHost.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package ICCC
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/SommerEngineering/Ocean/ICCC/SystemMessages"
|
||||||
|
"github.com/SommerEngineering/Ocean/Log"
|
||||||
|
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The receiver function for the ICCC message, that registers a host.
|
||||||
|
func ICCCRegisterHost(data map[string][]string) (result map[string][]string) {
|
||||||
|
|
||||||
|
// Recover from errors:
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityUnknown, LM.ImpactUnknown, LM.MessageNamePARSE, fmt.Sprintf("Was not able to execute the ICCC register host message. %s", err))
|
||||||
|
result = make(map[string][]string, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Converts the HTTP form data into an object:
|
||||||
|
_, _, obj := Data2Message(SystemMessages.ICCCRegisterHost{}, data)
|
||||||
|
|
||||||
|
// Was it possible to convert the data?
|
||||||
|
if obj != nil {
|
||||||
|
// Cast the object to the right type:
|
||||||
|
messageData := obj.(SystemMessages.ICCCRegisterHost)
|
||||||
|
|
||||||
|
// Provide a log entry:
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Should register another host.`, messageData.Hostname, messageData.IPAddressPort)
|
||||||
|
|
||||||
|
// Execute the command:
|
||||||
|
registerHost2Database(messageData.Hostname, messageData.IPAddressPort)
|
||||||
|
|
||||||
|
// An answer is necessary:
|
||||||
|
return Message2Data(``, ``, SystemMessages.AnswerACK)
|
||||||
|
} else {
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Was not able to create the message.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// In any other error case:
|
||||||
|
result = make(map[string][]string, 0)
|
||||||
|
return
|
||||||
|
}
|
@ -25,5 +25,5 @@ func init() {
|
|||||||
initDB()
|
initDB()
|
||||||
|
|
||||||
// Register this server to the listener (if not present):
|
// Register this server to the listener (if not present):
|
||||||
registerHost2Database()
|
registerThisHost2Database()
|
||||||
}
|
}
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
package ICCC
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
|
|
||||||
"github.com/SommerEngineering/Ocean/Log"
|
|
||||||
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
|
||||||
"gopkg.in/mgo.v2/bson"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The internal function to register a command to ICCC.
|
|
||||||
func register2Database(channel, command string) {
|
|
||||||
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Register this ICCC command in to the database.`, `channel=`+channel, `command=`+command)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Case: Exist and active :)
|
|
||||||
//
|
|
||||||
emptyEntry := Scheme.Listener{}
|
|
||||||
selection := bson.D{{`Channel`, channel}, {`Command`, command}, {`IPAddressPort`, correctAddressWithPort}, {`IsActive`, true}}
|
|
||||||
count1, _ := collectionListener.Find(selection).Count()
|
|
||||||
|
|
||||||
if count1 == 1 {
|
|
||||||
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.SeverityHigh, LM.ImpactHigh, LM.MessageNameSTARTUP, `This ICCC command is already known and active.`, `Please shutdown the system next time!`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Case: Exist but not active
|
|
||||||
//
|
|
||||||
selection = bson.D{{`Channel`, channel}, {`Command`, command}, {`IPAddressPort`, correctAddressWithPort}, {`IsActive`, false}}
|
|
||||||
notActiveEntry := Scheme.Listener{}
|
|
||||||
collectionListener.Find(selection).One(¬ActiveEntry)
|
|
||||||
|
|
||||||
if notActiveEntry != emptyEntry {
|
|
||||||
notActiveEntry.IsActive = true
|
|
||||||
collectionListener.Update(selection, notActiveEntry)
|
|
||||||
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.SeverityNone, LM.ImpactNone, LM.MessageNameSTARTUP, `This ICCC command is already known but it was not active.`, `The command is active now!`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Case: Not exist
|
|
||||||
//
|
|
||||||
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityCritical, LM.ImpactNone, LM.MessageNameCONFIGURATION, `This ICCC command is not known.`, `Create now a new entry!`)
|
|
||||||
|
|
||||||
entry := Scheme.Listener{}
|
|
||||||
entry.Channel = channel
|
|
||||||
entry.Command = command
|
|
||||||
entry.IsActive = true
|
|
||||||
entry.IPAddressPort = correctAddressWithPort
|
|
||||||
|
|
||||||
if err := collectionListener.Insert(entry); err != nil {
|
|
||||||
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityCritical, LM.ImpactCritical, LM.MessageNameDATABASE, `It was not possible to add this ICCC command!`, err.Error(), `channel=`+channel, `command=`+command)
|
|
||||||
} else {
|
|
||||||
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, `This ICCC command is now known and active.`)
|
|
||||||
}
|
|
||||||
}
|
|
44
ICCC/RegisterCommand2Database.go
Normal file
44
ICCC/RegisterCommand2Database.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package ICCC
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
|
||||||
|
"github.com/SommerEngineering/Ocean/Log"
|
||||||
|
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
||||||
|
"gopkg.in/mgo.v2/bson"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The internal function to register a command to ICCC.
|
||||||
|
func registerCommand2Database(channel, command, ipAddressPort string, isActive bool) {
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Register this ICCC command in to the database.`, `channel=`+channel, `command=`+command, `IPAddressPort=`+ipAddressPort, fmt.Sprintf("isActive=%v", isActive))
|
||||||
|
|
||||||
|
entry := Scheme.Listener{}
|
||||||
|
entry.Channel = channel
|
||||||
|
entry.Command = command
|
||||||
|
entry.IsActive = isActive
|
||||||
|
entry.IPAddressPort = ipAddressPort
|
||||||
|
|
||||||
|
//
|
||||||
|
// Case: Exists?
|
||||||
|
//
|
||||||
|
selection := bson.D{{`Channel`, channel}, {`Command`, command}, {`IPAddressPort`, ipAddressPort}}
|
||||||
|
count1, _ := collectionListener.Find(selection).Count()
|
||||||
|
if count1 == 1 {
|
||||||
|
//
|
||||||
|
// Case: Exist but maybe not active
|
||||||
|
//
|
||||||
|
collectionListener.Update(selection, entry)
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, `Updating the existing ICCC command.`, `channel=`+channel, `command=`+command, `IPAddressPort=`+ipAddressPort)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Case: Not exist
|
||||||
|
//
|
||||||
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityCritical, LM.ImpactNone, LM.MessageNameCONFIGURATION, `This ICCC command is not known.`, `Create now a new entry!`, `channel=`+channel, `command=`+command, `IPAddressPort=`+ipAddressPort)
|
||||||
|
if err := collectionListener.Insert(entry); err != nil {
|
||||||
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityCritical, LM.ImpactCritical, LM.MessageNameDATABASE, `It was not possible to add this ICCC command!`, err.Error(), `channel=`+channel, `command=`+command, `IPAddressPort=`+ipAddressPort)
|
||||||
|
} else {
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, `This ICCC command is now known and active.`, `channel=`+channel, `command=`+command, `IPAddressPort=`+ipAddressPort)
|
||||||
|
}
|
||||||
|
}
|
@ -4,17 +4,16 @@ import (
|
|||||||
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
|
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
|
||||||
"github.com/SommerEngineering/Ocean/Log"
|
"github.com/SommerEngineering/Ocean/Log"
|
||||||
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
||||||
"github.com/SommerEngineering/Ocean/Tools"
|
|
||||||
"gopkg.in/mgo.v2/bson"
|
"gopkg.in/mgo.v2/bson"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Function to register this server to the ICCC.
|
// Function to register a server to the ICCC.
|
||||||
func registerHost2Database() {
|
func registerHost2Database(hostname, ipAddressPort string) {
|
||||||
|
|
||||||
// Create the host entry:
|
// Create the host entry:
|
||||||
host := Scheme.Host{}
|
host := Scheme.Host{}
|
||||||
host.Hostname = Tools.ThisHostname()
|
host.Hostname = hostname
|
||||||
host.IPAddressPort = correctAddressWithPort
|
host.IPAddressPort = ipAddressPort
|
||||||
|
|
||||||
// The query to find already existing entries:
|
// The query to find already existing entries:
|
||||||
selection := bson.D{{`Hostname`, host.Hostname}, {`IPAddressPort`, host.IPAddressPort}}
|
selection := bson.D{{`Hostname`, host.Hostname}, {`IPAddressPort`, host.IPAddressPort}}
|
||||||
|
12
ICCC/RegisterLocalCommand2Database.go
Normal file
12
ICCC/RegisterLocalCommand2Database.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package ICCC
|
||||||
|
|
||||||
|
// The internal function to register a local command to ICCC.
|
||||||
|
func registerLocalCommand2Database(channel, command string) {
|
||||||
|
/*
|
||||||
|
Cannot use here the ICCC command to register this command.
|
||||||
|
Because, this host is maybe the first one. In that case,
|
||||||
|
there would be no server which can execute the ICCC command.
|
||||||
|
Therefore, every Ocean server registers the own commans directly.
|
||||||
|
*/
|
||||||
|
registerCommand2Database(channel, command, correctAddressWithPort, true)
|
||||||
|
}
|
16
ICCC/RegisterThisHost2Database.go
Normal file
16
ICCC/RegisterThisHost2Database.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package ICCC
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/SommerEngineering/Ocean/Tools"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Function to register this server to the ICCC.
|
||||||
|
func registerThisHost2Database() {
|
||||||
|
/*
|
||||||
|
Cannot use here the ICCC command to register this host.
|
||||||
|
Because, this host is maybe the first one. In that case,
|
||||||
|
there would be no server which can execute the ICCC command.
|
||||||
|
Therefore, every Ocean server registers the own host directly.
|
||||||
|
*/
|
||||||
|
registerHost2Database(Tools.ThisHostname(), correctAddressWithPort)
|
||||||
|
}
|
@ -12,7 +12,7 @@ func Registrar(channel, command string, callback func(data map[string][]string)
|
|||||||
defer listenersLock.Unlock()
|
defer listenersLock.Unlock()
|
||||||
|
|
||||||
// Write the command to the database:
|
// Write the command to the database:
|
||||||
register2Database(channel, command)
|
registerLocalCommand2Database(channel, command)
|
||||||
|
|
||||||
// Register the command at the local cache:
|
// Register the command at the local cache:
|
||||||
listeners[fmt.Sprintf(`%s::%s`, channel, command)] = callback
|
listeners[fmt.Sprintf(`%s::%s`, channel, command)] = callback
|
||||||
|
10
ICCC/SystemMessages/ICCCNumGen.go
Normal file
10
ICCC/SystemMessages/ICCCNumGen.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package SystemMessages
|
||||||
|
|
||||||
|
// The message to request a new number from NumGen package.
|
||||||
|
type ICCCNumGenNext struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// The response to the Numgen request.
|
||||||
|
type ICCCAnswerNumGen struct {
|
||||||
|
Number int64
|
||||||
|
}
|
7
ICCC/SystemMessages/ICCCRegisterHost.go
Normal file
7
ICCC/SystemMessages/ICCCRegisterHost.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package SystemMessages
|
||||||
|
|
||||||
|
// The message to register a host to ICCC.
|
||||||
|
type ICCCRegisterHost struct {
|
||||||
|
Hostname string // The hostname for the end-point
|
||||||
|
IPAddressPort string // The IP address and port for the end-point
|
||||||
|
}
|
9
ICCC/SystemMessages/ICCCRegisterListener.go
Normal file
9
ICCC/SystemMessages/ICCCRegisterListener.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package SystemMessages
|
||||||
|
|
||||||
|
// The message to register a command/listener to ICCC.
|
||||||
|
type ICCCRegisterListener struct {
|
||||||
|
Channel string // The channel for the provided command
|
||||||
|
Command string // The provided command
|
||||||
|
IsActive bool // Is the command active?
|
||||||
|
IPAddressPort string // The IP address and port for the end-point
|
||||||
|
}
|
@ -2,6 +2,6 @@ package SystemMessages
|
|||||||
|
|
||||||
// Message type for the startup message:
|
// Message type for the startup message:
|
||||||
type ICCCStartUpMessage struct {
|
type ICCCStartUpMessage struct {
|
||||||
PublicIPAddressAndPort string
|
PublicIPAddressAndPort string // The public web server's IP address and port
|
||||||
AdminIPAddressAndPort string
|
AdminIPAddressAndPort string // The private admin server's IP address and port
|
||||||
}
|
}
|
||||||
|
45
NumGen/ICCCNextNumber.go
Normal file
45
NumGen/ICCCNextNumber.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package NumGen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/SommerEngineering/Ocean/ICCC"
|
||||||
|
"github.com/SommerEngineering/Ocean/ICCC/SystemMessages"
|
||||||
|
"github.com/SommerEngineering/Ocean/Log"
|
||||||
|
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The receiver function for the ICCC message, that registers a command.
|
||||||
|
func ICCCNextNumber(data map[string][]string) (result map[string][]string) {
|
||||||
|
|
||||||
|
// Recover from errors:
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityUnknown, LM.ImpactUnknown, LM.MessageNamePARSE, fmt.Sprintf("Was not able to execute the ICCC next number command message. %s", err))
|
||||||
|
result = make(map[string][]string, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Converts the HTTP form data into an object:
|
||||||
|
_, _, obj := ICCC.Data2Message(SystemMessages.ICCCNumGenNext{}, data)
|
||||||
|
|
||||||
|
// Was it possible to convert the data?
|
||||||
|
if obj != nil {
|
||||||
|
// Cast the object to the right type (just as check):
|
||||||
|
_ = obj.(SystemMessages.ICCCNumGenNext)
|
||||||
|
|
||||||
|
// Execute the command:
|
||||||
|
nextNumber := GetUniqueID()
|
||||||
|
|
||||||
|
// An answer is necessary:
|
||||||
|
answer := SystemMessages.ICCCAnswerNumGen{}
|
||||||
|
answer.Number = nextNumber
|
||||||
|
return ICCC.Message2Data(``, ``, answer)
|
||||||
|
} else {
|
||||||
|
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Was not able to create the message.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// In any other error case:
|
||||||
|
result = make(map[string][]string, 0)
|
||||||
|
return
|
||||||
|
}
|
@ -98,6 +98,9 @@ func initSystem() {
|
|||||||
|
|
||||||
// Register all system ICCC commands:
|
// Register all system ICCC commands:
|
||||||
ICCC.Registrar(ICCC.ChannelSYSTEM, `System::Start`, icccSystemStart)
|
ICCC.Registrar(ICCC.ChannelSYSTEM, `System::Start`, icccSystemStart)
|
||||||
|
ICCC.Registrar(ICCC.ChannelICCC, `ICCC::RegisterHost`, ICCC.ICCCRegisterHost)
|
||||||
|
ICCC.Registrar(ICCC.ChannelICCC, `ICCC::RegisterCommand`, ICCC.ICCCRegisterCommand)
|
||||||
|
ICCC.Registrar(ICCC.ChannelNUMGEN, `NumGen::Next`, NumGen.ICCCNextNumber)
|
||||||
|
|
||||||
// Start the ICCC Listener Cache:
|
// Start the ICCC Listener Cache:
|
||||||
ICCC.InitCacheNow() // Blocking, until the job is done
|
ICCC.InitCacheNow() // Blocking, until the job is done
|
||||||
|
Loading…
Reference in New Issue
Block a user