blob: b432b88547120111f01cdf813d34c824eb7b436b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"os"
"reflect"
"strings"
)
// OwExecutionEnv is the execution environment set at compile time
var OwExecutionEnv = ""
func main() {
// check if the execution environment is correct
if OwExecutionEnv != "" && OwExecutionEnv != os.Getenv("__OW_EXECUTION_ENV") {
fmt.Println("Execution Environment Mismatch")
fmt.Println("Expected: ", OwExecutionEnv)
fmt.Println("Actual: ", os.Getenv("__OW_EXECUTION_ENV"))
os.Exit(1)
}
// debugging
var debug = os.Getenv("OW_DEBUG") != ""
if debug {
f, err := os.OpenFile("/tmp/action.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(f)
}
log.Printf("Environment: %v", os.Environ())
}
resultKind := reflect.TypeOf(Main).Out(0).Kind()
if resultKind != reflect.Map && resultKind != reflect.Slice && resultKind != reflect.Array {
fmt.Println("Support map and slice and array only")
os.Exit(1)
}
// input
out := os.NewFile(3, "pipe")
defer out.Close()
reader := bufio.NewReader(os.Stdin)
// acknowledgement of started action
fmt.Fprintf(out, `{ "ok": true}%s`, "\n")
if debug {
log.Println("action started")
}
// read-eval-print loop
for {
// read one line
inbuf, err := reader.ReadBytes('\n')
if err != nil {
if err != io.EOF {
log.Println(err)
}
break
}
if debug {
log.Printf(">>>'%s'>>>", inbuf)
}
// parse one line
var input map[string]interface{}
err = json.Unmarshal(inbuf, &input)
if err != nil {
log.Println(err.Error())
fmt.Fprintf(out, "{ error: %q}\n", err.Error())
continue
}
if debug {
log.Printf("%v\n", input)
}
// set environment variables
for k, v := range input {
if k == "value" {
continue
}
if s, ok := v.(string); ok {
os.Setenv("__OW_"+strings.ToUpper(k), s)
}
}
// get payload if not empty
isJsonObjectParam := true
var payloadForJsonObject map[string]interface{}
var payloadForJsonArray []interface{}
if value, ok := input["value"].(map[string]interface{}); ok {
payloadForJsonObject = value
} else {
if value, ok := input["value"].([]interface{}); ok {
payloadForJsonArray = value
isJsonObjectParam = false
}
}
// process the request
var result interface{}
funcMain := reflect.ValueOf(Main)
if isJsonObjectParam {
param := []reflect.Value{reflect.ValueOf(payloadForJsonObject)}
reflectResult := funcMain.Call(param)
result = reflectResult[0].Interface()
} else {
param := []reflect.Value{reflect.ValueOf(payloadForJsonArray)}
reflectResult := funcMain.Call(param)
result = reflectResult[0].Interface()
}
// encode the answer
output, err := json.Marshal(&result)
if err != nil {
log.Println(err.Error())
fmt.Fprintf(out, "{ error: %q}\n", err.Error())
continue
}
output = bytes.Replace(output, []byte("\n"), []byte(""), -1)
if debug {
log.Printf("<<<'%s'<<<", output)
}
fmt.Fprintf(out, "%s\n", output)
}
}