Beispiel #1
0
func fetchConfig(funcname string, name string, config interface{}) bool {

	var ret otto.Value
	var err error

	if name == "" {
		ret, err = jsVM.Call(funcname, nil)
	} else {
		ret, err = jsVM.Call(funcname, nil, name)
	}

	if err != nil {
		log.Printf("call failed, in '%s', %v", funcname, err)
		return false
	}

	jsonConfig, err := ret.ToString()

	if err != nil {
		log.Println(err)
		return false
	}

	if err := json.Unmarshal([]byte(jsonConfig), config); err != nil {
		log.Printf("json.Unmarshal failed, in '%s', %v", funcname, err)
		return false
	}

	return true
}
Beispiel #2
0
func (es *ExpressionStats) ConsiderValue(val otto.Value) {
	// increment the count
	es.Count += 1

	if val.IsNumber() {
		f, err := val.ToFloat()
		if err != nil {
			log.Printf("Error converting number to float %v", err)
		} else {
			// update the sum
			es.Sum += f

			// if this is smaller than anything we've seen so far update the min
			if f < es.Min {
				es.Min = f
			}

			// if this is larger than anything we've seen so far update the max
			if f > es.Max {
				es.Max = f
			}

			// update the average (perhaps wasteful, could be done once at the end
			// but i'd have to walk the whole tree again, for now will do update it each time
			es.Avg = es.Sum / float64(es.Count) // we incremented es.count in this function, can not divide by 0
		}
	}
}
// find the node from the based ont the hash passed in
// the hash needs to at least have a {name: }property
func (js *JavascriptBuilder) findNode(token string, in otto.Value) (n Node, err error) {
	var (
		givenOptions map[string]interface{}
		ok           bool
		name         string
	)

	e, err := in.Export()
	if err != nil {
		return n, err
	}

	// accept both a json hash and a string as an argument.
	// if the arg is a hash, then we should extract the name,
	// and pull the node from the yaml, and then merge the given options
	// over top of the options presented in the config node.
	//
	// if the arg is a string, then use that string as the name
	// and pull the config node
	switch arg := e.(type) {
	case map[string]interface{}:
		givenOptions = arg
		if name, ok = givenOptions["name"].(string); ok {
			// merge the two maps
			tmpMap := make(map[string]interface{})
			for k, v := range js.config.Nodes[name] {
				tmpMap[k] = v
			}
			for k, v := range givenOptions {
				tmpMap[k] = v
			}
			givenOptions = tmpMap
		} else { // we don't have a name, so lets generate one.
			u, err := uuid.NewV4()
			if err != nil {
				return n, fmt.Errorf("%s error. unable to create uuid (%s)", token, err.Error())
			}
			name = u.String()
			givenOptions["name"] = name
		}
	case string:
		name = arg
		givenOptions, ok = js.config.Nodes[name]
		if !ok {
			return n, fmt.Errorf("%s error. unable to find node '%s'", token, name)
		}
	}

	if token == "transform" {
		// this is a little bit of magic so that transformers (which are added by the transform fn get the right kind)
		givenOptions["type"] = "transformer"
	}

	kind, ok := givenOptions["type"].(string)
	if !ok {
		return n, fmt.Errorf("%s: hash requires a type field, but no type given", token)
	}

	return NewNode(name, kind, givenOptions)
}
Beispiel #4
0
// Execute Javascript
func (sh *Shell) execScript(editor bool) stateFn {
	var out string
	var value otto.Value
	var err error

	if !editor {
		tmp := strings.TrimPrefix(sh.input, RunJavascript) // remove script meta-command
		value, err = sh.jsengine.Run(tmp)
	} else {
		value, err = sh.jsengine.Run(sh.input)
	}

	if err != nil {
		out = err.Error()
	} else if value.IsDefined() {
		out = value.String()
	}

	sh.write(out)
	if !editor {
		sh.line.AppendHistory(sh.input)
	}

	return bqlPrompt
}
Beispiel #5
0
func formatObject(v otto.Value, width, indent, limit, level int, seen map[otto.Value]bool) (string, error) {
	if seen[v] {
		return strings.Repeat(" ", level*indent) + "[circular]", nil
	}

	o := v.Object()

	bits := []string{"{"}

	keys := o.Keys()

	for i, k := range keys {
		e, err := o.Get(k)

		d, err := formatIndent(e, width, indent, limit-1, level+1, len(k)+2, seenWith(seen, v))
		if err != nil {
			return "", err
		}

		bits = append(bits, strings.Repeat(" ", (level+1)*indent)+k+": "+d+",")

		i++
	}

	bits = append(bits, strings.Repeat(" ", level*indent)+"}")

	return strings.Join(bits, "\n"), nil
}
Beispiel #6
0
func formatObjectOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) {
	if limit == 0 {
		return "...", nil
	}

	if seen[v] {
		return "[circular]", nil
	}

	o := v.Object()

	bits := []string{}

	keys := o.Keys()

	for _, k := range keys {
		e, err := o.Get(k)
		if err != nil {
			return "", err
		}

		d, err := formatOneLine(e, limit-1, seenWith(seen, v))
		if err != nil {
			return "", err
		}

		bits = append(bits, k+": "+d)
	}

	return "{" + strings.Join(bits, ", ") + "}", nil
}
Beispiel #7
0
//GetInt64 gets int64 from otto value
func GetInt64(value otto.Value) (result int64, err error) {
	result, err = value.ToInteger()
	if err != nil {
		err = fmt.Errorf(wrongArgumentType, value, "int64")
	}
	return
}
Beispiel #8
0
func runIteratorWithCallback(it graph.Iterator, ses *Session, callback otto.Value, this otto.FunctionCall, limit int) {
	count := 0
	it, _ = it.Optimize()
	for {
		if ses.doHalt {
			return
		}
		_, ok := it.Next()
		if !ok {
			break
		}
		tags := make(map[string]graph.TSVal)
		it.TagResults(&tags)
		val, _ := this.Otto.ToValue(tagsToValueMap(tags, ses))
		val, _ = callback.Call(this.This, val)
		count++
		if limit >= 0 && count >= limit {
			break
		}
		for it.NextResult() == true {
			if ses.doHalt {
				return
			}
			tags := make(map[string]graph.TSVal)
			it.TagResults(&tags)
			val, _ := this.Otto.ToValue(tagsToValueMap(tags, ses))
			val, _ = callback.Call(this.This, val)
			count++
			if limit >= 0 && count >= limit {
				break
			}
		}
	}
	it.Close()
}
Beispiel #9
0
//GetBool gets bool from otto value
func GetBool(value otto.Value) (bool, error) {
	rawBool, _ := value.Export()
	result, ok := rawBool.(bool)
	if !ok {
		return false, fmt.Errorf(wrongArgumentType, rawBool, "bool")
	}
	return result, nil
}
Beispiel #10
0
//GetAuthorization gets Transaction from otto value
func GetAuthorization(value otto.Value) (schema.Authorization, error) {
	rawAuthorization, _ := value.Export()
	result, ok := rawAuthorization.(schema.Authorization)
	if !ok {
		return nil, fmt.Errorf(wrongArgumentType, rawAuthorization, "Authorization")
	}
	return result, nil
}
Beispiel #11
0
//GetTransaction gets Transaction from otto value
func GetTransaction(value otto.Value) (transaction.Transaction, error) {
	rawTransaction, _ := value.Export()
	result, ok := rawTransaction.(transaction.Transaction)
	if !ok {
		return nil, fmt.Errorf(wrongArgumentType, rawTransaction, "Transaction")
	}
	return result, nil
}
Beispiel #12
0
//GetString gets string from otto value
func GetString(value otto.Value) (string, error) {
	rawString, _ := value.Export()
	result, ok := rawString.(string)
	if !ok {
		return "", fmt.Errorf(wrongArgumentType, rawString, "string")
	}
	return result, nil
}
Beispiel #13
0
//GetStringList gets []string  from otto value
func GetStringList(value otto.Value) ([]string, error) {
	rawSlice, _ := value.Export()
	rawResult, ok := rawSlice.([]string)
	if !ok {
		return make([]string, 0), fmt.Errorf(wrongArgumentType, rawSlice, "array of strings")
	}
	return rawResult, nil
}
Beispiel #14
0
func (f *JSFilter) Filter(ev *message.Event) (*message.Event, error) {
	var dropped bool
	f.vm.Set("$", map[string]interface{}{
		"env": f.conf.Env,
		"event": map[string]interface{}{
			"tag":    ev.Tag,
			"time":   ev.Time,
			"record": ev.Record,
		},
		"drop": func(call otto.FunctionCall) otto.Value {
			dropped = true
			return otto.Value{}
		},
		"emit": func(call otto.FunctionCall) (ret otto.Value) {
			var record otto.Value
			var t time.Time
			tag := call.Argument(0).String()
			if !call.Argument(2).IsDefined() {
				record = call.Argument(1)
				t = time.Now()
			} else {
				record = call.Argument(2)
				v, err := call.Argument(1).Export()
				if err != nil {
					f.env.Log.Warningf("Failed to get time: %v", err)
					return
				}
				var ok bool
				t, ok = v.(time.Time)
				if !ok {
					f.env.Log.Warningf("Failed to get time: unsupported type %T", v)
					return
				}
			}
			rec, err := record.Export()
			if err != nil {
				f.env.Log.Warningf("Failed to get record: %v", err)
				return
			}
			typedRec, ok := rec.(map[string]interface{})
			if !ok {
				f.env.Log.Warningf("Failed to get record: Unsupported type %T", rec)
				return
			}
			f.env.Emit(message.NewEventWithTime(tag, t, typedRec))
			return
		},
	})
	_, err := f.vm.Run(f.script)
	if err != nil {
		return nil, err
	} else if dropped {
		return nil, nil
	}
	return ev, nil
}
Beispiel #15
0
//GetMap gets map[string]interface{} from otto value
func GetMap(value otto.Value) (map[string]interface{}, error) {
	rawMap, _ := value.Export()
	result, ok := rawMap.(map[string]interface{})
	if !ok {
		return map[string]interface{}{}, fmt.Errorf(wrongArgumentType, rawMap, "Object")
	}
	for key, value := range result {
		result[key] = ConvertOttoToGo(value)
	}
	return result, nil
}
func (rm refMap) MustResolve(ref otto.Value) interface{} {
	key, err := ref.ToString()
	if err != nil {
		panic(err)
	}
	v, ok := rm[key]
	if !ok {
		panic(fmt.Sprintf("Invalid reference: %s", key))
	}
	return v
}
Beispiel #17
0
//GetOrCreateTransaction gets transaction from otto value or creates new is otto value is null
func (env *Environment) GetOrCreateTransaction(value otto.Value) (transaction.Transaction, bool, error) {
	if !value.IsNull() {
		tx, err := GetTransaction(value)
		return tx, false, err
	}
	dataStore := env.DataStore
	tx, err := dataStore.Begin()
	if err != nil {
		return nil, false, fmt.Errorf("Error creating transaction: %v", err.Error())
	}
	return tx, true, nil
}
Beispiel #18
0
func (p *Plugin) AddCallback(eventCode string, name string, callback otto.Value) {
	wrappedCallback := func(env otto.Value) {
		_, err := callback.Call(env)
		if err != nil {
			p.log.Printf("Callback `%s` (%#v) for event code `%s` errored: %s", name, callback, eventCode, err)
		}
	}
	p.callbacks[eventCode] = append(p.callbacks[eventCode], &pluginFunc{
		function: wrappedCallback,
		help:     name,
	})
}
Beispiel #19
0
func (wk *worker) runIteratorWithCallback(it graph.Iterator, callback otto.Value, this otto.FunctionCall, limit int) {
	ctx, cancel := wk.newContext()
	defer cancel()

	err := graph.Iterate(ctx, it).Paths(true).Limit(limit).TagEach(func(tags map[string]graph.Value) {
		val, _ := this.Otto.ToValue(wk.tagsToValueMap(tags))
		val, _ = callback.Call(this.This, val)
	})
	if err != nil {
		clog.Errorf("gremlin: %v", err)
	}
}
Beispiel #20
0
// uses the "prettyPrint" JS function to format a value
func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) {
	var method otto.Value
	v, err = self.vm.ToValue(v)
	if err != nil {
		return
	}
	method, err = self.vm.Get("prettyPrint")
	if err != nil {
		return
	}
	return method.Call(method, v)
}
Beispiel #21
0
func (p *PacSandbox) ottoRetString(v otto.Value, rte error) (string, error) {
	if rte != nil {
		return "", rte
	}

	ret, err := v.ToString()

	if err != nil {
		return "", err
	}

	return ret, nil
}
Beispiel #22
0
// PrettyPrint writes v to standard output.
func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) {
	var method otto.Value
	self.do(func(vm *otto.Otto) {
		val, err = vm.ToValue(v)
		if err != nil {
			return
		}
		method, err = vm.Get("prettyPrint")
		if err != nil {
			return
		}
		val, err = method.Call(method, val)
	})
	return val, err
}
Beispiel #23
0
//GetList gets []interface{} from otto value
func GetList(value otto.Value) ([]interface{}, error) {
	rawSlice, err := value.Export()
	result := make([]interface{}, 0)
	if rawSlice == nil || err != nil {
		return result, err
	}
	typeOfSlice := reflect.TypeOf(rawSlice)
	if typeOfSlice.Kind() != reflect.Array && typeOfSlice.Kind() != reflect.Slice {
		return result, fmt.Errorf(wrongArgumentType, value, "array")
	}
	list := reflect.ValueOf(rawSlice)
	for i := 0; i < list.Len(); i++ {
		result = append(result, ConvertOttoToGo(list.Index(i).Interface()))
	}

	return result, err
}
Beispiel #24
0
func (wk *worker) runIteratorWithCallback(it graph.Iterator, callback otto.Value, this otto.FunctionCall, limit int) {
	n := 0
	it, _ = it.Optimize()
	if glog.V(2) {
		b, err := json.MarshalIndent(it.Describe(), "", "  ")
		if err != nil {
			glog.V(2).Infof("failed to format description: %v", err)
		} else {
			glog.V(2).Infof("%s", b)
		}
	}
	for {
		select {
		case <-wk.kill:
			return
		default:
		}
		if !graph.Next(it) {
			break
		}
		tags := make(map[string]graph.Value)
		it.TagResults(tags)
		val, _ := this.Otto.ToValue(wk.tagsToValueMap(tags))
		val, _ = callback.Call(this.This, val)
		n++
		if limit >= 0 && n >= limit {
			break
		}
		for it.NextPath() {
			select {
			case <-wk.kill:
				return
			default:
			}
			tags := make(map[string]graph.Value)
			it.TagResults(tags)
			val, _ := this.Otto.ToValue(wk.tagsToValueMap(tags))
			val, _ = callback.Call(this.This, val)
			n++
			if limit >= 0 && n >= limit {
				break
			}
		}
	}
	it.Close()
}
Beispiel #25
0
func (p *Plugin) SetCommand(name string, command otto.Value, help string) {
	if _, ok := p.commands[name]; ok {
		if p.cfg.Irc.Debug || p.cfg.Debug {
			p.log.Printf("Warning: Command `%s` was already defined. Overriding...", name)
		}
	}
	wrappedCommand := func(env otto.Value) {
		_, err := command.Call(env)
		if err != nil {
			p.log.Printf("Command `%s` errored: %s", name, err)
		}
	}
	p.commands[name] = &pluginFunc{
		function: wrappedCommand,
		help:     help,
	}
}
Beispiel #26
0
func (ctrl *JsController) callHandler(handler otto.Value, params ...interface{}) (interface{}, error) {
	if !handler.IsFunction() {
		return nil, fmt.Errorf("Result should be a function, got %v", handler)
	}
	out, err := handler.Call(handler, params...)
	if err != nil {
		glog.Errorf("Call resulted in failure %#v", err)
		return nil, err
	}

	obj, err := out.Export()
	if err != nil {
		glog.Errorf("Failed to extract response %#v", err)
		return nil, err
	}
	return obj, nil
}
func ottoValueToStringArray(value otto.Value) []string {
	{
		value, _ := value.Export()
		switch value := value.(type) {
		case string:
			return []string{value}
		case []interface{}:
			result := make([]string, 0, len(value))
			for _, item := range value {
				if value, ok := item.(string); ok {
					result = append(result, value)
				}
			}
			return result
		}
	}
	return nil
}
Beispiel #28
0
func objToHeader(data *otto.Value, header http.Header) {
	dataMap, _ := data.Export()
	for key, val := range dataMap.(map[string]interface{}) {
		switch val.(type) {
		case string:
			{
				header.Add(key, val.(string))
				break
			}
		case []interface{}:
			{
				for _, headerVal := range val.([]interface{}) {
					header.Add(key, headerVal.(string))
				}
				break
			}
		}
	}
}
Beispiel #29
0
func formatArrayOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) {
	if limit == 0 {
		return "...", nil
	}

	if seen[v] {
		return "[circular]", nil
	}

	o := v.Object()

	lv, err := o.Get("length")
	if err != nil {
		return "", err
	}
	li, err := lv.Export()
	if err != nil {
		return "", err
	}
	l, ok := li.(uint32)
	if !ok {
		return "", fmt.Errorf("length property must be a number; was %T", li)
	}

	var bits []string

	for i := 0; i < int(l); i++ {
		e, err := o.Get(fmt.Sprintf("%d", i))
		if err != nil {
			return "", err
		}

		d, err := formatOneLine(e, limit-1, seenWith(seen, v))
		if err != nil {
			return "", err
		}

		bits = append(bits, d)
	}

	return "[" + strings.Join(bits, ", ") + "]", nil
}
// Converts a JS array into a Go string array.
func ottoArrayToStrings(array otto.Value) []string {
	goValue, err := array.Export()
	if err != nil {
		return nil
	}
	if result, ok := goValue.([]string); ok {
		return result
	}
	goArray, ok := goValue.([]interface{})
	if !ok || len(goArray) == 0 {
		return nil
	}
	result := make([]string, 0, len(goArray))
	for _, item := range goArray {
		if str, ok := item.(string); ok {
			result = append(result, str)
		}
	}
	return result
}