func (t *tribe) handleAddPlugin(msg *pluginMsg) bool { t.mutex.Lock() defer t.mutex.Unlock() // update the clock if newer t.clock.Update(msg.LTime) if t.isDuplicate(msg) { return false } t.msgBuffer[msg.LTime%LTime(len(t.msgBuffer))] = msg if _, ok := t.agreements[msg.AgreementName]; ok { if t.agreements[msg.AgreementName].PluginAgreement.Add(msg.Plugin) { ptype, _ := core.ToPluginType(msg.Plugin.TypeName()) work := worker.PluginRequest{ Plugin: agreement.Plugin{ Name_: msg.Plugin.Name(), Version_: msg.Plugin.Version(), Type_: ptype, }, RequestType: worker.PluginLoadedType, } t.pluginWorkQueue <- work t.processIntents() return true } } t.addPluginIntent(msg) return true }
func (p *pluginControl) ValidateDeps(mts []core.Metric, plugins []core.SubscribedPlugin) []serror.SnapError { var serrs []serror.SnapError for _, mt := range mts { _, errs := p.validateMetricTypeSubscription(mt, mt.Config()) if len(errs) > 0 { serrs = append(serrs, errs...) } } if len(serrs) > 0 { return serrs } //validate plugins for _, plg := range plugins { typ, err := core.ToPluginType(plg.TypeName()) if err != nil { return []serror.SnapError{serror.New(err)} } plg.Config().Merge(p.Config.Plugins.getPluginConfigDataNode(typ, plg.Name(), plg.Version())) errs := p.validatePluginSubscription(plg) if len(errs) > 0 { serrs = append(serrs, errs...) return serrs } } return serrs }
func (t *tribe) processAddPluginIntents() bool { for idx, v := range t.intentBuffer { if v.GetType() == addPluginMsgType { intent := v.(*pluginMsg) if _, ok := t.agreements[intent.AgreementName]; ok { if ok, _ := t.agreements[intent.AgreementName].PluginAgreement.Plugins.Contains(intent.Plugin); !ok { t.agreements[intent.AgreementName].PluginAgreement.Plugins = append(t.agreements[intent.AgreementName].PluginAgreement.Plugins, intent.Plugin) t.intentBuffer = append(t.intentBuffer[:idx], t.intentBuffer[idx+1:]...) ptype, _ := core.ToPluginType(intent.Plugin.TypeName()) work := worker.PluginRequest{ Plugin: agreement.Plugin{ Name_: intent.Plugin.Name(), Version_: intent.Plugin.Version(), Type_: ptype, }, RequestType: worker.PluginLoadedType, } t.pluginWorkQueue <- work return false } } } } return true }
func (p *pluginControl) validateMetricTypeSubscription(mt core.RequestedMetric, cd *cdata.ConfigDataNode) []serror.SnapError { var serrs []serror.SnapError controlLogger.WithFields(log.Fields{ "_block": "validate-metric-subscription", "namespace": mt.Namespace(), "version": mt.Version(), }).Info("subscription called on metric") m, err := p.metricCatalog.Get(mt.Namespace(), mt.Version()) if err != nil { serrs = append(serrs, serror.New(err, map[string]interface{}{ "name": mt.Namespace().String(), "version": mt.Version(), })) return serrs } // No metric found return error. if m == nil { serrs = append(serrs, serror.New(fmt.Errorf("no metric found cannot subscribe: (%s) version(%d)", mt.Namespace(), mt.Version()))) return serrs } m.config = cd typ, serr := core.ToPluginType(m.Plugin.TypeName()) if serr != nil { return []serror.SnapError{serror.New(err)} } // merge global plugin config if m.config != nil { m.config.ReverseMerge(p.Config.Plugins.getPluginConfigDataNode(typ, m.Plugin.Name(), m.Plugin.Version())) } else { m.config = p.Config.Plugins.getPluginConfigDataNode(typ, m.Plugin.Name(), m.Plugin.Version()) } // When a metric is added to the MetricCatalog, the policy of rules defined by the plugin is added to the metric's policy. // If no rules are defined for a metric, we set the metric's policy to an empty ConfigPolicyNode. // Checking m.policy for nil will not work, we need to check if rules are nil. if m.policy.HasRules() { if m.Config() == nil { serrs = append(serrs, serror.New(fmt.Errorf("Policy defined for metric, (%s) version (%d), but no config defined in manifest", mt.Namespace(), mt.Version()))) return serrs } ncdTable, errs := m.policy.Process(m.Config().Table()) if errs != nil && errs.HasErrors() { for _, e := range errs.Errors() { serrs = append(serrs, serror.New(e)) } return serrs } m.config = cdata.FromTable(*ncdTable) } return serrs }
func getPluginType(t string) (core.PluginType, error) { if ityp, err := strconv.Atoi(t); err == nil { return core.PluginType(ityp), nil } ityp, err := core.ToPluginType(t) if err != nil { return core.PluginType(-1), err } return ityp, nil }
func (t *tribe) joinAgreement(msg *agreementMsg) serror.SnapError { if err := t.canJoinAgreement(msg.Agreement(), msg.MemberName); err != nil { return err } // add plugin agreement to the member if t.agreements[msg.Agreement()].PluginAgreement != nil { t.members[msg.MemberName].PluginAgreement = t.agreements[msg.Agreement()].PluginAgreement } t.members[msg.MemberName].TaskAgreements[msg.Agreement()] = t.agreements[msg.Agreement()].TaskAgreement // update the agreements membership t.agreements[msg.Agreement()].Members[msg.MemberName] = t.members[msg.MemberName] // get plugins and tasks if this is the node joining if msg.MemberName == t.memberlist.LocalNode().Name { go func(a *agreement.Agreement) { for _, p := range a.PluginAgreement.Plugins { ptype, _ := core.ToPluginType(p.TypeName()) work := worker.PluginRequest{ Plugin: agreement.Plugin{ Name_: p.Name(), Version_: p.Version(), Type_: ptype, }, RequestType: worker.PluginLoadedType, } t.pluginWorkQueue <- work } for _, tsk := range a.TaskAgreement.Tasks { state := t.TaskStateQuery(msg.Agreement(), tsk.ID) startOnCreate := false if state == core.TaskSpinning || state == core.TaskFiring { startOnCreate = true } work := worker.TaskRequest{ Task: worker.Task{ ID: tsk.ID, StartOnCreate: startOnCreate, }, RequestType: worker.TaskCreatedType, } t.taskWorkQueue <- work } }(t.agreements[msg.Agreement()]) } return nil }
func (p *pluginControl) sendPluginUnsubscriptionEvent(taskId string, pl core.Plugin) serror.SnapError { pt, err := core.ToPluginType(pl.TypeName()) if err != nil { return serror.New(err) } e := &control_event.PluginUnsubscriptionEvent{ TaskId: taskId, PluginType: int(pt), PluginName: pl.Name(), PluginVersion: pl.Version(), } if _, err := p.eventManager.Emit(e); err != nil { return serror.New(err) } return nil }
func (p *pluginControl) sendPluginSubscriptionEvent(taskID string, pl core.Plugin) serror.SnapError { pt, err := core.ToPluginType(pl.TypeName()) if err != nil { return serror.New(err) } e := &control_event.PluginSubscriptionEvent{ TaskId: taskID, PluginType: int(pt), PluginName: pl.Name(), PluginVersion: pl.Version(), SubscriptionType: int(strategy.UnboundSubscriptionType), } if pl.Version() > 0 { e.SubscriptionType = int(strategy.BoundSubscriptionType) } if _, err := p.eventManager.Emit(e); err != nil { return serror.New(err) } return nil }
func (s *subscriptionGroups) ValidateDeps(requested []core.RequestedMetric, plugins []core.SubscribedPlugin, configTree *cdata.ConfigDataTree) (serrs []serror.SnapError) { // resolve requested metrics and map to collectors pluginToMetricMap, collectors, errs := s.getMetricsAndCollectors(requested, configTree) if errs != nil { serrs = append(serrs, errs...) } // validateMetricsTypes for _, pmt := range pluginToMetricMap { for _, mt := range pmt.Metrics() { errs := s.validateMetric(mt) if len(errs) > 0 { serrs = append(serrs, errs...) } } } // add collectors to plugins (processors and publishers) for _, collector := range collectors { plugins = append(plugins, collector) } // validate plugins for _, plg := range plugins { typ, err := core.ToPluginType(plg.TypeName()) if err != nil { return []serror.SnapError{serror.New(err)} } plg.Config().ReverseMerge( s.Config.Plugins.getPluginConfigDataNode( typ, plg.Name(), plg.Version())) errs := s.validatePluginSubscription(plg) if len(errs) > 0 { serrs = append(serrs, errs...) return serrs } } return }
func (s *subscriptionGroups) validateMetric( metric core.Metric) (serrs []serror.SnapError) { m, err := s.metricCatalog.GetMetric(metric.Namespace(), metric.Version()) if err != nil { serrs = append(serrs, serror.New(err, map[string]interface{}{ "name": metric.Namespace().String(), "version": metric.Version(), })) return serrs } // No metric found return error. if m == nil { serrs = append( serrs, serror.New( fmt.Errorf("no metric found cannot subscribe: (%s) version(%d)", metric.Namespace(), metric.Version()))) return serrs } m.config = metric.Config() typ, serr := core.ToPluginType(m.Plugin.TypeName()) if serr != nil { return []serror.SnapError{serror.New(err)} } // merge global plugin config if m.config != nil { m.config.ReverseMerge( s.Config.Plugins.getPluginConfigDataNode(typ, m.Plugin.Name(), m.Plugin.Version())) } else { m.config = s.Config.Plugins.getPluginConfigDataNode(typ, m.Plugin.Name(), m.Plugin.Version()) } // When a metric is added to the MetricCatalog, the policy of rules defined by the plugin is added to the metric's policy. // If no rules are defined for a metric, we set the metric's policy to an empty ConfigPolicyNode. // Checking m.policy for nil will not work, we need to check if rules are nil. if m.policy.HasRules() { if m.Config() == nil { fields := log.Fields{ "metric": m.Namespace(), "version": m.Version(), "plugin": m.Plugin.Name(), } serrs = append(serrs, serror.New(ErrConfigRequiredForMetric, fields)) return serrs } ncdTable, errs := m.policy.Process(m.Config().Table()) if errs != nil && errs.HasErrors() { for _, e := range errs.Errors() { serrs = append(serrs, serror.New(e)) } return serrs } m.config = cdata.FromTable(*ncdTable) } return serrs }