Example #1
0
func parseAggregateRequest(r *http.Request) (*aggregator.Aggregator, *handlerError) {
	var request struct {
		Fun      string
		OutFmt   string
		Interval uint
		Wait     uint
		Regex    string
	}
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, &handlerError{err, "Couldn't parse json", http.StatusBadRequest}
	}
	aggregate, err := aggregator.New(request.Fun, request.Regex, request.OutFmt, request.Interval, request.Wait, table.In)
	if err != nil {
		return nil, &handlerError{err, "Couldn't create aggregator", http.StatusBadRequest}
	}
	return aggregate, nil
}
Example #2
0
func readAddAgg(s *toki.Scanner, table *Table) error {
	t := s.Next()
	if t.Token != sumFn && t.Token != avgFn {
		return errors.New("invalid function. need sum/avg")
	}
	fun := string(t.Value)

	if t = s.Next(); t.Token != word {
		return errors.New("need a regex string")
	}
	regex := string(t.Value)

	if t = s.Next(); t.Token != word {
		return errors.New("need a format string")
	}
	outFmt := string(t.Value)

	if t = s.Next(); t.Token != num {
		return errors.New("need an interval number")
	}
	interval, err := strconv.Atoi(strings.TrimSpace(string(t.Value)))
	if err != nil {
		return err
	}

	if t = s.Next(); t.Token != num {
		return errors.New("need a wait number")
	}
	wait, err := strconv.Atoi(strings.TrimSpace(string(t.Value)))
	if err != nil {
		return err
	}

	agg, err := aggregator.New(fun, regex, outFmt, uint(interval), uint(wait), table.In)
	if err != nil {
		return err
	}
	table.AddAggregator(agg)
	return nil
}
Example #3
0
func applyCommand(table *Table, cmd string) error {
	inputs := strings.Split(cmd, "  ")
	s := toki.NewScanner(tokenDefGlobal)
	s.SetInput(inputs[0])
	t := s.Next()
	if t.Token == addBlack {
		inputs = strings.Fields(cmd)

		prefix_pat := ""
		sub_pat := ""
		regex_pat := ""

		if len(inputs) == 2 {
			// The fallback case to support the default substring method
			sub_pat = inputs[1]
		} else if len(inputs) == 3 {
			// New case supporting prefix, sub and regex patterns
			match_method := inputs[1]
			pattern := inputs[2]

			if match_method == "prefix" {
				prefix_pat = pattern
			} else if match_method == "sub" {
				sub_pat = pattern
			} else if match_method == "regex" {
				regex_pat = pattern
			} else {
				return errors.New("addBlack [prefix|sub|regex] <pattern> (invalid match type)")
			}
		} else {
			return errors.New("addBlack [prefix|sub|regex] <pattern>")
		}

		m, err := NewMatcher(prefix_pat, sub_pat, regex_pat)
		if err != nil {
			return err
		}
		table.AddBlacklist(m)

	} else if t.Token == addAgg {
		inputs = strings.Fields(cmd)
		if len(inputs) != 6 {
			return errors.New("addAgg <func> <match> <key> <interval> <wait>")
		}
		fun := inputs[1]
		regex := inputs[2]
		outFmt := inputs[3]
		interval, err := strconv.Atoi(inputs[4])
		if err != nil {
			return err
		}
		wait, err := strconv.Atoi(inputs[5])
		if err != nil {
			return err
		}
		agg, err := aggregator.New(fun, regex, outFmt, uint(interval), uint(wait), table.In)
		if err != nil {
			return err
		}
		table.AddAggregator(agg)
	} else if t.Token == addRouteSendAllMatch {
		split := strings.Split(string(t.Value), " ")
		key := split[2]
		if len(inputs) < 2 {
			return fmt.Errorf("must get at least 1 destination for route '%s'", key)
		}

		prefix, sub, regex, err := readRouteOpts(s)
		if err != nil {
			return err
		}
		destinations, err := readDestinations(inputs[1:], table, true)
		if err != nil {
			return err
		}
		route, err := NewRouteSendAllMatch(key, prefix, sub, regex, destinations)
		if err != nil {
			return err
		}
		table.AddRoute(route)
	} else if t.Token == addRouteSendFirstMatch {
		split := strings.Split(string(t.Value), " ")
		key := split[2]
		if len(inputs) < 2 {
			return fmt.Errorf("must get at least 1 destination for route '%s'", key)
		}

		prefix, sub, regex, err := readRouteOpts(s)
		if err != nil {
			return err
		}
		destinations, err := readDestinations(inputs[1:], table, true)
		if err != nil {
			return err
		}
		route, err := NewRouteSendFirstMatch(key, prefix, sub, regex, destinations)
		if err != nil {
			return err
		}
		table.AddRoute(route)
	} else if t.Token == addRouteConsistentHashing {
		split := strings.Split(string(t.Value), " ")
		key := split[2]
		if len(inputs) < 3 {
			return fmt.Errorf("must get at least 2 destinations for consistent hashing route '%s'", key)
		}

		prefix, sub, regex, err := readRouteOpts(s)
		if err != nil {
			return err
		}
		destinations, err := readDestinations(inputs[1:], table, false)
		if err != nil {
			return err
		}
		route, err := NewRouteConsistentHashing(key, prefix, sub, regex, destinations)
		if err != nil {
			return err
		}
		table.AddRoute(route)
	} else if t.Token == addDest {
		//split := strings.Split(string(t.Value), " ")
		//key := split[2]

		fmt.Println("val", t.Value)
		fmt.Println("inputs", inputs[0])
	} else if t.Token == modDest {
		split := strings.Split(string(t.Value), " ")
		if len(split) < 4 {
			return errors.New("need a key, index and at least one option")
		}
		key := split[1]
		index, err := strconv.Atoi(split[2])
		if err != nil {
			return err
		}
		opts := make(map[string]string)
		for _, str := range split[3:] {
			opt := strings.Split(str, "=")
			if len(opt) != 2 {
				return fmt.Errorf("bad option format at '%s'", str)
			}
			opts[opt[0]] = opt[1]
		}

		return table.UpdateDestination(key, index, opts)
	} else if t.Token == modRoute {
		split := strings.Split(string(t.Value), " ")
		if len(split) < 3 {
			return errors.New("need a key and at least one option")
		}
		key := split[1]
		opts := make(map[string]string)
		for _, str := range split[2:] {
			opt := strings.Split(str, "=")
			if len(opt) != 2 {
				return fmt.Errorf("bad option format at '%s'", str)
			}
			opts[opt[0]] = opt[1]
		}

		return table.UpdateRoute(key, opts)
	} else {
		return fmt.Errorf("unrecognized command '%s'", t.Value)
	}
	if t = s.Next(); t.Token != toki.EOF {
		//fmt.Println("h")
		return fmt.Errorf("extraneous input '%s'", t.Value)
	}
	return nil
}