diff --git a/examples/tutorial/hello/node/README.md b/examples/tutorial/hello/node/README.md index 2a4baff97..83903eb00 100644 --- a/examples/tutorial/hello/node/README.md +++ b/examples/tutorial/hello/node/README.md @@ -1,23 +1,41 @@ -## Quick Example for a NodeJS Function (4 minutes) +# Tutorial 1: NodeJS Function w/ Input (3 minutes) -This example will show you how to test and deploy a Node function to Oracle Functions. +This example will show you how to test and deploy Node code to Oracle Functions. It will also demonstrate passing data in through stdin. + +### First, run the following commands: ```sh -# create your func.yaml file -fn init /hello -# build the function -fn build -# test it +# Initialize your function creating a func.yaml file +fn init /hello + +# Test your function. +# This will run inside a container exactly how it will on the server. It will also install and vendor dependencies from Gemfile +fn run + +# Now try with an input cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create myapp /hello + +# Deploy your functions to the Oracle Functions server (default localhost:8080) +# This will create a route to your function as well +fn deploy myapp +``` +### Now call your function: + +```sh +curl http://localhost:8080/r/myapp/hello ``` -Now surf to: http://localhost:8080/r/myapp/hello +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) -## Dependencies +And now with the JSON input: + +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello +``` + +That's it! + +### Note on Dependencies Create a [package.json](https://docs.npmjs.com/getting-started/using-a-package.json) file in your functions directory. @@ -39,3 +57,33 @@ request('http://www.google.com', function (error, response, body) { } }) ``` + + +# In Review + +1. We piped JSON data into the function at the command line + ```sh + cat hello.payload.json | fn run + ``` + +2. We received our function input through **stdin** + ```node + obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) + ``` + +3. We wrote our output to **stdout** + ```node + console.log + ``` + +4. We sent **stderr** to the server logs + ```node + console.error + ``` + + +# Next Up +## [Tutorial 2: Input Parameters](examples/tutorial/params) + + + diff --git a/examples/tutorial/hello/node/func.js b/examples/tutorial/hello/node/func.js index 356544e81..5d78d1143 100644 --- a/examples/tutorial/hello/node/func.js +++ b/examples/tutorial/hello/node/func.js @@ -7,3 +7,5 @@ try { } } catch(e) {} console.log("Hello", name, "from Node!"); + +console.error("Stderr goes to the server logs..."); diff --git a/examples/tutorial/hello/php/Dockerfile b/examples/tutorial/hello/php/Dockerfile deleted file mode 100644 index 1da497e06..000000000 --- a/examples/tutorial/hello/php/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM funcy/php - -WORKDIR /app -ADD . /app - -ENTRYPOINT ["php", "hello.php"] diff --git a/examples/tutorial/hello/php/README.md b/examples/tutorial/hello/php/README.md index 1ccc9b1d1..d00232b40 100644 --- a/examples/tutorial/hello/php/README.md +++ b/examples/tutorial/hello/php/README.md @@ -1,10 +1,41 @@ -## Quick Example for a PHP Function (4 minutes) +# Tutorial 1: PHP Function w/ Input (3 minutes) -This example will show you how to test and deploy Go (Golang) code to Oracle Functions. +This example will show you how to test and deploy PHP code to Oracle Functions. It will also demonstrate passing data in through stdin. -### 1. Prepare the `func.yaml` file: +### First, run the following commands: -At func.yaml you will find: +```sh +# Initialize your function creating a func.yaml file +fn init /hello + +# Test your function. +# This will run inside a container exactly how it will on the server. It will also install and vendor dependencies from Gemfile +fn run + +# Now try with an input +cat hello.payload.json | fn run + +# Deploy your functions to the Oracle Functions server (default localhost:8080) +# This will create a route to your function as well +fn deploy myapp +``` +### Now call your function: + +```sh +curl http://localhost:8080/r/myapp/hello +``` + +Or call from a browser: [http://localhost:8080/r/myapp/hello](http://localhost:8080/r/myapp/hello) + +And now with the JSON input: + +```sh +curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/myapp/hello +``` + +That's it! + +### Note on Dependencies ```yml name: USERNAME/hello @@ -14,25 +45,6 @@ build: - docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install ``` -The important step here is to ensure you replace `USERNAME` with your Docker Hub account name. Some points of note: -the application name is `phpapp` and the route for incoming requests is `/hello`. These informations are relevant for -the moment you try to test this function. - -### 2. Build: - -```sh -# build the function -fn build -# test it -cat hello.payload.json | fn run -# push it to Docker Hub -fn push -# Create a route to this function on Oracle Functions -fn routes create phpapp /hello -``` - -`-v` is optional, but it allows you to see how this function is being built. - ### 3. Queue jobs for your function Now you can start jobs on your function. Let's quickly queue up a job to try it out. @@ -41,8 +53,30 @@ Now you can start jobs on your function. Let's quickly queue up a job to try it cat hello.payload.json | fn call phpapp /hello ``` -Here's a curl example to show how easy it is to do in any language: -```sh -curl -H "Content-Type: application/json" -X POST -d @hello.payload.json http://localhost:8080/r/phpapp/hello -``` \ No newline at end of file + +# In Review + +1. We piped JSON data into the function at the command line + ```sh + cat hello.payload.json | fn run + ``` + +2. We received our function input through **stdin** + ```node + obj = JSON.parse(fs.readFileSync('/dev/stdin').toString()) + ``` + +3. We wrote our output to **stdout** + ```node + console.log + ``` + +4. We sent **stderr** to the server logs + ```node + console.error + ``` + + +# Next Up +## [Tutorial 2: Input Parameters](examples/tutorial/params) diff --git a/examples/tutorial/hello/php/hello.php b/examples/tutorial/hello/php/func.php similarity index 100% rename from examples/tutorial/hello/php/hello.php rename to examples/tutorial/hello/php/func.php diff --git a/examples/tutorial/hello/php/func.yaml b/examples/tutorial/hello/php/func.yaml index 027b012ee..b645b5960 100644 --- a/examples/tutorial/hello/php/func.yaml +++ b/examples/tutorial/hello/php/func.yaml @@ -1,5 +1,6 @@ -name: USERNAME/hello +name: carimura2/hello version: 0.0.1 +runtime: php +entrypoint: php func.php path: /hello -build: -- docker run --rm -v "$PWD":/worker -w /worker funcy/php:dev composer install +max_concurrency: 1 diff --git a/fn/init.go b/fn/init.go index f07d7bb0a..18142a58b 100644 --- a/fn/init.go +++ b/fn/init.go @@ -23,13 +23,14 @@ import ( var ( fileExtToRuntime = map[string]string{ - ".go": "go", - ".js": "node", - ".rb": "ruby", - ".py": "python", - ".rs": "rust", - ".cs": "dotnet", - ".fs": "dotnet", + ".go": "go", + ".js": "node", + ".rb": "ruby", + ".py": "python", + ".php": "php", + ".rs": "rust", + ".cs": "dotnet", + ".fs": "dotnet", } fnInitRuntimes []string diff --git a/fn/langs/base.go b/fn/langs/base.go index 606402f7b..1319ca014 100644 --- a/fn/langs/base.go +++ b/fn/langs/base.go @@ -11,6 +11,8 @@ func GetLangHelper(lang string) LangHelper { return &RubyLangHelper{} case "python": return &PythonHelper{} + case "php": + return &PhpLangHelper{} case "rust": return &RustLangHelper{} case "dotnet": diff --git a/fn/langs/php.go b/fn/langs/php.go new file mode 100644 index 000000000..e97dd5d6e --- /dev/null +++ b/fn/langs/php.go @@ -0,0 +1,49 @@ +package langs + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +type PhpLangHelper struct { + BaseHelper +} + +func (lh *PhpLangHelper) Entrypoint() string { + return "php func.php" +} + +func (lh *PhpLangHelper) HasPreBuild() bool { + return true +} + +func (lh *PhpLangHelper) PreBuild() error { + wd, err := os.Getwd() + if err != nil { + return err + } + + if !exists(filepath.Join(wd, "composer.json")) { + return nil + } + + pbcmd := fmt.Sprintf("docker run --rm -v %s:/worker -w /worker funcy/php:dev composer install", wd) + fmt.Println("Running prebuild command:", pbcmd) + parts := strings.Fields(pbcmd) + head := parts[0] + parts = parts[1:len(parts)] + cmd := exec.Command(head, parts...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running docker build: %v", err) + } + return nil +} + +func (lh *PhpLangHelper) AfterBuild() error { + return nil +} diff --git a/fn/main.go b/fn/main.go index d26c14a4f..a2821c75d 100644 --- a/fn/main.go +++ b/fn/main.go @@ -37,7 +37,7 @@ func newFn() *cli.App { app.Version = vers.Version app.Authors = []cli.Author{{Name: "Oracle Corporation"}} app.Description = "Oracle Functions command line tools" - app.UsageText = `Check the manual at https://github.com/treeder/functions/blob/master/fn/README.md` + app.UsageText = `Check the manual at https://gitlab.oracledx.com/odx/functions/blob/master/fn/README.md` cli.AppHelpTemplate = `{{.Name}} {{.Version}}{{if .Description}}