All Products
Search
Document Center

Object Storage Service:Compile a function that is used to process GetObject requests

Last Updated:Aug 27, 2024

When you use an Object FC Access Point to call the GetObject operation, the bound function in Function Compute is triggered. You can call the WriteGetObjectResponse operation in the function to return only custom data and response headers.

Prerequisites

An Object FC Access Point is created. For more information, see Create Object FC Access Points.

Procedure

  1. Compile a function that is used to process GetObject requests.

    Java

    The version of OSS SDK for Java must be 3.17.2 or later.

    import com.aliyun.fc.runtime.Context;
    import com.aliyun.fc.runtime.Credentials;
    import com.aliyun.fc.runtime.StreamRequestHandler;
    import com.aliyun.oss.ClientException;
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.OSSException;
    import com.aliyun.oss.model.ObjectMetadata;
    import com.aliyun.oss.model.VoidResult;
    import com.aliyun.oss.model.WriteGetObjectResponseRequest;
    import org.codehaus.jettison.json.JSONException;
    import org.codehaus.jettison.json.JSONObject;
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.Scanner;
    
    public class Example1 implements StreamRequestHandler {
        // In this example, the endpoint of the China (Qingdao) region is used. 
        String endpoint = "https://oss-cn-qingdao.aliyuncs.com";
        private static int status = 200;
    
        public static String convertToString(InputStream inputStream) {
            Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
            return scanner.hasNext() ?  scanner.next() : "";
        }
    
        @Override
        public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
            Credentials creds = context.getExecutionCredentials();
            // Obtain the AccessKey pair from the context. 
            OSS ossClient = new OSSClientBuilder().build(endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken());
    
    
            try {
                String result = convertToString(inputStream);
                JSONObject jsonObject = new JSONObject(result);
                String route = jsonObject.getJSONObject("getObjectContext").getString("outputRoute");
                String token = jsonObject.getJSONObject("getObjectContext").getString("outputToken");
                // Call BufferedImage to create an image object that has a resolution of 200 × 200 pixels and draw a red rectangle for the object. 
                // Write content to the body of the WriteGetObjectResponse request. 
                BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics = image.createGraphics();
                graphics.setColor(Color.RED);
                graphics.fillRect(0, 0, 200, 200);
                graphics.dispose();
    
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageIO.write(image, "png", baos);
                WriteGetObjectResponseRequest writeGetObjectResponseRequest = new WriteGetObjectResponseRequest(route, token, status,new ByteArrayInputStream(baos.toByteArray()));
    
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentLength(baos.size());
                writeGetObjectResponseRequest.setMetadata(metadata);
    
                VoidResult voidResult = ossClient.writeGetObjectResponse(writeGetObjectResponseRequest);
                System.out.println("getRequestId:"+voidResult.getRequestId());
                System.out.println("status:"+voidResult.getResponse().getStatusCode());
                System.out.println("Headers:"+voidResult.getResponse().getHeaders().toString());
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message: " + oe.getMessage());
                System.out.println("Error Code:       " + oe.getErrorCode());
                System.out.println("Request ID:      " + oe.getRequestId());
                System.out.println("Host ID:           " + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("Caught an ClientException, which means the client encountered "
                        + "a serious internal problem while trying to communicate with OSS, "
                        + "such as not being able to access the network.");
                System.out.println("Error Message: " + ce.getMessage());
            } catch (JSONException e) {
                e.printStackTrace();
            } finally {
                ossClient.shutdown();
            }
        }
    }
    

    Python

    The version of OSS SDK for Python must be 2.18.3 or later.

    # -*- coding: utf-8 -*-
    import io
    from PIL import Image
    import oss2
    import json
    
    # In this example, the endpoint of the China (Qingdao) region is used. 
    endpoint = 'http://oss-cn-qingdao.aliyuncs.com'
    fwd_status = '200'
    
    # Fc function entry
    def handler(event, context):
    
        evt = json.loads(event)
        creds = context.credentials
        # do not forget security_token
        auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
    
        headers = dict()    
    
        event_ctx = evt["getObjectContext"]
        route = event_ctx["outputRoute"]
        token = event_ctx["outputToken"]
        print(evt)
    
        endpoint = route
        service = oss2.Service(auth, endpoint)
        # Call Image to create an image object that has a resolution of 200 × 200 pixels and draw a red rectangle for the object. 
        # Write content to the body of the write_get_object_response request. 
        image = Image.new('RGB', (200, 200), color=(255, 0, 0))
        transformed = io.BytesIO()
        image.save(transformed, "png")
    
        resp = service.write_get_object_response(route, token, fwd_status, transformed.getvalue(), headers)
    
        print('status: {0}'.format(resp.status))
        print(resp.headers)
    
        return 'success'

    Go

    The version of OSS SDK for Go must be 1.2.2 or later.

    package main
    
    import (
      "bytes"
      "context"
      "fmt"
      "github.com/aliyun/aliyun-oss-go-sdk/oss"
      "github.com/aliyun/fc-runtime-go-sdk/fc"
      "github.com/aliyun/fc-runtime-go-sdk/fccontext"
      "image"
      "image/color"
      "image/draw"
      "image/png"
    )
    // Specify the GetObjectContext structure, which contains the output route (outputRoute), output token (outputToken), and input OSS URL(inputOssUrl). 
    type GetObjectContext struct {
      OutputRoute string `json:"outputRoute"`
      OutputToken string `json:"outputToken"`
    }
    // Specify the StructEvent structure to receive the event data that triggers the function. 
    type StructEvent struct {
      GetObjectContext GetObjectContext `json:"getObjectContext"`
    }
    // Specify the HandleRequest function to process computing logic. 
    func HandleRequest(ctx context.Context, event StructEvent) error {
      fmt.Printf("event:%#v\n", event)
      endpoint := event.GetObjectContext.OutputRoute
      fwdStatus := "200"
      fctx, _ := fccontext.FromContext(ctx)
      // Obtain the AccessKey pair from the context. 
      client, err := oss.New(endpoint, fctx.Credentials.AccessKeyId, fctx.Credentials.AccessKeySecret, oss.SecurityToken(fctx.Credentials.SecurityToken), oss.AuthVersion(oss.AuthV4), oss.Region("cn-qingdao"))
      if err != nil {
        return fmt.Errorf("client new error: %v", err)
      }
      params := map[string]interface{}{}
      params["x-oss-write-get-object-response"] = nil
    
      // Create an image object that has a resolution of 200 × 200 pixels and draw a red rectangle for the object. 
      img := image.NewRGBA(image.Rect(0, 0, 200, 200))
      red := color.RGBA{255, 0, 0, 255}
      draw.Draw(img, img.Bounds(), &image.Uniform{red}, image.Point{}, draw.Src)
    
      // Save the image in the PNG format. 
      var buf bytes.Buffer
      err = png.Encode(&buf, img)
      if err != nil {
        return fmt.Errorf("png encode error: %v", err)
      }
      reader := bytes.NewReader(buf.Bytes())
      // Use the OSS client to upload the converted image by sending a POST request, and specify specific HTTP headers, such as x-oss-request-route, to facilitate the identification and processing of special forwarding requests. 
      headers := make(map[string]string)
      headers["x-oss-request-route"] = event.GetObjectContext.OutputRoute
      headers["x-oss-request-token"] = event.GetObjectContext.OutputToken
      headers["x-oss-fwd-status"] = fwdStatus
      resp, err := client.Conn.Do("POST", "", "", params, headers, reader, 0, nil)
      if err != nil {
        return fmt.Errorf("client conn do error: %v", err)
      }
      fmt.Println("status:", resp.StatusCode)
      fmt.Println(resp.Headers)
    
      return nil
    }
    // Call fc.Start(HandleRequest) to register and run the HandleRequest function and wait for and process the event triggers of Alibaba Cloud Function Compute. 
    func main() {
      fc.Start(HandleRequest)
    }
  2. Deploy the function.

    Java

    1. Decompress the .jar file.

    2. Upload the .jar file to the Function Compute console.

      1. Log on to the Function Compute console. Click Back to Function Compute 2.0 in the upper-right corner.

      2. In the left-side navigation pane, click Services & Functions.

      3. In the top navigation bar, select China (Qingdao).

      4. On the Services page, click the service that you created and then click the function whose runtime is Java 11.

      5. On the function details page, choose Upload Code > Upload JAR Package.

      6. In the dialog box that appears, select the .jar file, select Deploy the function after the files are selected., and then click Save and Deploy.

    3. Modify the function handler based on the sample function.

      1. On the function details page, click the Configurations tab.

      2. In the Environment Information section, click Edit.

      3. Modify the value of the Handler parameter.

        If the runtime is Java, the current value is in the [package].[class]::[method] format. If the current value is example.HelloFC::handleRequest, the handleRequest function of the HelloFC class in the example package is invoked. You need to modify the current value based on the actual sample function. Example: com.aliyun.sts.sample.Example1::handleRequest.

    Python

    1. On the Services page, click the service that you created, and then click the function whose runtime is Python 3.10.

    2. On the function details page, click the Code tab and choose Terminal > New Terminal.

    3. In the TERMINAL panel, run the following command to update the version of OSS SDK for Python:

      pip install oss2 -t .
    4. Replace the sample code in index.py with the sample Python function code that is used to process GetObject requests. Then, click Deploy.

    Go

    1. Install the OSS SDK for Go runtime environment.

    2. Compile the code package. For more information, see Compile and package code on Linux or macOS.

      During compilation, replace the main.go compilation file with the sample function that is used to process GetObject requests provided in the preceding step.

    3. Upload the compiled binary file as a ZIP package to the created function in the Go 1 runtime environment, and configure a handler for the function. For more information, see Configure Function Compute handlers.

What to do next

Use Object FC Access Points