|  | @ -25,7 +25,8 @@ import ( | 
			
		
	
		
		
			
				
					|  |  | 	"io/ioutil" |  |  | 	"io/ioutil" | 
			
		
	
		
		
			
				
					|  |  | 	"sort" |  |  | 	"sort" | 
			
		
	
		
		
			
				
					|  |  | 	"bytes" |  |  | 	"bytes" | 
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  | 	"errors" | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  | 	 | 
			
		
	
		
		
			
				
					|  |  | 	"github.com/namsral/flag" |  |  | 	"github.com/namsral/flag" | 
			
		
	
		
		
			
				
					|  |  | 	"github.com/prometheus/client_golang/prometheus" |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
			
		
	
		
		
			
				
					|  |  | 	"github.com/prometheus/client_golang/prometheus/promhttp" |  |  | 	"github.com/prometheus/client_golang/prometheus/promhttp" | 
			
		
	
	
		
		
			
				
					|  | @ -37,6 +38,7 @@ const serviceLoadRetryTime = 1 * time.Minute | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | var ( |  |  | var ( | 
			
		
	
		
		
			
				
					|  |  | 	flag_test = flag.Bool("test", false, "print all available metrics to stdout") |  |  | 	flag_test = flag.Bool("test", false, "print all available metrics to stdout") | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	flag_collect = flag.Bool("collect", false, "print configured metrics to stdout and exit") | 
			
		
	
		
		
			
				
					|  |  | 	flag_jsonout = flag.String("json-out", "", "store metrics also to JSON file when running test") |  |  | 	flag_jsonout = flag.String("json-out", "", "store metrics also to JSON file when running test") | 
			
		
	
		
		
			
				
					|  |  | 	  |  |  | 	  | 
			
		
	
		
		
			
				
					|  |  | 	flag_addr = flag.String("listen-address", "127.0.0.1:9042", "The address to listen on for HTTP requests.") |  |  | 	flag_addr = flag.String("listen-address", "127.0.0.1:9042", "The address to listen on for HTTP requests.") | 
			
		
	
	
		
		
			
				
					|  | @ -61,10 +63,18 @@ type JSON_PromDesc struct { | 
			
		
	
		
		
			
				
					|  |  | 	VarLabels	[]string	`json:"varLabels"` |  |  | 	VarLabels	[]string	`json:"varLabels"` | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | type ActionArg struct { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	Name string				`json:"Name"` | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	IsIndex bool			`json:"IsIndex"` | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	ProviderAction string	`json:"ProviderAction"` | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	Value string			`json:"Value"` | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | type Metric struct { |  |  | type Metric struct { | 
			
		
	
		
		
			
				
					|  |  | 	// initialized loading JSON
 |  |  | 	// initialized loading JSON
 | 
			
		
	
		
		
			
				
					|  |  | 	Service	string		`json:"service"` |  |  | 	Service	string		`json:"service"` | 
			
		
	
		
		
			
				
					|  |  | 	Action	string		`json:"action"` |  |  | 	Action	string		`json:"action"` | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	ActionArgument	*ActionArg	`json:"actionArgument"` | 
			
		
	
		
		
			
				
					|  |  | 	Result	string		`json:"result"` |  |  | 	Result	string		`json:"result"` | 
			
		
	
		
		
			
				
					|  |  | 	OkValue	string		`json:"okValue"` |  |  | 	OkValue	string		`json:"okValue"` | 
			
		
	
		
		
			
				
					|  |  | 	PromDesc	JSON_PromDesc		`json:"promDesc"` |  |  | 	PromDesc	JSON_PromDesc		`json:"promDesc"` | 
			
		
	
	
		
		
			
				
					|  | @ -87,6 +97,29 @@ type FritzboxCollector struct { | 
			
		
	
		
		
			
				
					|  |  | 	Root       *upnp.Root |  |  | 	Root       *upnp.Root | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | // simple ResponseWriter to collect output
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | type TestResponseWriter struct { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	header		http.Header | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	statusCode	int | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	body		bytes.Buffer | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | func (w *TestResponseWriter) Header() http.Header { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	return w.header | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | func (w *TestResponseWriter) Write(b []byte) (int, error) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	return w.body.Write(b) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | func (w *TestResponseWriter) WriteHeader(statusCode int) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	w.statusCode = statusCode | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | func (w *TestResponseWriter) String() string { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	return w.body.String() | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | // LoadServices tries to load the service information. Retries until success.
 |  |  | // LoadServices tries to load the service information. Retries until success.
 | 
			
		
	
		
		
			
				
					|  |  | func (fc *FritzboxCollector) LoadServices() { |  |  | func (fc *FritzboxCollector) LoadServices() { | 
			
		
	
		
		
			
				
					|  |  | 	for { |  |  | 	for { | 
			
		
	
	
		
		
			
				
					|  | @ -113,6 +146,72 @@ func (fc *FritzboxCollector) Describe(ch chan<- *prometheus.Desc) { | 
			
		
	
		
		
			
				
					|  |  | 	} |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | func (fc *FritzboxCollector) ReportMetric(ch chan<- prometheus.Metric, m *Metric, val interface{}) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	var floatval float64 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	switch tval := val.(type) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		case uint64: | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			floatval = float64(tval) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		case bool: | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			if tval { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				floatval = 1 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			} else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				floatval = 0 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		case string: | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			if tval == m.OkValue { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				floatval = 1 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			} else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				floatval = 0 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		default: | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			fmt.Println("unknown type", val) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			collect_errors.Inc() | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			return | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		m.Desc, | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		m.MetricType, | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		floatval, | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		fc.Gateway, | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	)	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | func (fc *FritzboxCollector) GetActionResult(result_map map[string]upnp.Result, serviceType string, actionName string, actionArg *upnp.ActionArgument) (upnp.Result, error) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	m_key := serviceType+"|"+actionName | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	// for calls with argument also add arguement name and value to key	
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	if actionArg != nil { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		m_key += "|"+actionArg.Name+"|"+fmt.Sprintf("%v", actionArg.Value) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	last_result	:= result_map[m_key]; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	if last_result == nil { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		service, ok := fc.Root.Services[serviceType] | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		if !ok { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			return nil, errors.New(fmt.Sprintf("service %s not found", serviceType))	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		action, ok := service.Actions[actionName] | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		if !ok { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			return nil, errors.New(fmt.Sprintf("action %s not found in service %s", actionName, serviceType))	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		var err error | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		last_result, err = action.Call(actionArg); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		if err != nil { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			return nil, err | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		result_map[m_key]=last_result | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	return last_result, nil | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | func (fc *FritzboxCollector) Collect(ch chan<- prometheus.Metric) { |  |  | func (fc *FritzboxCollector) Collect(ch chan<- prometheus.Metric) { | 
			
		
	
		
		
			
				
					|  |  | 	fc.Lock() |  |  | 	fc.Lock() | 
			
		
	
		
		
			
				
					|  |  | 	root := fc.Root |  |  | 	root := fc.Root | 
			
		
	
	
		
		
			
				
					|  | @ -123,73 +222,57 @@ func (fc *FritzboxCollector) Collect(ch chan<- prometheus.Metric) { | 
			
		
	
		
		
			
				
					|  |  | 		return |  |  | 		return | 
			
		
	
		
		
			
				
					|  |  | 	} |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | 	var err error |  |  | 	// create a map for caching results
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 	var result_map = make(map[string]upnp.Result) |  |  | 	var result_map = make(map[string]upnp.Result) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | 	for _, m := range metrics { |  |  | 	for _, m := range metrics { | 
			
		
	
		
		
			
				
					
					|  |  | 		m_key := m.Service+"|"+m.Action |  |  | 		var actArg *upnp.ActionArgument | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		last_result	:= result_map[m_key]; |  |  | 		if m.ActionArgument != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		if last_result == nil { |  |  | 			aa := m.ActionArgument | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			service, ok := root.Services[m.Service] |  |  | 			var value interface {}   | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			if !ok { |  |  | 			value = aa.Value | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				// TODO
 |  |  | 			  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				fmt.Println("cannot find service", m.Service) |  |  | 			if aa.ProviderAction != "" { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				fmt.Println(root.Services) |  |  | 				provRes, err := fc.GetActionResult(result_map, m.Service, aa.ProviderAction, nil) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				continue |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			} |  |  | 				if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			action, ok := service.Actions[m.Action] |  |  | 					fmt.Printf("Error getting provider action %s result for %s.%s: %s\n", aa.ProviderAction, m.Service, m.Action, err.Error()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			if !ok { |  |  | 					collect_errors.Inc() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				// TODO
 |  |  | 					continue | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				fmt.Println("cannot find action", m.Action) |  |  | 				} | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				continue |  |  | 				 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  | 				var ok bool | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				value, ok = provRes[aa.Value]		// Value contains the result name for provider actions
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				if !ok { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 					fmt.Printf("provider action %s for %s.%s has no result %s", m.Service, m.Action, aa.Value) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 					collect_errors.Inc() | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 					continue | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				} | 
			
		
	
		
		
			
				
					|  |  | 			} |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | 			last_result, err = action.Call() |  |  | 			if aa.IsIndex { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			if err != nil { |  |  | 				// TODO handle index iterations
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				fmt.Println(err) |  |  | 			} else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				collect_errors.Inc() |  |  | 				actArg = &upnp.ActionArgument{Name: aa.Name, Value: value } | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 				continue |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 			} |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  | 			 |  |  | 		}  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			result_map[m_key]=last_result |  |  | 		 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		} |  |  | 		result, err := fc.GetActionResult(result_map, m.Service, m.Action, actArg) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | 		val, ok := last_result[m.Result] |  |  | 		if err != nil { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		if !ok { |  |  | 			fmt.Println(err.Error()) | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 			fmt.Println("result not found", m.Result) |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 			collect_errors.Inc() |  |  | 			collect_errors.Inc() | 
			
		
	
		
		
			
				
					
					|  |  | 			continue |  |  | 			continue			 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 		} |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  | 		 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		var floatval float64 |  |  | 		val, ok := result[m.Result] | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		switch tval := val.(type) { |  |  | 		if !ok { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 		case uint64: |  |  | 			fmt.Printf("%s.%s has no result %s", m.Service, m.Action, m.Result) | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 			floatval = float64(tval) |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 		case bool: |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			if tval { |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				floatval = 1 |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			} else { |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				floatval = 0 |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			} |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 		case string: |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			if tval == m.OkValue { |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				floatval = 1 |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			} else { |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				floatval = 0 |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			} |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 		default: |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			fmt.Println("unknown", val) |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 			collect_errors.Inc() |  |  | 			collect_errors.Inc() | 
			
		
	
		
		
			
				
					|  |  | 			continue |  |  | 			continue | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 		} |  |  | 		} | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | 		ch <- prometheus.MustNewConstMetric( |  |  | 		fc.ReportMetric(ch, m, val) | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 			m.Desc, |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			m.MetricType, |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			floatval, |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 			fc.Gateway, |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 		) |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  | 	} |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -219,26 +302,20 @@ func test() { | 
			
		
	
		
		
			
				
					|  |  | 		sort.Strings(actionKeys) |  |  | 		sort.Strings(actionKeys) | 
			
		
	
		
		
			
				
					|  |  | 		for _, l := range actionKeys { |  |  | 		for _, l := range actionKeys { | 
			
		
	
		
		
			
				
					|  |  | 			a := s.Actions[l] |  |  | 			a := s.Actions[l] | 
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  | 			fmt.Printf("  %s - arguments: variable [direction] (soap name, soap type)\n", a.Name) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			if !a.IsGetOnly() { |  |  | 			for _, arg := range a.Arguments { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				fmt.Printf("  %s - not calling - arguments: variable [direction] (soap name, soap type\n", a.Name) |  |  | 				sv := arg.StateVariable | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				for _, arg := range a.Arguments { |  |  | 				fmt.Printf("    %s [%s] (%s, %s)\n", arg.RelatedStateVariable, arg.Direction, arg.Name, sv.DataType) | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 					sv := arg.StateVariable |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 					fmt.Printf("    %s [%s] (%s, %s)\n", arg.RelatedStateVariable, arg.Direction, arg.Name, sv.DataType) |  |  |  | 
			
		
	
		
		
			
				
					|  |  |        				} |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				continue |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 			} |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  | 			 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			fmt.Printf("  %s\n", a.Name) |  |  | 			if !a.IsGetOnly() { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 			res, err := a.Call() |  |  | 				fmt.Printf("  %s - not calling, since arguments required or no output\n", a.Name) | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 			if err != nil { |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				fmt.Printf("    FAILED:%s\n", err.Error()) |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 				continue |  |  | 				continue | 
			
		
	
		
		
			
				
					|  |  | 			} |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			// only create JSON for Get
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			// TODO also create JSON templates for input actionParams 
 | 
			
		
	
		
		
			
				
					|  |  | 			for _, arg := range a.Arguments { |  |  | 			for _, arg := range a.Arguments { | 
			
		
	
		
		
			
				
					|  |  | 				fmt.Printf("    %s: %v\n", arg.RelatedStateVariable, res[arg.StateVariable.Name]) |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 				// create new json entry				
 |  |  | 				// create new json entry				
 | 
			
		
	
		
		
			
				
					|  |  | 				if(newEntry) { |  |  | 				if(newEntry) { | 
			
		
	
		
		
			
				
					|  |  | 					json.WriteString(",\n") |  |  | 					json.WriteString(",\n") | 
			
		
	
	
		
		
			
				
					|  | @ -254,6 +331,18 @@ func test() { | 
			
		
	
		
		
			
				
					|  |  | 				json.WriteString(arg.RelatedStateVariable) |  |  | 				json.WriteString(arg.RelatedStateVariable) | 
			
		
	
		
		
			
				
					|  |  | 				json.WriteString("\"\n\t}") |  |  | 				json.WriteString("\"\n\t}") | 
			
		
	
		
		
			
				
					|  |  | 			} |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			fmt.Printf("  %s - calling - results: variable: value\n", a.Name) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			res, err := a.Call(nil) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			if err != nil { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				fmt.Printf("    FAILED:%s\n", err.Error()) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				continue | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			for _, arg := range a.Arguments { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 				fmt.Printf("    %s: %v\n", arg.RelatedStateVariable, res[arg.StateVariable.Name]) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					|  |  | 		} |  |  | 		} | 
			
		
	
		
		
			
				
					|  |  | 	} |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  | 	 |  |  | 	 | 
			
		
	
	
		
		
			
				
					|  | @ -320,7 +409,25 @@ func main() { | 
			
		
	
		
		
			
				
					|  |  | 		Username: *flag_gateway_username, |  |  | 		Username: *flag_gateway_username, | 
			
		
	
		
		
			
				
					|  |  | 		Password: *flag_gateway_password, |  |  | 		Password: *flag_gateway_password, | 
			
		
	
		
		
			
				
					|  |  | 	} |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	if *flag_collect { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		collector.LoadServices() | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		prometheus.MustRegister(collector) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		prometheus.MustRegister(collect_errors) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		fmt.Println("collecting metrics via http") | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		// simulate HTTP request without starting actual http server
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		writer := TestResponseWriter{header: http.Header{}} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		request := http.Request{} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		promhttp.Handler().ServeHTTP(&writer, &request)  | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		fmt.Println(writer.String()) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		return | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 		 | 
			
		
	
		
		
			
				
					|  |  | 	go collector.LoadServices() |  |  | 	go collector.LoadServices() | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | 	prometheus.MustRegister(collector) |  |  | 	prometheus.MustRegister(collector) | 
			
		
	
	
		
		
			
				
					|  | @ -328,5 +435,6 @@ func main() { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | 	http.Handle("/metrics", promhttp.Handler()) |  |  | 	http.Handle("/metrics", promhttp.Handler()) | 
			
		
	
		
		
			
				
					|  |  | 	fmt.Printf("metrics available at http://%s/metrics\n", *flag_addr) |  |  | 	fmt.Printf("metrics available at http://%s/metrics\n", *flag_addr) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | 	log.Fatal(http.ListenAndServe(*flag_addr, nil)) |  |  | 	log.Fatal(http.ListenAndServe(*flag_addr, nil)) | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
	
		
		
			
				
					|  | 
 |