@ -14,16 +14,11 @@ import (
)
// this package creates the central coordiantor and sub coordiantors for clients
// interfaces
// db client interface
type DB interface {
// getters (all create if doesnt exist)
//GetToken() (string, error) // returns admin token (Creates if it doesnt exist)
GetReactorClient ( int ) ( string , string , string , string , error ) // returns (url, org, bucket, token, err)
// delete
// DeleteReactorClient(string) error // removes client token but maintains bucket
// PurgeReactorClientData(string) error // perm deletes all assocaited reactor data (token, bucket etc)
}
func NewDBAdmin ( config * viper . Viper ) ( DB , error ) {
@ -31,9 +26,10 @@ func NewDBAdmin(config *viper.Viper) (DB, error) {
}
type CentralCoordinator struct {
// main coordinator
ClientConnections * ClientPacket
* SubCoordinators
* SystemViewer
//*SystemViewer
DB
Config * viper . Viper
// from config
@ -47,18 +43,23 @@ type SubCoordinators struct {
}
func NewCentralCoordinator ( config * viper . Viper , ch chan error ) * CentralCoordinator {
c := & CentralCoordinator { Err : ch , Config : config }
if err := config . UnmarshalKey ( "server" , c ) ; err != nil {
// report error
// create a central coordinator to manage requests
db , err := NewDBAdmin ( config )
if err != nil {
ch <- err
}
fmt . Printf ( "%+v\n" , c )
c . SystemViewer = NewSystemViewer ( )
go c . SystemViewer . Start ( )
c := & CentralCoordinator { Err : ch , Config : config , DB : db }
// grab config settings
if err = config . UnmarshalKey ( "server" , c ) ; err != nil {
ch <- err
}
// spawn a systemviewer DECOMIS
//c.SystemViewer = NewSystemViewer()
//.go c.SystemViewer.Start()
// subcoord map
s := make ( map [ string ] * SubCoordinator )
sub := & SubCoordinators { Directory : s }
c . SubCoordinators = sub
c. SubCoordinators = & SubCoordinators { Directory : s }
// return init coordinator
return c
}
@ -66,7 +67,10 @@ func (c *CentralCoordinator) Start() {
// starts up associated funcs
clientChan := make ( chan * ClientPacket )
l := NewListener ( clientChan , c . Err )
// grabs lis port
c . Config . UnmarshalKey ( "server.ports" , l )
// starts client listener routines
go l . Start ( )
go c . ClientListener ( clientChan )
}
@ -74,36 +78,48 @@ func (c *CentralCoordinator) Start() {
func ( c * CentralCoordinator ) ClientListener ( ch chan * ClientPacket ) {
for client := range ch {
// basically loops until channel is closed
cr := c . ClientHandler ( client . C lient)
client . Response <- c r
fmt. Printf ( "Incoming client: +%v\n" , c lient)
client . Response <- c . ClientHandle r( client . Client ) // respond with cred
}
}
func ( c * CentralCoordinator ) ClientHandler ( cl * Client ) * ClientResponse {
// look for sub coord
c . SubCoordinators . Lock ( )
defer c . SubCoordinators . Unlock ( )
subcoord , ok := c . SubCoordinators . Directory [ cl . Type ]
if ! ok {
// Sub Coordinator does not exists
logging. Debug ( logging . DSpawn , "CC0 01 Created %v Coordinator" , cl . Type )
subcoord = NewSubCoordinator ( cl . Type , c . SystemViewer , c . Err )
// Sub Coordinator does not exists , creating
fmt. Printf ( "Cl type: %s, Port: %d\n" , cl . Type , c . Ports [ cl . Type ] )
subcoord = NewSubCoordinator ( cl . Type , c . Ports[ cl . Type ] , c . Err )
c . SubCoordinators . Directory [ cl . Type ] = subcoord
fmt . Printf ( "Creating subcord for %s on %d\n" , cl . Type , c . Ports [ cl . Type ] )
logging . Debug ( logging . DSpawn , "CC0 01 Created %v Coordinator" , cl . Type )
}
// unlocking
c . SubCoordinators . Unlock ( )
// starts sub coord with client credentials
fmt . Printf ( "Starting subcoord client handler\n" )
go subcoord . ClientHandler ( cl )
fmt . Printf ( "Getting db info\n" )
// setting up client response
url , org , token , bucket , err := c . DB . GetReactorClient ( int ( cl . Id ) )
url , org , token , bucket , err := c . DB . GetReactorClient ( cl . Id )
fmt . Printf ( "Got URL: %s, Org: %s, Token: %s, Bucket: %b\n" , url , org , token , bucket )
if err != nil {
c . Err <- err
}
cr := & ClientResponse { URL : url , Org : org , Token : token , Bucket : bucket , Port : c . Ports [ cl . Type ] }
return cr
// returning info
return & ClientResponse { URL : url , Org : org , Token : token , Bucket : bucket , Port : c . Ports [ cl . Type ] }
}
type ManagerInterface interface {
Start ( )
NewManager ( * Client , * SystemViewer , chan error ) GeneralManager
GetManager ( u int32 ) ( GeneralManager , bool )
AddManager ( u int32 , GeneralManager )
NewManager ( * Client , chan error ) GeneralManager
GetManager ( int) ( GeneralManager , bool )
AddManager ( int, GeneralManager )
Register ( )
}
@ -116,22 +132,22 @@ type GeneralManager interface {
type SubCoordinator struct {
Port int // port that we set up gRPC endpoint on
ManagerInterface // embed an interface to create/manager managers
* SystemViewer
//*SystemViewer
Err chan error
}
type Managers struct {
Directory map [ u int32 ] interface { } // support for either manager
Directory map [ int] interface { } // support for either manager
sync . RWMutex // potential perf
}
// interface stuff
func NewSubCoordinator ( clientType string , sys * SystemViewer , err chan error ) * SubCoordinator {
c := & SubCoordinator { Err : err }
c . SystemViewer = sys
man , err s := NewCoordinatorType ( clientType , err )
if err s != nil {
err <- err s
func NewSubCoordinator ( clientType string , port int , errCh chan error ) * SubCoordinator {
c := & SubCoordinator { Err : err Ch }
//c.SystemViewer = sys
man , err := NewCoordinatorType ( clientType , err Ch )
if err != nil {
err Ch <- err
}
c . ManagerInterface = man
go man . Start ( )
@ -141,15 +157,16 @@ func NewSubCoordinator(clientType string, sys *SystemViewer, err chan error) *Su
func ( c * SubCoordinator ) ClientHandler ( cl * Client ) {
// (creates and) notifies manager of client connection
c . UpdateManager ( cl )
}
func ( c * SubCoordinator ) UpdateManager ( cl * Client ) {
// shouldn't happen all that often so should be fine to lock
fmt . Printf ( "Grabbing Manager\n" )
m , exists := c . GetManager ( cl . Id )
if ! exists {
m = c . NewManager ( cl , c . SystemViewer , c . Err )
fmt . Printf ( "Creating Manager\n" )
m = c . NewManager ( cl , c . Err )
m . UpdateClient ( cl )
go c . AddManager ( cl . Id , m )
go m . Start ( )
@ -157,13 +174,13 @@ func (c *SubCoordinator) UpdateManager(cl *Client) {
go m . UpdateClient ( cl )
}
func ( m * Managers ) AddManager ( id u int32 , man GeneralManager ) {
func ( m * Managers ) AddManager ( id int, man GeneralManager ) {
m . Lock ( )
defer m . Unlock ( )
m . Directory [ id ] = man
}
func ( m * Managers ) GetManager ( id u int32 ) ( GeneralManager , bool ) {
func ( m * Managers ) GetManager ( id int) ( GeneralManager , bool ) {
// just read locks and reuturns
m . RLock ( )
defer m . RUnlock ( )
@ -176,17 +193,17 @@ func (m *Managers) GetManager(id uint32) (GeneralManager, bool) {
func NewCoordinatorType ( clientType string , err chan error ) ( ManagerInterface , error ) {
m := make ( map [ u int32 ] interface { } )
m := make ( map [ int] interface { } )
if clientType == "reactor" {
c := & reactorCoordinator { }
//m := make(map[uint32]*ReactorManager)
c . Managers = & Managers { Directory : m }
return c , nil
} else if clientType == "tui" {
c := & tui Coordinator{ }
c := & reactor Coordinator{ }
//m := make(map[uint32]*TUIManager)
c . Managers = & Managers { Directory : m }
return c , nil
//c.Managers = &Managers{Directory: m}
return c , errors . New ( fmt . Sprint ( "error, TUI Not impl" ) )
}
return & reactorCoordinator { } , errors . New ( "Unrecognized client type" )
}
@ -202,9 +219,9 @@ func (r *reactorCoordinator) Start() {
logging . Debug ( logging . DStart , "RCO 01 Starting!" )
}
func ( r * reactorCoordinator ) NewManager ( cl * Client , sys * SystemViewer , err chan error ) GeneralManager {
func ( r * reactorCoordinator ) NewManager ( cl * Client , err chan error ) GeneralManager {
logging . Debug ( logging . DClient , "RCO 01 starting manager for %v client %v" , cl . Type , cl . Id )
return NewReactorManager ( cl , sys, err)
return NewReactorManager ( cl , err)
}
func ( r * reactorCoordinator ) Register ( ) {
@ -226,7 +243,7 @@ func (r *reactorCoordinator) Register() {
}
func ( r * reactorCoordinator ) ReactorStatusHandler ( ctx context . Context , req * pb . ReactorStatusPing ) ( * pb . ReactorStatusResponse , error ) {
m , exists := r . GetManager ( req . GetId ( ) )
m , exists := r . GetManager ( int ( req . GetId ( ) ) )
if ! exists {
return & pb . ReactorStatusResponse { } , errors . New ( "Manager doesn't exists for that client" )
}
@ -238,6 +255,7 @@ func (r *reactorCoordinator) ReactorStatusHandler(ctx context.Context, req *pb.R
}
// tui coordinator
/ *
type tuiCoordinator struct {
* Managers // by embedding general struct we allow coordinator to still call general funcs
pb . UnimplementedManagementServer
@ -247,9 +265,9 @@ func (t *tuiCoordinator) Start() {
logging . Debug ( logging . DStart , "TCO 01 Starting!" )
}
func ( t * tuiCoordinator ) NewManager ( cl * Client , sys * SystemViewer , err chan error ) GeneralManager {
func ( t * tuiCoordinator ) NewManager ( cl * Client , err chan error ) GeneralManager {
logging . Debug ( logging . DClient , "TCO 01 starting manager for %v client %v" , cl . Type , cl . Id )
return NewTUIManager ( cl , sys, err)
return NewTUIManager ( cl , err)
}
func ( t * tuiCoordinator ) Register ( ) {
@ -267,12 +285,13 @@ func (t *tuiCoordinator) Register() {
pb . RegisterManagementServer ( grpcServer , t )
go grpcServer . Serve ( lis )
logging . Debug ( logging . DClient , "TCO ready for client requests" )
* /
* /
/ *
}
func ( t * tuiCoordinator ) GetDevices ( ctx context . Context , req * pb . GetDevicesRequest ) ( * pb . GetDevicesResponse , error ) {
// grpc handler to fwd to manager
m , exists := t . GetManager ( req . GetClientId ( ) )
m , exists := t . GetManager ( int ( req . GetClientId ( ) ) )
if ! exists {
// doesnt exist for some reason
return & pb . GetDevicesResponse { } , errors . New ( "Manager doesn't exists for client" )
@ -294,3 +313,4 @@ func (t *tuiCoordinator) DeleteReactorDevice(ctx context.Context, req *pb.Delete
// TODO
return & pb . DeleteReactorDeviceResponse { } , nil
}
* /