{"id":23338395,"url":"https://github.com/abhirockzz/fn-go-sdk-invoke","last_synced_at":"2025-04-07T13:43:50.893Z","repository":{"id":79124955,"uuid":"172645248","full_name":"abhirockzz/fn-go-sdk-invoke","owner":"abhirockzz","description":"Invoke Oracle Functions using the OCI Go SDK","archived":false,"fork":false,"pushed_at":"2019-05-28T10:51:47.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2023-08-20T07:22:14.430Z","etag":null,"topics":["faas","go","golang","oracle-cloud-infrastructure","oracle-functions","orafunc-la","serverless"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abhirockzz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-26T05:38:24.000Z","updated_at":"2024-06-19T06:46:40.620Z","dependencies_parsed_at":"2023-03-13T20:10:54.974Z","dependency_job_id":null,"html_url":"https://github.com/abhirockzz/fn-go-sdk-invoke","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abhirockzz%2Ffn-go-sdk-invoke","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abhirockzz%2Ffn-go-sdk-invoke/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abhirockzz%2Ffn-go-sdk-invoke/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abhirockzz%2Ffn-go-sdk-invoke/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abhirockzz","download_url":"https://codeload.github.com/abhirockzz/fn-go-sdk-invoke/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247666003,"owners_count":20975785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["faas","go","golang","oracle-cloud-infrastructure","oracle-functions","orafunc-la","serverless"],"created_at":"2024-12-21T03:13:47.865Z","updated_at":"2025-04-07T13:43:50.870Z","avatar_url":"https://github.com/abhirockzz.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Invoke Oracle Functions using the OCI Go SDK\n\nThis example demonstrates how to invoke a function on Oracle Functions using (preview version of) the Oracle Cloud Infrastructure Go SDK. \n\n## Introduction\n\nTo be specifc, it shows how you can invoke a function by its name given that you also provide the application name (to which the function belongs), the OCI compartment (for which your Oracle Functions service is configured) and the OCID of your tenancy\n\nOCI SDK exposes two endpoints for Oracle Functions\n\n- `functions.FunctionsManagementClient` - for CRUD operations e.g. creating applications, listing functions etc.\n- `functions.FunctionsInvokeClient` - only required for invoking a function\n\nalong with a number of wrapper structs like `functions.FunctionSummary`,\n`functions.ApplicationSummary`, and `identity.Compartment`.\n\nThe `invokeFunction` function in struct `FunctionsUtil` (`functions-util.go`) takes a `functions.FunctionSummary` for a\ngiven function, the desired payload, and uses `functions.FunctionsInvokeClient` to\nactually invoke the function.  This seems relatively straightforward but\nobtaining a `functions.FunctionSummary` requires navigating from the OCI compartment, to\nthe application, to the function. This involves multiple lookups (API calls).\n\nTo illustrate the steps, the `FunctionsUtils` struct provides a number of methods\nthat capture the steps required to navigate the OCI object model\n\n- `getCompartment(compartmentName)` returns a Compartment with a given name\n  using `ListCompartments` function in `identity.IdentityClient` - it looks for compartments\n  in the tenancy with the provided name\n- `getApplication(appName, compartment)` searches in the specified compartment\n  for the named application using the `ListApplications` function exposed by `functions.FunctionsManagementClient`\n- `getFunction(funcName, application)` searches in the specified application for\n  the named function using `ListFunctions` in `functions.FunctionsManagementClient`.\n  The result is a `functions.FunctionSummary` object which provides the function ID, name,\n  and invoke endpoint\n\n\u003e The key thing to note here is that the function ID and its invoke endpoint will not change unless you delete the function (or the application it's a part of). As a result you do not need to repeat the above mentioned flow of API calls - the funtion ID and its invoke endpoint can be derived once and then **cached** in-memory (e.g. in a `map`) or an external data store\n\nOnce we have a `functions.FunctionSummary` (containing function OCID and invoke enpdoint)\nat our disposal we can use the `invokeFunction(function,payload)` function in `FunctionsUtils` which:\n\n- builds `functions.InvokeFunctionRequest` with the function OCID and the (optional) payload which we want to send to our function\n- sets `functionsInvokeClient.Host` to the value of the invoke endpoint\n- andn finally calls `invokeFunction` function in `functions.FunctionsInvokeClient` with the\n  `functions.InvokeFunctionRequest` returning the String response from the resulting\n  `functions.InvokeFunctionResponse` object\n\n### Authentication\n\nThe client program needs to authenticate to OCI before being able to make service calls. The standard OCI authenitcation is used, which accepts the following inputs (details below) - tenant OCID, user OCID, fingerprint, private key and passphrase (optional). These details are required to instantiate a `common.ConfigurationProvider` using `common.NewRawConfigurationProvider` method and subsequently used by the service client objects (`functions.FunctionsInvokeClient`, `functions.FunctionsManagementClient`, `identity.IdentityClient`)\n\nThis example does not assume the presence of an OCI config file on the machine from where this is being executed. However, if you have one present as per the standard OCI practices i.e. a config file in your home directory, you can use `common.DefaultConfigProvider` for convenience\n\n## Pre-requisites\n\n1. Install latest Fn CLI - \n\n`curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh`\n\n2. Create a function to invoke\n\nCreate a function using [Go Hello World Function](https://github.com/abhirockzz/oracle-functions-hello-worlds/blob/master/golang-hello-world.md)\n\n### Install preview OCI Go SDK\n\nYou need to add the OCI Go SDK to your `GOPATH`\n\nSet `GOPATH` environment variable\n\n    export GOPATH=\u003cYOUR_GOPATH\u003e\n\n1. Back up your existing installation of OCI Go SDK and remove it from your `GOPATH`\n\n2. Download and unzip the preview version of the OCI Go SDK\n\n        unzip oci-go-sdk-preview@35505cb3d6a.zip\n\n3. Copy the preview SDK to your `GOPATH`\n\n        cp -R oci-go-sdk-preview@35505cb3d6a/ $GOPATH/src/github.com/oracle/oci-go-sdk\n\n### Set environment variables\n\n   ```shell\n   export TENANT_OCID=\u003cOCID of your tenancy\u003e\n   export USER_OCID=\u003cOCID of the OCI user\u003e\n   export PUBLIC_KEY_FINGERPRINT=\u003cpublic key fingerprint\u003e\n   export PRIVATE_KEY_LOCATION=\u003clocation of the private key on your machine\u003e\n   ```\n\n   \u003e please note that `PASSPHRASE` is optional i.e. only required if your\n   \u003e private key has one\n\n   ```shell\n   export PASSPHRASE=\u003cprivate key passphrase\u003e\n   ```\n\n   e.g.\n\n   ```shell\n   export TENANT_OCID=ocid1.tenancy.oc1..aaaaaaaaydrjd77otncda2xn7qrv7l3hqnd3zxn2u4siwdhniibwfv4wwhtz\n   export USER_OCID=ocid1.user.oc1..aaaaaaaavz5efd7jwjjipbvm536plgylg7rfr53obvtghpi2vbg3qyrnrtfa\n   export PUBLIC_KEY_FINGERPRINT=42:42:5f:42:ca:a1:2e:58:d2:63:6a:af:42:d5:3d:42\n   export PRIVATE_KEY_LOCATION=/Users/foobar/oci_api_key.pem\n   ```\n\n   \u003e and only if your private key has a passphrase:\n\n   ```shell\n   export PASSPHRASE=4242\n   ```\n   \n## You can now invoke your function!\n\nClone this repository - \n\n`git clone https://github.com/abhirockzz/fn-go-sdk-invoke`\n\nChange to the correct directory where you cloned the example: \n\n`go run src/*.go --compartmentName=\u003ccompartmentName\u003e --appName=\u003cappName\u003e --funcName=\u003cfuncName\u003e --invokePayload=\u003c(optional) invokePayload\u003e`\n\n\u003e Payload is optional. If your function doesn't expect any input parameters, you can omit `--invokePayload` argument\n\ne.g. with payload:\n\n`go run src/*.go --compartmentName=mycompartment --appName=helloworld-app --funcName=helloworld-go --invokePayload={\\\"name\\\":\\\"foobar\\\"}`\n\ne.g. without payload:\n\n`go run src/*.go --compartmentName=mycompartments --appName=helloworld-app --funcName=helloworld-go`\n\n## What if my function needs input in binary form ?\n\nThis example demonstrates how to invoke a boilerplate function which accepts (an optional) string payload (JSON data). But, it is possible to send binary payload as well.\n\nYou can use this Tensorflow based function as an example to explore the possibility of invoking a function using binary content - https://github.com/abhirockzz/fn-hello-tensorflow. This function expects the image data (in binary form) as an input and returns what object that image resembles along with the percentage accuracy\n\nIf you were to deploy the above function and invoke it using Fn CLI, the command would something like this - `cat /home/foo/cat.jpeg | fn invoke fn-tensorflow-app classify`. In this case, the `cat.jpeg` image is being passed as an input to the function. The programmatic (using Go SDK) equivalent of this would look something like the below snippet, where the function invocation request (`functions.InvokeFunctionRequest`) is being built along with the binary input (image file content)\n\n    functionPayload, _ := os.Open(\"/home/foo/cat.jpeg\") //error handling ignored for brevity\n\tdefer functionPayload.Close()\n\tinvokeFunctionReq := functions.InvokeFunctionRequest{FunctionId: functionID, InvokeFunctionBody: functionPayload}\n\nPay attention to the following line `functionPayload, _ := os.Open(\"/home/foo/cat.jpeg\")`. The `InvokeFunctionBody` accepts an `io.ReadCloser` - as a result, it is possible to use `os.File` (or any other compatible type) as a function payload\n\n## Troubleshooting\n\n### If you fail to set the required environment variables like `TENANT_OCID` etc.\n\nYou will see the following error - `panic: Please set the environment variable TENANT_OCID`\n\n### If you do not provide required arguments i.e. compartment name etc.\n\nYou will see the following error - `panic: Please set mandatory flag compartmentName`\n\n### If you provide an invalid value for function name etc.\n\nYou will see something similar to - `panic: Could not find function myfunc in application myapp`\n\n### If you provide an incorrect `TENANT_OCID` or `USER_OCID` or `PUBLIC_KEY_FINGERPRINT`\n\nYou will get this error - `Service error:NotAuthenticated. The required information to complete authentication was not provided or was incorrect.. http status code: 401. Opc request id: 4d7d76463a4f437361a1eb47815015d9/450D86C860C0592949AFF344C6DB17F0/84F3CCC7542175C08646CD4E213A2CEF`\n\n### If your key has a passphrase but you fail to set the environment variable PASSPHRASE or provid an incorrect value\n\nYou will get this error - `panic: Could not instantiate Identity client - can not create client, bad configuration: x509: decryption password incorrect`\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabhirockzz%2Ffn-go-sdk-invoke","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabhirockzz%2Ffn-go-sdk-invoke","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabhirockzz%2Ffn-go-sdk-invoke/lists"}