func validateInstance(app map[string]interface{}, vars map[string]string) bool { if len(app) == 1 { var repo *repository.EtcdBaseRepository = repository.NewEctdRepository() repo.SetCollection("/apps") _, err := repo.Get(vars["appId"]) if err != nil { log.Warn(err) log.Warn("validateInstance: Error getting app " + vars["appId"]) return false } return true } else { return false } }
func (a *BasicController) Set(rw http.ResponseWriter, req *http.Request) { decoder := json.NewDecoder(req.Body) var app entity.EtcdBaseModel err := decoder.Decode(&app) if err != nil { http.Error(rw, err.Error(), http.StatusBadRequest) return } vars := mux.Vars(req) if a.setValidation(app, vars) != true { log.Warn("Post Instance: Set validation fail") http.Error(rw, "Post Instance: Set validation fail", http.StatusBadRequest) return } var ttl string = req.FormValue("ttl") if ttl == "" { ttl = a.defaultTTL } err = a.GetConfiguredRepository(vars).Set(&app, ttl, rw, req) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } }
// Locates the service (creates if necessary). func (self *loadBalancer) requireService(name string) *lbService { if len(name) == 0 { log.Warn("Invalid service name have been required") } service, ok := self.services[name] if !ok { service = &lbService{ name: name, waiting: NewList(), } self.services[name] = service } return service }
// Deletes worker from all data structures, and deletes worker. func (self *loadBalancer) deleteWorker(worker *lbWorker, disconnect bool) { if worker == nil { log.Warn("Nil worker") } if disconnect { log.Info("SIGNAL_DISCONNECT") self.sendToWorker(worker, SIGNAL_DISCONNECT, nil, nil) } if worker.service != nil { log.Info("Delete Worker Service") worker.service.waiting.Delete(worker) } self.waiting.Delete(worker) delete(self.workers, worker.identity) }
// Decompose func (self *loadBalancer) decomposeMapOfInstancesMsg(msg []byte) []byte { var levels []interface{} if err := json.Unmarshal(msg, &levels); err != nil { // TODO: Send an error } var computedInstances []interface{} var processMapLevels func([]interface{}) processMapLevels = func(levels []interface{}) { for _, level := range levels { if level != nil { kind := reflect.TypeOf(level).Kind() if kind == reflect.Slice || kind == reflect.Array { processMapLevels(level.([]interface{})) } else { computedInstances = append(computedInstances, levels...) return } } } } processMapLevels(levels) // TODO: extract uris sortedInstanceUris := make([]string, 0) for _, instance := range computedInstances { if instance != nil { if uri, ok := instance.(map[string]interface{})["Info"].(map[string]interface{})["uri"]; ok { sortedInstanceUris = append(sortedInstanceUris, uri.(string)) } } else { log.Warn("Remove instance without uri attribute from last balancer response") } } uris, err := json.Marshal(sortedInstanceUris) if err != nil { // TODO: Send an error } return uris }
// Process message sent to us by a worker. func (self *loadBalancer) processWorker(sender []byte, msg [][]byte) { // At least, command if len(msg) < 1 { log.Warn("Invalid message from Worker, this doesn contain command") return } command, msg := msg[0], msg[1:] identity := hex.EncodeToString(sender) worker, workerReady := self.workers[identity] if !workerReady { worker = &lbWorker{ identity: identity, address: sender, expiry: time.Now().Add(HEARTBEAT_EXPIRY), } self.workers[identity] = worker } switch string(command) { case SIGNAL_READY: // At least, a service name if len(msg) < 1 { log.Warn("Invalid message from worker, service name is missing") self.deleteWorker(worker, true) return } service := msg[0] // Not first command in session or Reserved service name if workerReady || string(service[:4]) == INTERNAL_SERVICE_PREFIX { self.deleteWorker(worker, true) } else { // Attach worker to service and mark as idle worker.service = self.requireService(string(service)) self.workerWaiting(worker) } case SIGNAL_REPLY: if workerReady { // Remove & save client return envelope and insert the // protocol header and service name, then rewrap envelope. client := msg[0] chain := self.chains[string(client)] chain.msg = msg[2] self.advanceShackle(chain) self.workerWaiting(worker) } else { self.deleteWorker(worker, true) } case SIGNAL_HEARTBEAT: if workerReady { worker.expiry = time.Now().Add(HEARTBEAT_EXPIRY) } else { self.deleteWorker(worker, true) } case SIGNAL_DISCONNECT: self.deleteWorker(worker, false) default: log.Warn("Invalid message in Load Balancer") Dump(msg) } return }