Improved ICCC for external components

This commit is contained in:
Thorsten Sommer 2015-07-09 20:19:01 +02:00
parent 6abe562642
commit 184f320a2e
12 changed files with 113 additions and 63 deletions

View File

@ -1,7 +1,7 @@
package SystemMessages package SystemMessages
// The type for any answer, which can be extended by using CommandData. // The type for any answer, which can be extended by using CommandData.
type DefaultAnswer struct { type ICCCDefaultAnswer struct {
CommandSuccessful bool CommandSuccessful bool
CommandAnswer int64 CommandAnswer int64
} }

View File

@ -5,6 +5,6 @@ type ICCCNumGenNext struct {
} }
// The response to the NumGen request. // The response to the NumGen request.
type ICCCAnswerNumGen struct { type ICCCNumGenNextAnswer struct {
Number int64 Number int64
} }

View File

@ -1,7 +0,0 @@
package SystemMessages
// Message type for the startup message:
type ICCCStartUpMessage struct {
PublicIPAddressAndPort string // The public web server's IP address and port
AdminIPAddressAndPort string // The private admin server's IP address and port
}

View File

@ -0,0 +1,12 @@
package SystemMessages
// Message type for the startup message of Ocean's servers:
type ICCCOceanStartUpMessage struct {
PublicIPAddressPort string // The public web server's IP address and port
AdminIPAddressPort string // The private admin server's IP address and port
}
// Message type for a startup message for external components:
type ICCCComponentStartUpMessage struct {
IPAddressPort string // The component's ICCC IP address and port
}

View File

@ -1,7 +1,7 @@
package SystemMessages package SystemMessages
var ( var (
AnswerACK DefaultAnswer = DefaultAnswer{true, 0} // The command was successful AnswerACK ICCCDefaultAnswer = ICCCDefaultAnswer{true, 0} // The command was successful
AnswerNACK DefaultAnswer = DefaultAnswer{false, 0} // The command was not successful AnswerNACK ICCCDefaultAnswer = ICCCDefaultAnswer{false, 0} // The command was not successful
AnswerUNKNOWN DefaultAnswer = DefaultAnswer{false, -1} // The answer is unknown e.g. an error while reading the answer (HTTP errors, etc.) AnswerUNKNOWN ICCCDefaultAnswer = ICCCDefaultAnswer{false, -1} // The answer is unknown e.g. an error while reading the answer (HTTP errors, etc.)
) )

View File

@ -32,7 +32,7 @@ func ICCCNextNumber(data map[string][]string) (result map[string][]string) {
nextNumber := GetUniqueID() nextNumber := GetUniqueID()
// An answer is necessary: // An answer is necessary:
answer := SystemMessages.ICCCAnswerNumGen{} answer := SystemMessages.ICCCNumGenNextAnswer{}
answer.Number = nextNumber answer.Number = nextNumber
return ICCC.Message2Data(``, ``, answer) return ICCC.Message2Data(``, ``, answer)
} else { } else {

View File

@ -1,44 +1,44 @@
package System package System
import ( import (
"fmt" "fmt"
"github.com/SommerEngineering/Ocean/ICCC" "github.com/SommerEngineering/Ocean/ICCC"
"github.com/SommerEngineering/Ocean/ICCC/SystemMessages" "github.com/SommerEngineering/Ocean/ICCC/SystemMessages"
"github.com/SommerEngineering/Ocean/Log" "github.com/SommerEngineering/Ocean/Log"
LM "github.com/SommerEngineering/Ocean/Log/Meta" LM "github.com/SommerEngineering/Ocean/Log/Meta"
) )
// The receiver function for the ICCC message, that a server is up and running. // The receiver function for the ICCC message, that a external component is up and running.
func icccSystemStart(data map[string][]string) (result map[string][]string) { func icccComponentStartUpMessage(data map[string][]string) (result map[string][]string) {
// Recover from errors: // Recover from errors:
defer func() { defer func() {
if err := recover(); err != nil { 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 server startup message. %s", err)) Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityUnknown, LM.ImpactUnknown, LM.MessageNamePARSE, fmt.Sprintf("Was not able to execute the ICCC component startup message. %s", err))
result = make(map[string][]string, 0) result = make(map[string][]string, 0)
return return
} }
}() }()
// Converts the HTTP form data into an object: // Converts the HTTP form data into an object:
_, _, obj := ICCC.Data2Message(SystemMessages.ICCCStartUpMessage{}, data) _, _, obj := ICCC.Data2Message(SystemMessages.ICCCComponentStartUpMessage{}, data)
// Was it possible to convert the data? // Was it possible to convert the data?
if obj != nil { if obj != nil {
// Cast the object to the right type: // Cast the object to the right type:
messageData := obj.(SystemMessages.ICCCStartUpMessage) messageData := obj.(SystemMessages.ICCCComponentStartUpMessage)
// Provide a log entry: // Provide a log entry:
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: The server is now up and ready.`, messageData.PublicIPAddressAndPort, messageData.AdminIPAddressAndPort) Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: The external component is now up and ready.`, messageData.IPAddressPort)
// An answer is necessary: // An answer is necessary:
return ICCC.Message2Data("", "", SystemMessages.AnswerACK) return ICCC.Message2Data("", "", SystemMessages.AnswerACK)
} else { } else {
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Was not able to create the message.`) Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Was not able to create the message.`)
fmt.Println(`[Error] ICCC message: Was not able to create the message.`) fmt.Println(`[Error] ICCC message: Was not able to create the message.`)
} }
// In any other error case: // In any other error case:
result = make(map[string][]string, 0) result = make(map[string][]string, 0)
return return
} }

View File

@ -0,0 +1,44 @@
package System
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 an Ocean server is up and running.
func icccOceanStartUpMessage(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 Ocean server startup message. %s", err))
result = make(map[string][]string, 0)
return
}
}()
// Converts the HTTP form data into an object:
_, _, obj := ICCC.Data2Message(SystemMessages.ICCCOceanStartUpMessage{}, data)
// Was it possible to convert the data?
if obj != nil {
// Cast the object to the right type:
messageData := obj.(SystemMessages.ICCCOceanStartUpMessage)
// Provide a log entry:
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: The Ocean server is now up and ready.`, messageData.PublicIPAddressPort, messageData.AdminIPAddressPort)
// An answer is necessary:
return ICCC.Message2Data("", "", SystemMessages.AnswerACK)
} else {
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `ICCC message: Was not able to create the message.`)
fmt.Println(`[Error] ICCC message: Was not able to create the message.`)
}
// In any other error case:
result = make(map[string][]string, 0)
return
}

View File

@ -97,7 +97,8 @@ func initSystem() {
// The logging subsystem is not registered here, because it will be automated called at the end // The logging subsystem is not registered here, because it will be automated called at the end
// Register all system ICCC commands: // Register all system ICCC commands:
ICCC.Registrar(ICCC.ChannelSYSTEM, `System::Start`, icccSystemStart) ICCC.Registrar(ICCC.ChannelSYSTEM, `System::OceanStart`, icccOceanStartUpMessage)
ICCC.Registrar(ICCC.ChannelSYSTEM, `System::ComponentStart`, icccComponentStartUpMessage)
ICCC.Registrar(ICCC.ChannelICCC, `ICCC::RegisterHost`, ICCC.ICCCRegisterHost) ICCC.Registrar(ICCC.ChannelICCC, `ICCC::RegisterHost`, ICCC.ICCCRegisterHost)
ICCC.Registrar(ICCC.ChannelICCC, `ICCC::RegisterCommand`, ICCC.ICCCRegisterCommand) ICCC.Registrar(ICCC.ChannelICCC, `ICCC::RegisterCommand`, ICCC.ICCCRegisterCommand)
ICCC.Registrar(ICCC.ChannelNUMGEN, `NumGen::Next`, NumGen.ICCCNextNumber) ICCC.Registrar(ICCC.ChannelNUMGEN, `NumGen::Next`, NumGen.ICCCNextNumber)

View File

@ -11,27 +11,27 @@ import (
func Start() { func Start() {
// Tell the whole cluster, that we are up and ready: // Tell the whole cluster, that we are up and ready:
data := SystemMessages.ICCCStartUpMessage{} data := SystemMessages.ICCCOceanStartUpMessage{}
// Start the public web server: // Start the public web server:
if serverPublic != nil { if serverPublic != nil {
data.PublicIPAddressAndPort = serverPublicAddressPort data.PublicIPAddressPort = serverPublicAddressPort
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Public web server is now listening.`, `Configuration for hostname and port.`, serverPublicAddressPort) Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Public web server is now listening.`, `Configuration for hostname and port.`, serverPublicAddressPort)
go serverPublic.ListenAndServe() go serverPublic.ListenAndServe()
} }
// Start the private web server: // Start the private web server:
if serverAdmin != nil { if serverAdmin != nil {
data.AdminIPAddressAndPort = serverAdminAddressPort data.AdminIPAddressPort = serverAdminAddressPort
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Admin web server is now listening.`, `Configuration for hostname and port.`, serverAdminAddressPort) Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Admin web server is now listening.`, `Configuration for hostname and port.`, serverAdminAddressPort)
go serverAdmin.ListenAndServe() go serverAdmin.ListenAndServe()
} }
// Notify the whole cluster, that this server is now up and ready: // Notify the whole cluster, that this server is now up and ready:
answers := ICCC.WriteMessage2All(ICCC.ChannelSYSTEM, `System::Start`, data, SystemMessages.DefaultAnswer{}) answers := ICCC.WriteMessage2All(ICCC.ChannelSYSTEM, `System::Start`, data, SystemMessages.ICCCDefaultAnswer{})
for n, obj := range answers { for n, obj := range answers {
if obj != nil { if obj != nil {
answer := obj.(SystemMessages.DefaultAnswer) answer := obj.(SystemMessages.ICCCDefaultAnswer)
Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, fmt.Sprintf("An answer to the ICCC start up message: Successful=%v, Status=%d, Answer=%d/%d", answer.CommandSuccessful, answer.CommandAnswer, n+1, len(answers))) Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, fmt.Sprintf("An answer to the ICCC start up message: Successful=%v, Status=%d, Answer=%d/%d", answer.CommandSuccessful, answer.CommandAnswer, n+1, len(answers)))
} }
} }