|
| 1 | +# Function that returns the HTTP request information when called through API Gateway |
| 2 | +This function returns the HTTP request information when called through API Gateway. |
| 3 | + |
| 4 | +As you make your way through this tutorial, look out for this icon . |
| 5 | +Whenever you see it, it's time for you to perform an action. |
| 6 | + |
| 7 | + |
| 8 | +## Prerequisites |
| 9 | +Before you deploy this sample function, make sure you have run step A, B and C of the [Oracle Functions Quick Start Guide for Cloud Shell](https://www.oracle.com/webfolder/technetwork/tutorials/infographics/oci_functions_cloudshell_quickview/functions_quickview_top/functions_quickview/index.html) |
| 10 | +* A - Set up your tenancy |
| 11 | +* B - Create application |
| 12 | +* C - Set up your Cloud Shell dev environment |
| 13 | + |
| 14 | + |
| 15 | +## List Applications |
| 16 | +Assuming your have successfully completed the prerequisites, you should see your |
| 17 | +application in the list of applications. |
| 18 | +``` |
| 19 | +fn ls apps |
| 20 | +``` |
| 21 | + |
| 22 | + |
| 23 | +## Review and customize the function |
| 24 | +Review the following files in the current folder: |
| 25 | +* the code of the function, [func.py](./func.py) |
| 26 | +* its dependencies, [requirements.txt](./requirements.txt) |
| 27 | +* the function metadata, [func.yaml](./func.yaml) |
| 28 | + |
| 29 | + |
| 30 | +## Deploy the function |
| 31 | +In Cloud Shell, run the *fn deploy* command to build the function and its dependencies as a Docker image, |
| 32 | +push the image to OCIR, and deploy the function to Oracle Functions in your application. |
| 33 | + |
| 34 | + |
| 35 | +``` |
| 36 | +fn -v deploy --app <app-name> |
| 37 | +``` |
| 38 | + |
| 39 | + |
| 40 | +## Create the API Gateway |
| 41 | +The functions is meant to be invoked through API Gateway. |
| 42 | + |
| 43 | + |
| 44 | + |
| 45 | +On the OCI console, navigate to *Developer Services* > *API Gateway*. Click on *Create Gateway*. Provide a name, set the type to "Public", select a compartment, a VCN, a public subnet, and click *Create*. |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +Once created, click on your gateway. Under *Resources*, select *Deployments* and click *Create Deployment*. Provide a name, a path prefix ("/v1" for example), click *Next*. Provide a name to the route ("/display-httprequest-info" for example), select methods "GET" and "POST", select type "Oracle Functions", select the Application for your function, and select your function you deployed in the previous step. |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | +Click *Next* and finally, click *Save Changes*. |
| 54 | + |
| 55 | +Note the endpoint of your API Gateway deployment. |
| 56 | + |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | +## Create or Update your Dynamic Group for API Gateway |
| 61 | +In order to invoke functions, your API Gateway must be part of a dynamic group. |
| 62 | + |
| 63 | +When specifying the *Matching Rules*, we suggest matching all functions in a compartment with: |
| 64 | +``` |
| 65 | +ALL {resource.type = 'ApiGateway', resource.compartment.id = 'ocid1.compartment.oc1..aaaaaxxxxx'} |
| 66 | +``` |
| 67 | + |
| 68 | + |
| 69 | +## Create or Update IAM Policies for API Gateway |
| 70 | +Create a new policy that allows the API Gateway dynamic group to invoke functions. We will grant `use` access to `functions-family` in the compartment. |
| 71 | + |
| 72 | + |
| 73 | + |
| 74 | +Your policy should look something like this: |
| 75 | +``` |
| 76 | +Allow dynamic-group <dynamic-group-name> to use functions-family in compartment <compartment-name> |
| 77 | +``` |
| 78 | + |
| 79 | +For more information on how to create policies, check the [documentation](https://docs.cloud.oracle.com/iaas/Content/Identity/Concepts/policysyntax.htm). |
| 80 | + |
| 81 | + |
| 82 | +## Set the function configuration values |
| 83 | +The function returns the configuration values you set. |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +Use the *fn CLI* to set the config value: |
| 88 | +``` |
| 89 | +fn config function <app-name> <function-name> <configkey> <configvalue> |
| 90 | +``` |
| 91 | +e.g. |
| 92 | +``` |
| 93 | +fn config function myapp oci-apigw-display-httprequest-info-python configkey1 "value1" |
| 94 | +``` |
| 95 | + |
| 96 | + |
| 97 | +## Invoke the function |
| 98 | +The function returns the information of the HTTP request through API Gateway. |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +Set the Environment variable "APIGW_ENDPOINT" to the value of the endpoint of your API Gateway deployment, e.g. |
| 103 | +``` |
| 104 | +export APIGW_ENDPOINT=https://xxxxx.apigateway.us-phoenix-1.oci.customer-oci.com/v1 |
| 105 | +``` |
| 106 | + |
| 107 | +Use the curl command to make the HTTP request. You can optionally specify a request header just to see it returned by the function. You may want to pipe the curl command to `jq` to get a nicer output. |
| 108 | +``` |
| 109 | +curl --header "X-MyHeader1: headerValue" $APIGW_ENDPOINT/display-httprequest-info | jq . |
| 110 | +``` |
| 111 | + |
| 112 | +Upon success, curl should return something similar to: |
| 113 | +``` |
| 114 | +{ |
| 115 | + "Headers": { |
| 116 | + "host": [ |
| 117 | + "localhost", |
| 118 | + "xxxxx.apigateway.us-phoenix-1.oci.customer-oci.com" |
| 119 | + ], |
| 120 | + "user-agent": [ |
| 121 | + "lua-resty-http/0.14 (Lua) ngx_lua/10015", |
| 122 | + "curl/7.64.1" |
| 123 | + ], |
| 124 | + "transfer-encoding": "chunked", |
| 125 | + "content-type": [ |
| 126 | + "application/octet-stream", |
| 127 | + "application/octet-stream" |
| 128 | + ], |
| 129 | + "date": "Tue, 23 Jun 2020 01:09:41 GMT", |
| 130 | + "fn-call-id": "xxxxxxxxx", |
| 131 | + "fn-deadline": "2020-06-23T01:10:21Z", |
| 132 | + "accept": "*/*", |
| 133 | + "forwarded": "for=x.x.x.x", |
| 134 | + "x-forwarded-for": "x.x.x.x", |
| 135 | + "x-myheader1": "headerValue", |
| 136 | + "x-real-ip": "x.x.x.x", |
| 137 | + "fn-http-method": "GET", |
| 138 | + "fn-http-request-url": "/v1/display-httprequest-info", |
| 139 | + "fn-intent": "httprequest", |
| 140 | + "fn-invoke-type": "sync", |
| 141 | + "oci-subject-id": "ocid1.apigateway.oc1.phx.xxxxx", |
| 142 | + "oci-subject-tenancy-id": "ocid1.tenancy.oc1..xxxxx", |
| 143 | + "oci-subject-type": "resource", |
| 144 | + "opc-request-id": "xxxxxxxxx", |
| 145 | + "x-content-sha256": "xxxxxxxxx", |
| 146 | + "accept-encoding": "gzip" |
| 147 | + }, |
| 148 | + "Configuration": { |
| 149 | + "PATH": "/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| 150 | + "HOSTNAME": "xxxxxxxxx", |
| 151 | + "FN_FN_ID": "ocid1.fnfunc.oc1.phx.xxxxx", |
| 152 | + "FN_MEMORY": "256", |
| 153 | + "FN_TYPE": "sync", |
| 154 | + "configkey1": "value1", |
| 155 | + "FN_LISTENER": "unix:/tmp/iofs/lsnr.sock", |
| 156 | + "FN_FORMAT": "http-stream", |
| 157 | + "FN_APP_ID": "ocid1.fnapp.oc1.phx.xxxxx", |
| 158 | + "FN_CPUS": "100m", |
| 159 | + "OCI_RESOURCE_PRINCIPAL_RPST": "/.oci-credentials/rpst", |
| 160 | + "OCI_RESOURCE_PRINCIPAL_PRIVATE_PEM": "/.oci-credentials/private.pem", |
| 161 | + "OCI_RESOURCE_PRINCIPAL_VERSION": "2.2", |
| 162 | + "OCI_RESOURCE_PRINCIPAL_REGION": "us-phoenix-1", |
| 163 | + "OCI_REGION_METADATA": "{\"realmDomainComponent\":\"oraclecloud.com\",\"realmKey\":\"ocX\",\"regionIdentifier\":\"xx-xxxxx-x\",\"regionKey\":\"XXX\"}", |
| 164 | + "LANG": "C.UTF-8", |
| 165 | + "GPG_KEY": "xxxxxxxxx", |
| 166 | + "PYTHON_VERSION": "3.6.10", |
| 167 | + "PYTHON_PIP_VERSION": "20.1.1", |
| 168 | + "PYTHON_GET_PIP_URL": "https://github.com/pypa/get-pip/raw/eff16c878c7fd6b688b9b4c4267695cf1a0bf01b/get-pip.py", |
| 169 | + "PYTHON_GET_PIP_SHA256": "xxxxxxxxx", |
| 170 | + "PYTHONPATH": "/function:/python", |
| 171 | + "HOME": "/home/fn" |
| 172 | + }, |
| 173 | + "Request body": {}, |
| 174 | + "Request URL": "/v1/display-httprequest-info", |
| 175 | + "Query String": {}, |
| 176 | + "Request Method": "GET", |
| 177 | + "AppID": "ocid1.fnapp.oc1.phx.xxxxx", |
| 178 | + "FnID": "ocid1.fnfunc.oc1.phx.xxxxx", |
| 179 | + "CallID": "xxxxxxxxx", |
| 180 | + "Format": "http-stream", |
| 181 | + "Deadline": "2020-06-23T01:10:21Z" |
| 182 | +} |
| 183 | +``` |
| 184 | + |
| 185 | +Now, use the "POST" method so you can specify a request payload, and specify some query string parameters: |
| 186 | +``` |
| 187 | +curl -X POST --header "X-MyHeader1: headerValue" -d '{"key1":"value"}' "$APIGW_ENDPOINT/display-httprequest-info?key1=value1&key2=value2" | jq . |
| 188 | +``` |
| 189 | + |
| 190 | +Upon success, curl should return something similar to: |
| 191 | +``` |
| 192 | +{ |
| 193 | + "Headers": { |
| 194 | + "host": [ |
| 195 | + "localhost", |
| 196 | + "xxxxx.apigateway.us-phoenix-1.oci.customer-oci.com" |
| 197 | + ], |
| 198 | + "user-agent": [ |
| 199 | + "lua-resty-http/0.14 (Lua) ngx_lua/10015", |
| 200 | + "curl/7.64.1" |
| 201 | + ], |
| 202 | + "transfer-encoding": "chunked", |
| 203 | + "content-type": [ |
| 204 | + "application/x-www-form-urlencoded", |
| 205 | + "application/x-www-form-urlencoded" |
| 206 | + ], |
| 207 | + "date": "Tue, 23 Jun 2020 17:58:40 GMT", |
| 208 | + "fn-call-id": "xxxxxxxxx", |
| 209 | + "fn-deadline": "2020-06-23T17:59:10Z", |
| 210 | + "accept": "*/*", |
| 211 | + "content-length": "16", |
| 212 | + "forwarded": "for=x.x.x.x", |
| 213 | + "x-forwarded-for": "x.x.x.x", |
| 214 | + "x-myheader1": "headerValue", |
| 215 | + "x-real-ip": "x.x.x.x", |
| 216 | + "fn-http-method": "POST", |
| 217 | + "fn-http-request-url": "/v1/display-httprequest-info?key1=value1&key2=value2", |
| 218 | + "fn-intent": "httprequest", |
| 219 | + "fn-invoke-type": "sync", |
| 220 | + "oci-subject-id": "ocid1.apigateway.oc1.phx.xxxxx", |
| 221 | + "oci-subject-tenancy-id": "ocid1.tenancy.oc1..xxxxx", |
| 222 | + "oci-subject-type": "resource", |
| 223 | + "opc-request-id": "xxxxxxxxx", |
| 224 | + "x-content-sha256": "xxxxxxxxx", |
| 225 | + "accept-encoding": "gzip" |
| 226 | + }, |
| 227 | + "Configuration": { |
| 228 | + "PATH": "/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| 229 | + "HOSTNAME": "xxxxxxxxx", |
| 230 | + "FN_LISTENER": "unix:/tmp/iofs/lsnr.sock", |
| 231 | + "FN_FORMAT": "http-stream", |
| 232 | + "FN_APP_ID": "ocid1.fnapp.oc1.phx.xxxxx", |
| 233 | + "FN_CPUS": "100m", |
| 234 | + "FN_FN_ID": "ocid1.fnfunc.oc1.phx.xxxxx", |
| 235 | + "FN_MEMORY": "256", |
| 236 | + "FN_TYPE": "sync", |
| 237 | + "configkey1": "value1", |
| 238 | + "OCI_RESOURCE_PRINCIPAL_RPST": "/.oci-credentials/rpst", |
| 239 | + "OCI_RESOURCE_PRINCIPAL_PRIVATE_PEM": "/.oci-credentials/private.pem", |
| 240 | + "OCI_RESOURCE_PRINCIPAL_VERSION": "2.2", |
| 241 | + "OCI_RESOURCE_PRINCIPAL_REGION": "us-phoenix-1", |
| 242 | + "OCI_REGION_METADATA": "{\"realmDomainComponent\":\"oraclecloud.com\",\"realmKey\":\"ocX\",\"regionIdentifier\":\"xx-xxxxx-x\",\"regionKey\":\"XXX\"}", |
| 243 | + "LANG": "C.UTF-8", |
| 244 | + "GPG_KEY": "xxxxxxxxx", |
| 245 | + "PYTHON_VERSION": "3.6.10", |
| 246 | + "PYTHON_PIP_VERSION": "20.1.1", |
| 247 | + "PYTHON_GET_PIP_URL": "https://github.com/pypa/get-pip/raw/eff16c878c7fd6b688b9b4c4267695cf1a0bf01b/get-pip.py", |
| 248 | + "PYTHON_GET_PIP_SHA256": "xxxxxxxxx", |
| 249 | + "PYTHONPATH": "/function:/python", |
| 250 | + "HOME": "/home/fn" |
| 251 | + }, |
| 252 | + "Request body": { |
| 253 | + "key1": "value" |
| 254 | + }, |
| 255 | + "Request URL": "/v1/display-httprequest-info?key1=value1&key2=value2", |
| 256 | + "Query String": { |
| 257 | + "key1": [ |
| 258 | + "value1" |
| 259 | + ], |
| 260 | + "key2": [ |
| 261 | + "value2" |
| 262 | + ] |
| 263 | + }, |
| 264 | + "Request Method": "POST", |
| 265 | + "AppID": "ocid1.fnapp.oc1.phx.xxxxx", |
| 266 | + "FnID": "ocid1.fnfunc.oc1.phx.xxxxx", |
| 267 | + "CallID": "xxxxxxxxx", |
| 268 | + "Format": "http-stream", |
| 269 | + "Deadline": "2020-06-23T17:59:10Z" |
| 270 | +} |
| 271 | +``` |
0 commit comments