func (db *serviceClient) Cells(logger lager.Logger) (models.CellSet, error) { kvPairs, _, err := db.consulClient.KV().List(CellSchemaRoot(), nil) if err != nil { bbsErr := models.ConvertError(convertConsulError(err)) if bbsErr.Type != models.Error_ResourceNotFound { return nil, bbsErr } } if kvPairs == nil { err = consuladapter.NewPrefixNotFoundError(CellSchemaRoot()) bbsErr := models.ConvertError(convertConsulError(err)) if bbsErr.Type != models.Error_ResourceNotFound { return nil, bbsErr } } cellPresences := models.NewCellSet() for _, kvPair := range kvPairs { if kvPair.Session == "" { continue } cell := kvPair.Value presence := new(models.CellPresence) err := models.FromJSON(cell, presence) if err != nil { logger.Error("failed-to-unmarshal-cells-json", err) continue } cellPresences.Add(presence) } return cellPresences, nil }
func (db *ETCDDB) rawActualLRPGroupByProcessGuidAndIndex(logger lager.Logger, processGuid string, index int32) (*models.ActualLRPGroup, uint64, *models.Error) { node, bbsErr := db.fetchRecursiveRaw(logger, ActualLRPIndexDir(processGuid, index)) if bbsErr != nil { return nil, 0, bbsErr } group := models.ActualLRPGroup{} for _, instanceNode := range node.Nodes { var lrp models.ActualLRP deserializeErr := models.FromJSON([]byte(instanceNode.Value), &lrp) if deserializeErr != nil { logger.Error("failed-parsing-actual-lrp", deserializeErr, lager.Data{"key": instanceNode.Key}) return nil, 0, models.ErrDeserializeJSON } if isInstanceActualLRPNode(instanceNode) { group.Instance = &lrp } if isEvacuatingActualLRPNode(instanceNode) { group.Evacuating = &lrp } } if group.Evacuating == nil && group.Instance == nil { return nil, 0, models.ErrResourceNotFound } return &group, node.ModifiedIndex, nil }
func (db *ETCDDB) Tasks(logger lager.Logger, taskFilter db.TaskFilter) (*models.Tasks, *models.Error) { root, bbsErr := db.fetchRecursiveRaw(logger, TaskSchemaRoot) if bbsErr.Equal(models.ErrResourceNotFound) { return &models.Tasks{}, nil } if bbsErr != nil { return nil, bbsErr } if root.Nodes.Len() == 0 { return &models.Tasks{}, nil } tasks := models.Tasks{} for _, node := range root.Nodes { node := node var task models.Task deserializeErr := models.FromJSON([]byte(node.Value), &task) if deserializeErr != nil { logger.Error("failed-parsing-task", deserializeErr, lager.Data{"key": node.Key}) return nil, models.ErrUnknownError } if taskFilter == nil || taskFilter(&task) { tasks.Tasks = append(tasks.Tasks, &task) } } logger.Debug("succeeded-performing-deserialization", lager.Data{"num-tasks": len(tasks.GetTasks())}) return &tasks, nil }
func (db *ETCDDB) DesiredLRPs(logger lager.Logger, filter models.DesiredLRPFilter) (*models.DesiredLRPs, *models.Error) { root, bbsErr := db.fetchRecursiveRaw(logger, DesiredLRPSchemaRoot) if bbsErr.Equal(models.ErrResourceNotFound) { return &models.DesiredLRPs{}, nil } if bbsErr != nil { return nil, bbsErr } if root.Nodes.Len() == 0 { return &models.DesiredLRPs{}, nil } desiredLRPs := models.DesiredLRPs{} lrpsLock := sync.Mutex{} var workErr atomic.Value works := []func(){} for _, node := range root.Nodes { node := node works = append(works, func() { var lrp models.DesiredLRP deserializeErr := models.FromJSON([]byte(node.Value), &lrp) if deserializeErr != nil { logger.Error("failed-parsing-desired-lrp", deserializeErr) workErr.Store(fmt.Errorf("cannot parse lrp JSON for key %s: %s", node.Key, deserializeErr.Error())) return } if filter.Domain == "" || lrp.GetDomain() == filter.Domain { lrpsLock.Lock() desiredLRPs.DesiredLrps = append(desiredLRPs.DesiredLrps, &lrp) lrpsLock.Unlock() } }) } throttler, err := workpool.NewThrottler(maxDesiredLRPGetterWorkPoolSize, works) if err != nil { logger.Error("failed-constructing-throttler", err, lager.Data{"max-workers": maxDesiredLRPGetterWorkPoolSize, "num-works": len(works)}) return &models.DesiredLRPs{}, models.ErrUnknownError } logger.Debug("performing-deserialization-work") throttler.Work() if err, ok := workErr.Load().(error); ok { logger.Error("failed-performing-deserialization-work", err) return &models.DesiredLRPs{}, models.ErrUnknownError } logger.Debug("succeeded-performing-deserialization-work", lager.Data{"num-desired-lrps": len(desiredLRPs.GetDesiredLrps())}) return &desiredLRPs, nil }
func (t *ETCDHelper) GetInstanceActualLRP(lrpKey *models.ActualLRPKey) (*models.ActualLRP, error) { resp, err := t.etcdClient.Get(etcd.ActualLRPSchemaPath(lrpKey.ProcessGuid, lrpKey.Index), false, false) if err == storeadapter.ErrorKeyNotFound { return &models.ActualLRP{}, models.ErrResourceNotFound } Expect(err).NotTo(HaveOccurred()) var lrp models.ActualLRP err = models.FromJSON([]byte(resp.Node.Value), &lrp) Expect(err).NotTo(HaveOccurred()) return &lrp, nil }
func (db *serviceClient) CurrentBBS(logger lager.Logger) (*models.BBSPresence, error) { value, err := db.getAcquiredValue(BBSLockSchemaPath()) if err != nil { return nil, convertConsulError(err) } presence := new(models.BBSPresence) err = models.FromJSON(value, presence) if err != nil { return nil, err } return presence, nil }
func (db *serviceClient) CellById(logger lager.Logger, cellId string) (*models.CellPresence, error) { value, err := db.getAcquiredValue(CellSchemaPath(cellId)) if err != nil { return nil, convertConsulError(err) } presence := new(models.CellPresence) err = models.FromJSON(value, presence) if err != nil { return nil, models.NewError(models.Error_InvalidJSON, err.Error()) } return presence, nil }
func (db *ConsulDB) CellById(logger lager.Logger, cellId string) (*models.CellPresence, *models.Error) { cellPresence := models.CellPresence{} value, err := db.session.GetAcquiredValue(CellSchemaPath(cellId)) if err != nil { return nil, convertConsulError(err) } err = models.FromJSON(value, &cellPresence) if err != nil { return nil, models.ErrDeserializeJSON } return &cellPresence, nil }
func (db *ETCDDB) TaskByGuid(logger lager.Logger, taskGuid string) (*models.Task, *models.Error) { node, bbsErr := db.fetchRaw(logger, TaskSchemaPathByGuid(taskGuid)) if bbsErr != nil { return nil, bbsErr } var task models.Task deserializeErr := models.FromJSON([]byte(node.Value), &task) if deserializeErr != nil { logger.Error("failed-parsing-desired-task", deserializeErr) return nil, models.ErrDeserializeJSON } return &task, nil }
func (db *ETCDDB) DesiredLRPByProcessGuid(logger lager.Logger, processGuid string) (*models.DesiredLRP, *models.Error) { node, bbsErr := db.fetchRaw(logger, DesiredLRPSchemaPathByProcessGuid(processGuid)) if bbsErr != nil { return nil, bbsErr } var lrp models.DesiredLRP deserializeErr := models.FromJSON([]byte(node.Value), &lrp) if deserializeErr != nil { logger.Error("failed-parsing-desired-lrp", deserializeErr) return nil, models.ErrDeserializeJSON } return &lrp, nil }
func parseActualLRPGroups(logger lager.Logger, node *etcd.Node, filter models.ActualLRPFilter) (*models.ActualLRPGroups, *models.Error) { var groups = &models.ActualLRPGroups{} logger.Debug("performing-parsing-actual-lrp-groups") for _, indexNode := range node.Nodes { group := &models.ActualLRPGroup{} for _, instanceNode := range indexNode.Nodes { var lrp models.ActualLRP deserializeErr := models.FromJSON([]byte(instanceNode.Value), &lrp) if deserializeErr != nil { logger.Error("failed-parsing-actual-lrp-groups", deserializeErr, lager.Data{"key": instanceNode.Key}) return &models.ActualLRPGroups{}, models.ErrDeserializeJSON } if filter.Domain != "" && lrp.Domain != filter.Domain { continue } if filter.CellID != "" && lrp.CellId != filter.CellID { continue } if isInstanceActualLRPNode(instanceNode) { group.Instance = &lrp } if isEvacuatingActualLRPNode(instanceNode) { group.Evacuating = &lrp } } if group.Instance != nil || group.Evacuating != nil { groups.ActualLrpGroups = append(groups.ActualLrpGroups, group) } } logger.Debug("succeeded-performing-parsing-actual-lrp-groups", lager.Data{"num-actual-lrp-groups": len(groups.ActualLrpGroups)}) return groups, nil }
}) }) }) Describe("ToJSON", func() { It("should JSONify", func() { json, err := models.ToJSON(&cellPresence) Expect(err).NotTo(HaveOccurred()) Expect(string(json)).To(MatchJSON(payload)) }) }) Describe("FromJSON", func() { It("returns a CellPresence with correct fields", func() { decodedCellPresence := &models.CellPresence{} err := models.FromJSON([]byte(payload), decodedCellPresence) Expect(err).NotTo(HaveOccurred()) Expect(decodedCellPresence).To(Equal(&cellPresence)) }) Context("with an invalid payload", func() { It("returns the error", func() { payload = "aliens lol" decodedCellPresence := &models.CellPresence{} err := models.FromJSON([]byte(payload), decodedCellPresence) Expect(err).To(HaveOccurred()) }) }) })
}, } }) Describe("To JSON", func() { It("should JSONify", func() { marshalled, err := json.Marshal(&lrp) Expect(err).NotTo(HaveOccurred()) Expect(string(marshalled)).To(MatchJSON(lrpPayload)) }) }) Describe("FromJSON", func() { It("returns a LRP with correct fields", func() { aLRP := &models.ActualLRP{} err := models.FromJSON([]byte(lrpPayload), aLRP) Expect(err).NotTo(HaveOccurred()) Expect(aLRP).To(Equal(&lrp)) }) Context("with an invalid payload", func() { It("returns the error", func() { aLRP := &models.ActualLRP{} err := models.FromJSON([]byte("something lol"), aLRP) Expect(err).To(HaveOccurred()) }) }) for field, payload := range map[string]string{ "process_guid": `{"instance_guid": "instance_guid", "cell_id": "cell_id", "domain": "domain"}`,
testValidatorErrorCase(testCase) } }) Describe("Marshal", func() { It("should JSONify", func() { json, err := models.ToJSON(&task) Expect(err).NotTo(HaveOccurred()) Expect(string(json)).To(MatchJSON(taskPayload)) }) }) Describe("Unmarshal", func() { It("returns a Task with correct fields", func() { decodedTask := &models.Task{} err := models.FromJSON([]byte(taskPayload), decodedTask) Expect(err).NotTo(HaveOccurred()) Expect(decodedTask).To(Equal(&task)) }) Context("with an invalid payload", func() { It("returns the error", func() { decodedTask := &models.Task{} err := models.FromJSON([]byte("aliens lol"), decodedTask) Expect(err).To(HaveOccurred()) }) }) }) Describe("DesireTaskRequest", func() {
func (db *ETCDDB) WatchForActualLRPChanges(logger lager.Logger, created func(*models.ActualLRPGroup), changed func(*models.ActualLRPChange), deleted func(*models.ActualLRPGroup), ) (chan<- bool, <-chan error) { logger = logger.Session("watching-for-actual-lrp-changes") events, stop, err := db.watch(ActualLRPSchemaRoot) go func() { logger.Info("started-watching") defer logger.Info("finished-watching") for event := range events { switch { case event.Node != nil && event.PrevNode == nil: logger.Debug("received-create") var actualLRP models.ActualLRP err := models.FromJSON([]byte(event.Node.Value), &actualLRP) if err != nil { logger.Error("failed-to-unmarshal-actual-lrp-on-create", err, lager.Data{"key": event.Node.Key, "value": event.Node.Value}) continue } evacuating := isEvacuatingActualLRPNode(event.Node) actualLRPGroup := &models.ActualLRPGroup{} if evacuating { actualLRPGroup.Evacuating = &actualLRP } else { actualLRPGroup.Instance = &actualLRP } logger.Debug("sending-create", lager.Data{"actual-lrp": &actualLRP, "evacuating": evacuating}) created(actualLRPGroup) case event.Node != nil && event.PrevNode != nil: logger.Debug("received-change") var before models.ActualLRP err := models.FromJSON([]byte(event.PrevNode.Value), &before) if err != nil { logger.Error("failed-to-unmarshal-prev-actual-lrp-on-change", err, lager.Data{"key": event.PrevNode.Key, "value": event.PrevNode.Value}) continue } var after models.ActualLRP err = models.FromJSON([]byte(event.Node.Value), &after) if err != nil { logger.Error("failed-to-unmarshal-actual-lrp-on-change", err, lager.Data{"key": event.Node.Key, "value": event.Node.Value}) continue } evacuating := isEvacuatingActualLRPNode(event.Node) beforeGroup := &models.ActualLRPGroup{} afterGroup := &models.ActualLRPGroup{} if evacuating { afterGroup.Evacuating = &after beforeGroup.Evacuating = &before } else { afterGroup.Instance = &after beforeGroup.Instance = &before } logger.Debug("sending-change", lager.Data{"before": &before, "after": &after, "evacuating": evacuating}) changed(&models.ActualLRPChange{Before: beforeGroup, After: afterGroup}) case event.PrevNode != nil && event.Node == nil: logger.Debug("received-delete") var actualLRP models.ActualLRP if event.PrevNode.Dir { continue } err := models.FromJSON([]byte(event.PrevNode.Value), &actualLRP) if err != nil { logger.Error("failed-to-unmarshal-prev-actual-lrp-on-delete", err, lager.Data{"key": event.PrevNode.Key, "value": event.PrevNode.Value}) } else { evacuating := isEvacuatingActualLRPNode(event.PrevNode) actualLRPGroup := &models.ActualLRPGroup{} if evacuating { actualLRPGroup.Evacuating = &actualLRP } else { actualLRPGroup.Instance = &actualLRP } logger.Debug("sending-delete", lager.Data{"actual-lrp": &actualLRP, "evacuating": evacuating}) deleted(actualLRPGroup) } default: logger.Debug("received-event-with-both-nodes-nil") } } }() return stop, err }
func (db *ETCDDB) WatchForDesiredLRPChanges(logger lager.Logger, created func(*models.DesiredLRP), changed func(*models.DesiredLRPChange), deleted func(*models.DesiredLRP), ) (chan<- bool, <-chan error) { logger = logger.Session("watching-for-desired-lrp-changes") events, stop, err := db.watch(DesiredLRPSchemaRoot) go func() { for event := range events { switch { case event.Node != nil && event.PrevNode == nil: logger.Debug("received-create") var desiredLRP models.DesiredLRP err := models.FromJSON([]byte(event.Node.Value), &desiredLRP) if err != nil { logger.Error("failed-to-unmarshal-desired-lrp", err, lager.Data{"value": event.Node.Value}) continue } logger.Debug("sending-create", lager.Data{"desired-lrp": &desiredLRP}) created(&desiredLRP) case event.Node != nil && event.PrevNode != nil: // update logger.Debug("received-update") var before models.DesiredLRP err := models.FromJSON([]byte(event.PrevNode.Value), &before) if err != nil { logger.Error("failed-to-unmarshal-desired-lrp", err, lager.Data{"value": event.PrevNode.Value}) continue } var after models.DesiredLRP err = models.FromJSON([]byte(event.Node.Value), &after) if err != nil { logger.Error("failed-to-unmarshal-desired-lrp", err, lager.Data{"value": event.Node.Value}) continue } logger.Debug("sending-update", lager.Data{"before": &before, "after": &after}) changed(&models.DesiredLRPChange{Before: &before, After: &after}) case event.Node == nil && event.PrevNode != nil: // delete logger.Debug("received-delete") var desiredLRP models.DesiredLRP err := models.FromJSON([]byte(event.PrevNode.Value), &desiredLRP) if err != nil { logger.Error("failed-to-unmarshal-desired-lrp", err, lager.Data{"value": event.PrevNode.Value}) continue } logger.Debug("sending-delete", lager.Data{"desired-lrp": &desiredLRP}) deleted(&desiredLRP) default: logger.Debug("received-event-with-both-nodes-nil") } } }() return stop, err }