func LoadRemapRules()

in grove/remap/remap.go [322:468]


func LoadRemapRules(path string, pluginConfigLoaders map[string]plugin.LoadFunc, caches map[string]icache.Cache, baseTransport *http.Transport) ([]remapdata.RemapRule, map[string]interface{}, *remapdata.RemapRulesStats, error) {
	fmt.Println(time.Now().Format(time.RFC3339Nano) + " Loading Remap Rules")
	defer func() {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Loaded Remap Rules")
	}()
	file, err := os.Open(path)
	if err != nil {
		return nil, nil, nil, err
	}
	defer file.Close()

	remapRulesJSON := RemapRulesJSON{}
	if err := json.NewDecoder(file).Decode(&remapRulesJSON); err != nil {
		return nil, nil, nil, fmt.Errorf("decoding JSON: %s", err)
	}

	remapRules := RemapRules{RemapRulesBase: remapRulesJSON.RemapRulesBase}

	if remapRulesJSON.RetryCodes != nil {
		remapRules.RetryCodes = make(map[int]struct{}, len(*remapRulesJSON.RetryCodes))
		for _, code := range *remapRulesJSON.RetryCodes {
			if _, ok := rfc.ValidHTTPCodes[code]; !ok {
				return nil, nil, nil, fmt.Errorf("error parsing rules: retry code invalid: %v", code)
			}
			remapRules.RetryCodes[code] = struct{}{}
		}
	}
	if remapRulesJSON.TimeoutMS != nil {
		t := time.Duration(*remapRulesJSON.TimeoutMS) * time.Millisecond
		if remapRules.Timeout = &t; *remapRules.Timeout < 0 {
			return nil, nil, nil, fmt.Errorf("error parsing rules: timeout must be positive: %v", remapRules.Timeout)
		}
	}
	if remapRulesJSON.ParentSelection != nil {
		ps := remapdata.ParentSelectionTypeFromString(*remapRulesJSON.ParentSelection)
		if remapRules.ParentSelection = &ps; *remapRules.ParentSelection == remapdata.ParentSelectionTypeInvalid {
			return nil, nil, nil, fmt.Errorf("error parsing rules: parent selection invalid: '%v'", remapRulesJSON.ParentSelection)
		}
	}
	if remapRulesJSON.Stats.Allow != nil {
		if remapRules.Stats.Allow, err = makeIPNets(remapRulesJSON.Stats.Allow); err != nil {
			return nil, nil, nil, fmt.Errorf("error parsing rules allows: %v", err)
		}
	}
	if remapRulesJSON.Stats.Deny != nil {
		if remapRules.Stats.Deny, err = makeIPNets(remapRulesJSON.Stats.Deny); err != nil {
			return nil, nil, nil, fmt.Errorf("error parsing rules denys: %v", err)
		}
	}

	remapRules.Plugins = make(map[string]interface{}, len(remapRulesJSON.Plugins))
	for name, b := range remapRulesJSON.Plugins {
		if loadF := pluginConfigLoaders[name]; loadF != nil {
			remapRules.Plugins[name] = loadF(b)
		}
	}

	rules := make([]remapdata.RemapRule, len(remapRulesJSON.Rules))
	for i, jsonRule := range remapRulesJSON.Rules {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Creating Remap Rule " + jsonRule.Name)
		rule := remapdata.RemapRule{RemapRuleBase: jsonRule.RemapRuleBase}

		rule.Plugins = make(map[string]interface{}, len(jsonRule.Plugins))
		for name, b := range jsonRule.Plugins {
			if loadF := pluginConfigLoaders[name]; loadF != nil {
				rule.Plugins[name] = loadF(b)
			}
		}
		for name, loader := range remapRules.Plugins {
			if _, ok := rule.Plugins[name]; !ok {
				rule.Plugins[name] = loader
			}
		}

		if jsonRule.RetryCodes != nil {
			rule.RetryCodes = make(map[int]struct{}, len(*jsonRule.RetryCodes))
			for _, code := range *jsonRule.RetryCodes {
				if _, ok := rfc.ValidHTTPCodes[code]; !ok {
					return nil, nil, nil, fmt.Errorf("error parsing rule %v retry code invalid: %v", rule.Name, code)
				}
				rule.RetryCodes[code] = struct{}{}
			}
		} else {
			rule.RetryCodes = remapRules.RetryCodes
		}

		if jsonRule.TimeoutMS != nil {
			t := time.Duration(*jsonRule.TimeoutMS) * time.Millisecond
			if rule.Timeout = &t; *rule.Timeout < 0 {
				return nil, nil, nil, fmt.Errorf("error parsing rule %v timeout must be positive: %v", rule.Name, rule.Timeout)
			}
		} else {
			rule.Timeout = remapRules.Timeout
		}

		if rule.RetryNum == nil {
			rule.RetryNum = remapRules.RetryNum
		}

		if rule.PluginsShared == nil {
			rule.PluginsShared = remapRules.PluginsShared
		}

		cacheName := "" // default string is the default cache
		if jsonRule.CacheName != nil {
			cacheName = *jsonRule.CacheName
		}
		ok := false
		if rule.Cache, ok = caches[cacheName]; !ok {
			return nil, nil, nil, fmt.Errorf("error parsing rule %v: cache name %v not found", rule.Name, cacheName)
		}

		if rule.Allow, err = makeIPNets(jsonRule.Allow); err != nil {
			return nil, nil, nil, fmt.Errorf("error parsing rule %v allows: %v", rule.Name, err)
		}
		if rule.Deny, err = makeIPNets(jsonRule.Deny); err != nil {
			return nil, nil, nil, fmt.Errorf("error parsing rule %v denys: %v", rule.Name, err)
		}
		if rule.To, err = makeTo(jsonRule.To, rule, baseTransport); err != nil {
			return nil, nil, nil, fmt.Errorf("error parsing rule %v to: %v", rule.Name, err)
		}
		if jsonRule.ParentSelection != nil {
			ps := remapdata.ParentSelectionTypeFromString(*jsonRule.ParentSelection)
			if rule.ParentSelection = &ps; *rule.ParentSelection == remapdata.ParentSelectionTypeInvalid {
				return nil, nil, nil, fmt.Errorf("error parsing rule %v parent selection invalid: '%v'", rule.Name, jsonRule.ParentSelection)
			}
		} else {
			rule.ParentSelection = remapRules.ParentSelection
		}

		if rule.ParentSelection == nil {
			return nil, nil, nil, fmt.Errorf("error parsing rule %v - no parent_selection - must be set at rules or rule level", rule.Name)
		}

		if len(rule.To) == 0 {
			return nil, nil, nil, fmt.Errorf("error parsing rule %v - no to - must have at least one parent", rule.Name)
		}

		if *rule.ParentSelection == remapdata.ParentSelectionTypeConsistentHash {
			rule.ConsistentHash = makeRuleHash(rule)
		} else {
		}
		rules[i] = rule
	}

	return rules, remapRules.Plugins, &remapRules.Stats, nil
}