1 // SPDX-License-Identifier: Apache-2.0
\r
2 // Copyright (c) 2020 Intel Corporation
\r
9 "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/db"
\r
10 log "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/logutils"
\r
11 rpc "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/rpc"
\r
12 mtypes "github.com/open-ness/EMCO/src/orchestrator/pkg/module/types"
\r
13 pkgerrors "github.com/pkg/errors"
\r
16 // Controller contains the parameters needed for Controllers
\r
17 // It implements the interface for managing the Controllers
\r
18 type Controller struct {
\r
19 Metadata mtypes.Metadata `json:"metadata"`
\r
20 Spec ControllerSpec `json:"spec"`
\r
23 type ControllerSpec struct {
\r
24 Host string `json:"host"`
\r
25 Port int `json:"port"`
\r
26 Type string `json:"type"`
\r
27 Priority int `json:"priority"`
\r
30 const MinControllerPriority = 1
\r
31 const MaxControllerPriority = 1000000
\r
32 const CONTROLLER_TYPE_ACTION string = "action"
\r
33 const CONTROLLER_TYPE_PLACEMENT string = "placement"
\r
35 var CONTROLLER_TYPES = [...]string{CONTROLLER_TYPE_ACTION, CONTROLLER_TYPE_PLACEMENT}
\r
37 // ControllerKey is the key structure that is used in the database
\r
38 type ControllerKey struct {
\r
39 ControllerName string `json:"controller-name"`
\r
42 // We will use json marshalling to convert to string to
\r
43 // preserve the underlying structure.
\r
44 func (mk ControllerKey) String() string {
\r
45 out, err := json.Marshal(mk)
\r
53 // ControllerManager is an interface exposes the Controller functionality
\r
54 type ControllerManager interface {
\r
55 CreateController(ms Controller, mayExist bool) (Controller, error)
\r
56 GetController(name string) (Controller, error)
\r
57 GetControllers() ([]Controller, error)
\r
59 DeleteController(name string) error
\r
62 // ControllerClient implements the Manager
\r
63 // It will also be used to maintain some localized state
\r
64 type ControllerClient struct {
\r
65 collectionName string
\r
69 // NewControllerClient returns an instance of the ControllerClient
\r
70 // which implements the Manager
\r
71 func NewControllerClient() *ControllerClient {
\r
72 return &ControllerClient{
\r
73 collectionName: "controller",
\r
74 tagMeta: "controllermetadata",
\r
78 // CreateController a new collection based on the Controller
\r
79 func (mc *ControllerClient) CreateController(m Controller, mayExist bool) (Controller, error) {
\r
81 //Construct the composite key to select the entry
\r
82 key := ControllerKey{
\r
83 ControllerName: m.Metadata.Name,
\r
86 //Check if this Controller already exists
\r
87 _, err := mc.GetController(m.Metadata.Name)
\r
88 if err == nil && !mayExist {
\r
89 return Controller{}, pkgerrors.New("Controller already exists")
\r
92 err = db.DBconn.Insert(mc.collectionName, key, nil, mc.tagMeta, m)
\r
94 return Controller{}, pkgerrors.Wrap(err, "Creating DB Entry")
\r
97 // send message to create/update the rpc connection
\r
98 rpc.UpdateRpcConn(m.Metadata.Name, m.Spec.Host, m.Spec.Port)
\r
103 // GetController returns the Controller for corresponding name
\r
104 func (mc *ControllerClient) GetController(name string) (Controller, error) {
\r
106 //Construct the composite key to select the entry
\r
107 key := ControllerKey{
\r
108 ControllerName: name,
\r
110 value, err := db.DBconn.Find(mc.collectionName, key, mc.tagMeta)
\r
112 return Controller{}, pkgerrors.Wrap(err, "Get Controller")
\r
116 microserv := Controller{}
\r
117 err = db.DBconn.Unmarshal(value[0], µserv)
\r
119 return Controller{}, pkgerrors.Wrap(err, "Unmarshaling Value")
\r
121 return microserv, nil
\r
124 return Controller{}, pkgerrors.New("Error getting Controller")
\r
127 // GetControllers returns all the Controllers that are registered
\r
128 func (mc *ControllerClient) GetControllers() ([]Controller, error) {
\r
130 //Construct the composite key to select the entry
\r
131 key := ControllerKey{
\r
132 ControllerName: "",
\r
135 var resp []Controller
\r
136 values, err := db.DBconn.Find(mc.collectionName, key, mc.tagMeta)
\r
138 return []Controller{}, pkgerrors.Wrap(err, "Get Controller")
\r
141 for _, value := range values {
\r
142 microserv := Controller{}
\r
143 err = db.DBconn.Unmarshal(value, µserv)
\r
145 return []Controller{}, pkgerrors.Wrap(err, "Unmarshaling Value")
\r
148 resp = append(resp, microserv)
\r
154 // DeleteController the Controller from database
\r
155 func (mc *ControllerClient) DeleteController(name string) error {
\r
157 //Construct the composite key to select the entry
\r
158 key := ControllerKey{
\r
159 ControllerName: name,
\r
161 err := db.DBconn.Remove(mc.collectionName, key)
\r
163 return pkgerrors.Wrap(err, "Delete Controller Entry;")
\r
166 // send message to close rpc connection
\r
167 rpc.RemoveRpcConn(name)
\r
172 // InitControllers initializes connctions for controllers in the DB
\r
173 func (mc *ControllerClient) InitControllers() {
\r
174 vals, _ := mc.GetControllers()
\r
175 for _, v := range vals {
\r
176 log.Info("Initializing RPC connection for controller", log.Fields{
\r
177 "Controller": v.Metadata.Name,
\r
179 rpc.UpdateRpcConn(v.Metadata.Name, v.Spec.Host, v.Spec.Port)
\r