func parse(data []byte) (err error) { if mylog.Debugging { mylog.Debugf("enter config.parse %q", data) defer func() { mylog.Debugf("exit config.parse %+v", err) mylog.Debugf("after config.parse cfg=%+v", cfg) }() } text := string(data) for i, line := range strings.Split(text, "\n") { lnumber := i + 1 line = strings.TrimSpace(line) if len(line) == 0 || line[0] == '#' { continue } keyvalue := strings.SplitN(line, "=", 2) if len(keyvalue) != 2 { return fmt.Errorf("no-parseable config line %q at line %d", line, lnumber) } key, value := strings.TrimSpace(keyvalue[0]), strings.TrimSpace(keyvalue[1]) if key == "" { return fmt.Errorf("empty config key at line %d", lnumber) } if _, found := cfg[key]; found { return fmt.Errorf("overwriting config key %q at line", key, lnumber) } cfg[key] = value } return nil }
func (a *SMSAction) Do(n notices.Notice) (err error) { if mylog.Debugging { defer func() { mylog.Debugf("exit SMSAction.Do %+v", err) }() } text := util.ExpandFromMap(a.ActionData.Template, n) mylog.Debug("SMSAction text to send:", text) msg := fmt.Sprintf(`{"to":["tel:%s"], "message": %q}`, a.Parameters["to"], text) mylog.Debug("SMSAction msg to send:", msg) req, err := http.NewRequest("POST", config.SMSEndpoint(), strings.NewReader(msg)) if err != nil { mylog.Alert("SMSAction.Do", err) } req.Header.Add("API_KEY", config.APIKey()) req.Header.Add("API_SECRET", config.APISecret()) req.Header.Add("Content-Type", "application/json") mylog.Debug("SMSAction.Do msg:", msg) resp, err := httpClient.Do(req) if err != nil { mylog.Alert("SMSAction.Do", err) return err } respDump, err := httputil.DumpResponse(resp, true) mylog.Debugf("SMSAction.Do server response: (%q,%v)\n", string(respDump), err) return err }
func NewNoticeFromCB(ngsi []byte, service string) (n map[string]interface{}, err error) { if mylog.Debugging { mylog.Debugf("enter NewNoticeFromCB(%s,%d)\n", ngsi, service) defer func() { mylog.Debugf("exit NewNotifFromCB (%+v,%v)\n", n, err) }() } n = make(map[string]interface{}) n["noticeId"] = uuid.New() n["received"] = time.Now() var ncr NotifyContextRequest err = json.Unmarshal(ngsi, &ncr) if err != nil { return nil, err } mylog.Debugf("in NewNoticeFromCB NotifyContextRequest: %+v\n", ncr) n["id"] = ncr.ContextResponses[0].ContextElement.Id n["type"] = ncr.ContextResponses[0].ContextElement.Type n["isPattern"] = ncr.ContextResponses[0].ContextElement.IsPattern n["service"] = service //Transform name-value-type for _, attr := range ncr.ContextResponses[0].ContextElement.Attributes { n[attr.Name] = attr.Value n[attr.Name+"__type"] = attr.Type } n = util.FlattenMap("", n) n2 := make(map[string]interface{}, len(n)) for k, v := range n { n2[util.ChangeDot(k)] = v } return n2, nil }
func AddRoutes(router *httprouter.Router) { mylog.Debugf("enter notice.AddRoutes(%+v)", router) defer func() { mylog.Debugf("exit action.Handler(%+v)", router) }() controller := &controller{&actionList} router.POST("/action", controller.Post) }
func str(name string) (str string, found bool) { if mylog.Debugging { mylog.Debugf("enter config.str %q", name) defer func() { mylog.Debugf("exit config.str %q %+v", str, found) }() } str, found = cfg[name] return str, found }
func Remove(id string) { if mylog.Debugging { mylog.Debugf("enter action.Remove %q", id) defer func() { mylog.Debugf("exit action.Remove") }() } actionList.Lock() defer actionList.Unlock() delete(actionList.actions, id) }
func Add(a Action) { if mylog.Debugging { mylog.Debugf("enter action.Add %+v", a) defer func() { mylog.Debugf("exit action.Add") }() } actionList.Lock() defer actionList.Unlock() actionList.actions[a.Data().Name] = a }
func AddRoutes(router *httprouter.Router) { mylog.Debugf("enter rule.AddRoutes(%+v)", router) defer func() { mylog.Debugf("exit rule.AddRoutes(%+v)", router) }() controller := &controller{} router.GET("/rules", controller.GetAll) router.GET("/rules/:name", controller.Get) router.POST("/rules", controller.Post) router.DELETE("/rules/:name", controller.Del) }
func f64(name string) (f float64, found bool) { if mylog.Debugging { mylog.Debugf("enter config.f64 %q", name) defer func() { mylog.Debugf("exit config.str %+v %+v", f, found) }() } str, found := cfg[name] f, err := strconv.ParseFloat(str, 64) found = err == nil return f, found }
func Find(id string) (a Action) { if mylog.Debugging { mylog.Debugf("enter action.Find %q", id) defer func() { mylog.Debugf("exit action.Find %+v", a) }() } actionList.RLock() defer actionList.RUnlock() a = actionList.actions[id] return a }
func (r *Rule) GetAction() (axn actions.Action, err error) { if mylog.Debugging { mylog.Debugf("enter rules.GetAction %+v", r) defer func() { mylog.Debugf("exit rules.GetAction %+v, %+v ", axn, err) }() } ar := r.Action at, err := actions.ParseActionType(ar.Type) if err != nil { return nil, err } return actions.NewAction(ar.Name, at, ar.Template, ar.Parameters) }
func LoadConfig(filename string) (err error) { if mylog.Debugging { mylog.Debugf("enter config.LoadConfig %q", filename) defer func() { mylog.Debugf("exit config.LoadConfig %+v", err) }() } err = loadFile(filename) if err != nil { return err } var found bool port, found = str("port") if !found { return fmt.Errorf("config port is mandatory") } smsEndpoint, found = str("SMS.endpoint") if !found { return fmt.Errorf("config SMS.endpoint is mandatory") } apiKey, found = str("API_KEY") if !found { return fmt.Errorf("config SMS.endpoint is mandatory") } apiSecret, found = str("API_SECRET") if !found { return fmt.Errorf("config SMS.endpoint is mandatory") } smtpServer, found = str("email.SMTP.server") if !found { return fmt.Errorf("config SMS.endpoint is mandatory") } updateEndpoint, found = str("update.endpoint") if !found { return fmt.Errorf("config update.endpoint is mandatory") } noticeEndpoint, found = str("notice.endpoint") if !found { return fmt.Errorf("config notice.endpoint is mandatory") } ruleEndpoint, found = str("rule.endpoint") if !found { return fmt.Errorf("config rule.endpoint is mandatory") } return nil }
func FindAll() (as []Action) { if mylog.Debugging { mylog.Debugf("enter action.FindAll") defer func() { mylog.Debugf("exit action.FindAll %+v", as) }() } actionList.RLock() defer actionList.RUnlock() for _, a := range actionList.actions { as = append(as, a) } return as }
func loadFile(filename string) (err error) { if mylog.Debugging { mylog.Debugf("enter config.loadFile %q", filename) defer func() { mylog.Debugf("exit config.loadFile %+v", err) }() } data, err := ioutil.ReadFile(filename) if err != nil { return err } err = parse(data) return err }
func Save(r *Rule) (err error) { if mylog.Debugging { mylog.Debugf("enter rules.Save %+v", r) defer func() { mylog.Debugf("exit rules.Save %+v", err) }() } s := session.Clone() defer s.Close() c := session.DB("test").C("rules") err = c.EnsureIndex(index) if err != nil { return err } err = c.Insert(r) return err }
func (a *UpdateAction) Do(n notices.Notice) (err error) { // A litle (or very) dirty. Add "hidden" parameters as notification data // and remove them after executing template (better copy first level fields in a new map?) n["__attrName"] = a.ActionData.Parameters["name"] n["__attrValue"] = a.ActionData.Parameters["value"] n["__attrType"] = a.ActionData.Parameters["type"] text := util.ExpandFromMap(updateTemplateText, n) mylog.Debug("UpdateAction text to send:", text) delete(n, "__attrName") delete(n, "__attrValue") delete(n, "__attrType") req, err := http.NewRequest("POST", config.UpdateEndpoint(), strings.NewReader(text)) if err != nil { mylog.Alert("UpdateAction.Do", err) } req.Header.Add("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { mylog.Alert("UpdateAction.Do", err) return err } respDump, err := httputil.DumpResponse(resp, true) mylog.Debugf("UpdateAction.Do server response: (%q,%v)\n", string(respDump), err) return err }
func (a *EmailAction) Do(n notices.Notice) (err error) { if mylog.Debugging { mylog.Debugf("enter EmailAction.Do %+v %+v", a, n) defer func() { mylog.Debugf("exit EmailAction.Do %+v", err) }() } text := util.ExpandFromMap(a.ActionData.Template, n) mylog.Debugf("text to send %q", text) err = smtp.SendMail(config.SMTPServer(), nil, a.Parameters["from"], []string{a.Parameters["to"]}, []byte(text)) if err != nil { mylog.Alert("EmailAction.Do", err) } return err }
func FlattenMap(key string, targetMap map[string]interface{}) (newMap map[string]interface{}) { if mylog.Debugging { mylog.Debugf("enter flattenMap(%v,%v)\n", key, targetMap) defer func() { mylog.Debugf("exit flattenMap (%v)\n", newMap) }() } newMap = make(map[string]interface{}) for k, v := range targetMap { if submap, isMap := v.(map[string]interface{}); isMap { flattened := FlattenMap(k+"__", submap) for fk, fv := range flattened { newMap[key+fk] = fv } } else { newMap[key+k] = v } } return newMap }
func ParseActionType(s string) (at ActionType, err error) { if mylog.Debugging { mylog.Debugf("enter ParseActionType %q", s) defer func() { mylog.Debugf("exit ParseActionType %+v, %+v ", at, err) }() } var finalType ActionType switch s { case "SMS": finalType = SMS case "email": finalType = EMAIL case "update": finalType = UPDATE default: return 0, fmt.Errorf("unknown action type %q", s) } return finalType, nil }
func NewAction(id string, actionType ActionType, template string, parameters map[string]string) (axn Action, err error) { if mylog.Debugging { mylog.Debugf("enter NewAction %+v, %q, %+v", actionType, template, parameters) defer func() { mylog.Debugf("exit NewAction %+v, %+v ", axn, err) }() } var ad = &ActionData{Name: id, Type: actionType, Template: template, Parameters: parameters} switch actionType { case SMS: axn = &SMSAction{ad} case EMAIL: axn = &EmailAction{ad} case UPDATE: axn = &UpdateAction{ad} case HTTP: axn = &HTTPAction{ad} default: return nil, fmt.Errorf("unsupported action type %v", actionType) } return axn, nil }