Esempio n. 1
0
func init() {
	gohanUtilInit := func(env *Environment) {
		vm := env.VM
		builtins := map[string]interface{}{
			"gohan_http": func(call otto.FunctionCall) otto.Value {
				if len(call.ArgumentList) == 4 {
					emptyOpts, _ := otto.ToValue(map[string]interface{}{})
					call.ArgumentList = append(call.ArgumentList, emptyOpts)
				}
				VerifyCallArguments(&call, "gohan_http", 5)
				method := call.Argument(0).String()
				url := call.Argument(1).String()
				headers := ConvertOttoToGo(call.Argument(2))
				data := ConvertOttoToGo(call.Argument(3))
				options := ConvertOttoToGo(call.Argument(4))
				log.Debug("gohan_http  [%s] %s %s %s", method, headers, url, options)
				code, headers, body, err := gohanHTTP(method, url, headers, data, options)
				log.Debug("response code %d", code)
				resp := map[string]interface{}{}
				if err != nil {
					resp["status"] = "err"
					resp["error"] = err.Error()
				} else {
					resp["status"] = "success"
					resp["status_code"] = fmt.Sprint(code)
					resp["body"] = body
					resp["headers"] = headers
				}
				log.Debug("response code %d", code)
				value, _ := vm.ToValue(resp)
				return value
			},
			"gohan_schemas": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_schemas", 0)
				manager := schema.GetManager()
				response := []interface{}{}
				for _, schema := range manager.OrderedSchemas() {
					response = append(response, schema.RawData)
				}
				value, _ := vm.ToValue(response)
				return value
			},
			"gohan_schema_url": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_schema_url", 1)
				schemaID := call.Argument(0).String()
				manager := schema.GetManager()
				schema, ok := manager.Schema(schemaID)
				if !ok {
					ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID)
				}
				value, _ := vm.ToValue(schema.URL)
				return value
			},
			"gohan_policies": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_policies", 0)
				manager := schema.GetManager()
				response := []interface{}{}
				for _, policy := range manager.Policies() {
					response = append(response, policy.RawData)
				}
				value, _ := vm.ToValue(response)
				return value
			},
			"gohan_uuid": func(call otto.FunctionCall) otto.Value {
				value, _ := vm.ToValue(uuid.NewV4().String())
				return value
			},
			"gohan_sleep": func(call otto.FunctionCall) otto.Value {
				if len(call.ArgumentList) != 1 {
					panic("Wrong number of arguments in gohan_schema_url call.")
				}
				rawSleep, _ := call.Argument(0).Export()
				var sleep time.Duration
				switch rawSleep.(type) {
				case int:
					sleep = time.Duration(rawSleep.(int))
				case int64:
					sleep = time.Duration(rawSleep.(int64))
				}
				time.Sleep(sleep * time.Millisecond)
				return otto.NullValue()
			},
			"gohan_template": func(call otto.FunctionCall) otto.Value {
				if len(call.ArgumentList) != 2 {
					panic("Wrong number of arguments in gohan_db_create call.")
				}
				rawTemplate, _ := call.Argument(0).Export()
				templateString, ok := rawTemplate.(string)
				if !ok {
					value, _ := vm.ToValue(rawTemplate)
					return value
				}
				data := ConvertOttoToGo(call.Argument(1))
				t := template.Must(template.New("tmpl").Parse(templateString))
				b := bytes.NewBuffer(make([]byte, 0, 100))
				t.Execute(b, data)
				value, _ := vm.ToValue(b.String())
				return value
			},
			"gohan_exec": func(call otto.FunctionCall) otto.Value {
				if len(call.ArgumentList) != 2 {
					panic("Wrong number of arguments in gohan_db_create call.")
				}
				rawCommand, _ := call.Argument(0).Export()
				command, ok := rawCommand.(string)
				if !ok {
					return otto.NullValue()
				}
				stringArgs := []string{}
				rawArgs, _ := call.Argument(1).Export()
				args, ok := rawArgs.([]interface{})
				if !ok {
					return otto.NullValue()
				}
				for _, arg := range args {
					stringArgs = append(stringArgs, arg.(string))
				}
				out, err := exec.Command(command, stringArgs...).Output()
				resp := map[string]string{}
				if err != nil {
					resp["status"] = "error"
					resp["output"] = err.Error()
				} else {
					resp["status"] = "success"
					resp["output"] = string(out)
				}
				value, _ := vm.ToValue(resp)
				return value
			},
		}

		for name, object := range builtins {
			vm.Set(name, object)
		}

	}
	RegistInit(gohanUtilInit)
}
Esempio n. 2
0
func init() {
	gohanDBInit := func(env *Environment) {
		vm := env.VM
		builtins := map[string]interface{}{
			"gohan_db_transaction": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_transaction", 0)
				tx, err := env.DataStore.Begin()
				if err != nil {
					ThrowOttoException(&call, "failed to start a transaction")
				}
				value, _ := vm.ToValue(tx)
				return value
			},
			"gohan_db_list": func(call otto.FunctionCall) otto.Value {
				if len(call.ArgumentList) < 4 {
					defaultOrderKey, _ := otto.ToValue("") // no sorting
					call.ArgumentList = append(call.ArgumentList, defaultOrderKey)
				}
				if len(call.ArgumentList) < 5 {
					defaultLimit, _ := otto.ToValue(0) // no limit
					call.ArgumentList = append(call.ArgumentList, defaultLimit)
				}
				if len(call.ArgumentList) < 6 {
					defaultOffset, _ := otto.ToValue(0) // no offset
					call.ArgumentList = append(call.ArgumentList, defaultOffset)
				}
				VerifyCallArguments(&call, "gohan_db_list", 6)

				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				filter, err := GetMap(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				orderKey, err := GetString(call.Argument(3))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				rawLimit, err := GetInt64(call.Argument(4))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				limit := uint64(rawLimit)
				rawOffset, err := GetInt64(call.Argument(5))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				offset := uint64(rawOffset)

				resp, err := GohanDbList(transaction, schemaID, filter, orderKey, limit, offset)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				value, _ := vm.ToValue(resp)
				return value
			},
			"gohan_db_fetch": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_fetch", 4)
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				ID, err := GetString(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				tenantID, err := GetString(call.Argument(3))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				resp, err := GohanDbFetch(transaction, schemaID, ID, tenantID)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				if resp == nil {
					otto.NullValue()
				}
				value, _ := vm.ToValue(resp.Data())
				return value
			},
			"gohan_db_state_fetch": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_state_fetch", 4)
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				ID, err := GetString(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				tenantID, err := GetString(call.Argument(3))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				data, err := GohanDbStateFetch(transaction, schemaID, ID, tenantID)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				value, _ := vm.ToValue(data)
				return value
			},
			"gohan_db_create": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_create", 3)
				transaction, err := GetTransaction(call.Argument(0))
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				dataMap, err := GetMap(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				resource, err := GohanDbCreate(transaction, needCommit, schemaID, dataMap)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				value, _ := vm.ToValue(resource.Data())
				return value
			},
			"gohan_db_update": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_update", 3)
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				dataMap, err := GetMap(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				resource, err := GohanDbUpdate(transaction, needCommit, schemaID, dataMap)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				value, _ := vm.ToValue(resource.Data())
				return value
			},
			"gohan_db_state_update": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_state_update", 3)
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				dataMap, err := GetMap(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				resource, err := GohanDbStateUpdate(transaction, needCommit, schemaID, dataMap)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				value, _ := vm.ToValue(resource.Data())
				return value
			},
			"gohan_db_delete": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_delete", 3)
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				ID, err := GetString(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				err = GohanDbDelete(transaction, needCommit, schemaID, ID)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				return otto.NullValue()
			},
			"gohan_db_query": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_query", 4)
				transaction, needCommit, err := env.GetOrCreateTransaction(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				if needCommit {
					defer transaction.Close()
				}
				schemaID, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				sqlString, err := GetString(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				arguments, err := GetList(call.Argument(3))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				resp, err := GohanDbQuery(transaction, needCommit, schemaID, sqlString, arguments)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				value, _ := vm.ToValue(resp)
				return value
			},
			"gohan_db_sql_make_columns": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_db_query", 1)
				schemaID, err := GetString(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}

				results, err := GohanDbMakeColumns(schemaID)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				value, _ := vm.ToValue(results)
				return value
			},
		}

		for name, object := range builtins {
			vm.Set(name, object)
		}
	}
	RegisterInit(gohanDBInit)
}
Esempio n. 3
0
func init() {
	gohanUtilInit := func(env *Environment) {
		vm := env.VM
		builtins := map[string]interface{}{
			"gohan_http": func(call otto.FunctionCall) otto.Value {
				if len(call.ArgumentList) == 4 {
					defaultOpaque, _ := otto.ToValue(false)
					call.ArgumentList = append(call.ArgumentList, defaultOpaque)
				}
				VerifyCallArguments(&call, "gohan_http", 5)
				method, err := GetString(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				url, err := GetString(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				rawHeaders, err := GetMap(call.Argument(2))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				// A string or a map[string]interface{}
				data := ConvertOttoToGo(call.Argument(3))
				opaque, err := GetBool(call.Argument(4))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				log.Debug("gohan_http  [%s] %s %s %s", method, rawHeaders, url, opaque)
				code, headers, body, err := gohanHTTP(method, url, rawHeaders, data, opaque)
				log.Debug("response code %d", code)
				resp := map[string]interface{}{}
				if err != nil {
					resp["status"] = "err"
					resp["error"] = err.Error()
				} else {
					resp["status"] = "success"
					resp["status_code"] = fmt.Sprint(code)
					resp["body"] = body
					resp["headers"] = headers
				}
				log.Debug("response code %d", code)
				value, _ := vm.ToValue(resp)
				return value
			},
			"gohan_schemas": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_schemas", 0)
				manager := schema.GetManager()
				response := []interface{}{}
				for _, schema := range manager.OrderedSchemas() {
					response = append(response, schema)
				}
				value, _ := vm.ToValue(response)
				return value
			},
			"gohan_schema_url": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_schema_url", 1)
				schemaID, err := GetString(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				schema, err := getSchema(schemaID)
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				value, _ := vm.ToValue(schema.URL)
				return value
			},
			"gohan_policies": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_policies", 0)
				manager := schema.GetManager()
				response := []interface{}{}
				for _, policy := range manager.Policies() {
					response = append(response, policy.RawData)
				}
				value, _ := vm.ToValue(response)
				return value
			},
			"gohan_uuid": func(call otto.FunctionCall) otto.Value {
				value, _ := vm.ToValue(uuid.NewV4().String())
				return value
			},
			"gohan_sleep": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_sleep", 1)
				rawSleep, _ := call.Argument(0).Export()
				var sleep time.Duration
				switch rawSleep.(type) {
				case int:
					sleep = time.Duration(rawSleep.(int))
				case int64:
					sleep = time.Duration(rawSleep.(int64))
				}
				time.Sleep(sleep * time.Millisecond)
				return otto.NullValue()
			},
			"gohan_template": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_template", 2)
				templateString, err := GetString(call.Argument(0))
				if err != nil {
					return call.Argument(0)
				}
				data := ConvertOttoToGo(call.Argument(1))
				t := template.Must(template.New("tmpl").Parse(templateString))
				b := bytes.NewBuffer(make([]byte, 0, 100))
				t.Execute(b, data)
				value, _ := vm.ToValue(b.String())
				return value
			},
			"gohan_exec": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_exec", 2)
				command, err := GetString(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				stringArgs, err := GetStringList(call.Argument(1))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				out, err := exec.Command(command, stringArgs...).Output()
				resp := map[string]string{}
				if err != nil {
					resp["status"] = "error"
					resp["output"] = err.Error()
				} else {
					resp["status"] = "success"
					resp["output"] = string(out)
				}
				value, _ := vm.ToValue(resp)
				return value
			},
			"gohan_config": func(call otto.FunctionCall) otto.Value {
				VerifyCallArguments(&call, "gohan_exec", 2)
				configKey, err := GetString(call.Argument(0))
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				defaultValue, err := call.Argument(1).Export()
				if err != nil {
					ThrowOttoException(&call, err.Error())
				}
				config := util.GetConfig()
				result := config.GetParam(configKey, defaultValue)
				value, _ := vm.ToValue(result)
				return value
			},
		}

		for name, object := range builtins {
			vm.Set(name, object)
		}

	}
	RegisterInit(gohanUtilInit)
}