All Products
Search
Document Center

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

Last Updated:Mar 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.

  • Object Storage Service (OSS) SDK for Java 3.17.2 or later is installed and configured.

  • OSS SDK for Python 2.18.3 or later is installed and configured.

Procedure

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

    Example 1: Process GetObject requests by using a transformed image

    Java

    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. 
                // After that, 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

    # -*- 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. 
        # After that, 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'

    Example 2: Process GetObject requests by using compressed content

    Java

    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.OSSObject;
    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 java.io.*;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;
    
    public class Example2 implements StreamRequestHandler {
        // In this example, the endpoint of the China (Qingdao) region is used. 
        String endpoint = "https://oss-cn-qingdao.aliyuncs.com";
        // Specify the name of the object. 
        String fileName = "examplefile.txt";
        // Specify the path of the ZIP package that is temporarily generated on your local device. 
        String path = "test.zip";
        private static int status = 200;
    
        public static String convertToString(InputStream inputStream) {
            Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
            return scanner.hasNext() ? scanner.next() : "";
        }
    
        public static void convertToZip(InputStream inputStream, String fileName, String path) throws IOException {
            FileOutputStream fos = new FileOutputStream(path);
            ZipOutputStream zipOut = new ZipOutputStream(fos);
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOut.putNextEntry(zipEntry);
    
            byte[] bytes = new byte[1024];
            int length;
            while((length = inputStream.read(bytes)) >= 0) {
                zipOut.write(bytes, 0, length);
            }
    
            zipOut.close();
            inputStream.close();
            fos.close();
        }
    
        @Override
        public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
            Credentials creds = context.getExecutionCredentials();
            // Obtain the AccessKey pair from the context. 
            System.out.println("getAccessKeyId: "+creds.getAccessKeyId());
            System.out.println("getAccessKeySecret: "+creds.getAccessKeySecret());
            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");
                String inputOssUrl = jsonObject.getJSONObject("getObjectContext").getString("inputOssUrl");
    
                System.out.println("jsonObject:"+jsonObject);
                System.out.println("inputOssUrl: "+inputOssUrl);
    
                Map<String, String> customHeaders = new HashMap<String, String>();
                URL signedUrl = new URL(inputOssUrl);
                OSSObject ossObject = ossClient.getObject(signedUrl, customHeaders);
                System.out.println("getObject StatusCode: "+ossObject.getResponse().getStatusCode());
    
                // Compress the object obtained by using the signed URL and upload it. 
                convertToZip(ossObject.getObjectContent(), fileName, path);
                File file = new File(path);
                FileInputStream fis = new FileInputStream(file);
    
                WriteGetObjectResponseRequest writeGetObjectResponseRequest = new WriteGetObjectResponseRequest(route, token, status, fis);
    
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentLength(file.length());
                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());
                // Delete the ZIP package that is temporarily generated. 
                file.delete();
            } 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

    # -*- coding: utf-8 -*-
    import os
    import oss2
    import json
    import gzip
    import requests
    # In this example, the endpoint of the China (Qingdao) region is used. 
    endpoint = 'http://oss-cn-qingdao.aliyuncs.com'
    fwd_status = '200'
    
    # Specify the name of the object. 
    fileName = "examplefile.txt"
    # Specify the path of the ZIP package that is temporarily generated on your local device. 
    path = 'test.zip'
    
    def handler(event, context):
    
        evt = json.loads(event)
        creds = context.credentials
        # Obtain the AccessKey pair from the context. 
        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"]
        inputOssUrl = event_ctx["inputOssUrl"]
        print(evt)
    
        endpoint = route   
        resp = requests.get(inputOssUrl)
    
        # Compress the object obtained by using the signed URL and upload it. 
        g = gzip.GzipFile(filename=fileName, mode="wb", compresslevel=9, fileobj=open(path, 'wb'))
        g.write(resp.content)
        g.close()
    
        service = oss2.Service(auth, endpoint)
        with open(path, 'rb') as fileobj:
            resp = service.write_get_object_response(route, token, fwd_status, fileobj, headers)
            print('status: {0}'.format(resp.status))
            print(resp.headers)
    
        # Delete the ZIP package that is temporarily generated. 
        os.remove(path)
        return 'success'
  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, such as 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.

What to do next

Use Object FC Access Points