Thumbnail Sample¶
Thumbnail is a sample that processes an image uploaded to OBS, resizes it to fit within a maximum dimension, and uploads the resized image back to another OBS using FunctionGraph with OBS trigger event.
Source for this sample can be found in: /samples-doc/doc-sample-obs-thumbnail.
Overview¶
Following diagram shows components used in this example:
Deployment¶
This sample can be deployed using Terraform, see Prepare the Terraform environment for setup details.
Terraform deployment scripts can be found in: /samples-doc/doc-sample-obs-thumbnail/src/main/tf
Adapt file variables.tf according to your needs, see comments.
# prefix will be prepended to all resource names
variable "prefix" {
type = string
default = "doc-sample-obs-thumbnail"
}
# FunctionGraph: Function name
variable "function_name" {
type = string
default = "createThumbnails"
}
# FunctionGraph: Handler name
variable "function_handler_name" {
type = string
default = "com.opentelekomcloud.samples.Thumbnail.handleRequest"
}
# FunctionGraph: Initializer name
variable "initializer_handler_name" {
type = string
default = "com.opentelekomcloud.samples.Thumbnail.initializer"
}
# Name of jar file to deploy, generated by 'mvn package' command
# and stored in folder [project_folder]/target
variable "jar_file_name" {
type = string
default = "deployment-jar-with-dependencies.jar"
}
# Resource tag:
variable "tag_app_group" {
type = string
default = "doc-sample-obs-thumbnail"
}
This files contains all resources to be created for this sample.
/main.tf¶########################################################## # This bucket is used to store the function code ########################################################## resource "opentelekomcloud_obs_bucket" "codebucket" { bucket = format("%s-%s", var.prefix, "codebucket") acl = "private" # Warning: force_destroy will delete bucket on # terraform destroy even if it contains objects force_destroy = true tags = { "app_group" = var.tag_app_group } } ########################################################## # This code bucket object stores the function code ########################################################## resource "opentelekomcloud_obs_bucket_object" "code_object" { bucket = opentelekomcloud_obs_bucket.codebucket.bucket key = format("%s/%s", "code", var.jar_file_name) source = format("${path.root}/../../../target/%s", var.jar_file_name) etag = filemd5(format("${path.root}/../../../target/%s", var.jar_file_name)) } ########################################################### # Store md5 of zip file in terraform state file to check # for code changes in lifecycle of # "opentelekomcloud_fgs_function_v2" ########################################################### resource "terraform_data" "replacement" { input = [ filemd5(format("${path.root}/../../../target/%s", var.jar_file_name)) ] } ########################################################### # Custom role to allow FunctionGraph to access LTS and OBS ########################################################### resource "opentelekomcloud_identity_role_v3" "role" { display_name = format("%s-%s-role", var.prefix, var.function_name) description = "Role for FunctionGraph to access OBS" display_layer = "project" statement { effect = "Allow" action = [ "functiongraph:*:*", "lts:*:*", ] } statement { effect = "Allow" action = [ "obs:*:*", ] resource = [ "OBS:*:*:object:*", format("OBS:*:*:bucket:%s", opentelekomcloud_s3_bucket.inbucket.bucket), format("OBS:*:*:bucket:%s", opentelekomcloud_s3_bucket.outbucket.bucket), ] } } ########################################################## # Agency for FunctionGraph # Attention: Crating agency will take some time. # Calls to function after creating agency will fail until # agency is set up. ########################################################## resource "opentelekomcloud_identity_agency_v3" "agency" { depends_on = [opentelekomcloud_identity_role_v3.role] delegated_domain_name = "op_svc_cff" name = format("%s-%s-agency", var.prefix, var.function_name) description = "Agency for FunctionGraph to access OBS" project_role { all_projects = true project = "eu-de" roles = [ opentelekomcloud_identity_role_v3.role.display_name ] } } ########################################################## # Create Function ########################################################## resource "opentelekomcloud_fgs_function_v2" "MyFunction" { depends_on = [opentelekomcloud_obs_bucket_object.code_object] name = format("%s_%s", var.prefix, var.function_name) app = "default" agency = opentelekomcloud_identity_agency_v3.agency.name handler = var.function_handler_name initializer_handler = var.initializer_handler_name initializer_timeout = 30 description = "Sample on how to create Thumbnails from images uploaded to OBS" memory_size = 512 timeout = 30 max_instance_num = 1 enable_class_isolation = true runtime = "Java17" code_type = "obs" code_url = format("https://%s/code/%s", opentelekomcloud_obs_bucket.codebucket.bucket_domain_name, var.jar_file_name) code_filename = var.jar_file_name log_group_id = opentelekomcloud_lts_group_v2.MyLogGroup.id log_group_name = opentelekomcloud_lts_group_v2.MyLogGroup.group_name log_topic_id = opentelekomcloud_lts_stream_v2.MyLogStream.id log_topic_name = opentelekomcloud_lts_stream_v2.MyLogStream.stream_name # set some environment variables user_data = jsonencode({ "OUTPUT_BUCKET" : opentelekomcloud_s3_bucket.outbucket.bucket, # "RUNTIME_LOG_LEVEL" : "ERROR", # "RUNTIME_LOG_PATH" : "/tmp" }) tags = { "app_group" = var.tag_app_group } lifecycle { # replace if code in bucket changed replace_triggered_by = [ terraform_data.replacement ] } } ########################################################## # Create Log Group ########################################################## resource "opentelekomcloud_lts_group_v2" "MyLogGroup" { group_name = format("%s_%s_%s", var.prefix, var.function_name, "log_group") ttl_in_days = 1 tags = { "app_group" = var.tag_app_group } } ########################################################## # Create Log Stream ########################################################## resource "opentelekomcloud_lts_stream_v2" "MyLogStream" { group_id = opentelekomcloud_lts_group_v2.MyLogGroup.id stream_name = format("%s_%s_%s", var.prefix, var.function_name, "log_stream") tags = { "app_group" = var.tag_app_group } } ########################################################## # Input bucket for source images ########################################################## resource "opentelekomcloud_s3_bucket" "inbucket" { bucket = lower(format("%s-%s-%s", var.prefix, var.function_name, "images")) acl = "private" # Warning: force_destroy will delete bucket on # terraform destroy even if it contains objects force_destroy = true tags = { "app_group" = var.tag_app_group } } ########################################################## # Output bucket for thumbnail images # For output a different bucket is used to avoid potential # risk of recursive invocation of FunctionGraph ########################################################## resource "opentelekomcloud_s3_bucket" "outbucket" { bucket = lower(format("%s-%s-%s", var.prefix, var.function_name, "images-output")) acl = "private" # Warning: force_destroy will delete bucket on # terraform destroy even if it contains objects force_destroy = true tags = { "app_group" = var.tag_app_group } } ########################################################## # Create OBS Trigger listening for "ObjectCreate" in # input bucket ########################################################## resource "opentelekomcloud_fgs_trigger_v2" "obstrigger" { function_urn = opentelekomcloud_fgs_function_v2.MyFunction.urn type = "OBS" event_data = jsonencode({ "bucket" : opentelekomcloud_s3_bucket.inbucket.bucket "events" : [ "s3:ObjectCreated:*" ] "name" : lower(format("%s-%s-%s", var.prefix, var.function_name, "event")) }) }
This file contains the terraform provider configuration.
Adapt it according to Prepare the Terraform environment
Note
Check especially the backend “s3” configuration for bucket and key.
# ----------------------------------------------------------------------------
# Secret variables to be injected as envvar (capital letters for Windows systems)
# - no defaults
# - Declared as sensitive --> Not printed in console or log if used in resources
# ----------------------------------------------------------------------------
# set by environment variable TF_VAR_OTC_SDK_AK
variable "OTC_SDK_AK" {
description = "Personal access key"
type = string
sensitive = true
}
# set by environment variable TF_VAR_OTC_SDK_SK
variable "OTC_SDK_SK" {
description = "Personal secret key"
type = string
sensitive = true
}
# set by environment variable TF_VAR_OTC_SDK_DOMAIN_NAME
variable "OTC_SDK_DOMAIN_NAME" {
description = "Domain Name, eg. OTC-EU-DE-000000000010000XXXXX"
type = string
}
# set by environment variable TF_VAR_OTC_SDK_PROJECTID
variable "OTC_SDK_PROJECTID" {
description = "Project Id"
type = string
}
# set by environment variable TF_VAR_OTC_SDK_PROJECTNAME
variable "OTC_SDK_PROJECTNAME" {
description = "Project Name, eg. eu-de_MYPROJECT"
type = string
}
terraform {
required_providers {
# specifies required provider, source and version
# see https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest
opentelekomcloud = {
source = "opentelekomcloud/opentelekomcloud"
version = ">= 1.36.47"
}
}
backend "s3" {
# See: https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs/guides/backends
# (Required) Specifies the endpoint for OpenTelekomCloud OBS.
# The value is https://obs.{{region}}.otc.t-systems.com.
# This can also be sourced from the AWS_S3_ENDPOINT environment variable
endpoints = {
s3 = "https://obs.eu-de.otc.t-systems.com"
}
# (Required) Specifies the bucket name where to store the state.
# Make sure to create it before.
bucket = "sample-tf-backend"
# (Required) Specifies the path to the state file inside the bucket.
key = "terraform_state/doc-sample-obs-thumbnail.tf"
# (Required) Specifies the region where the bucket is located.
# This can also be sourced from the AWS_DEFAULT_REGION and
# AWS_REGION environment variables.
region = "eu-de"
# (Required) Skip credentials validation via the STS API.
# It's mandatory for OpenTelekomClou.
skip_credentials_validation = true
# (Required) Skip validation of provided region name.
# It's mandatory for OpenTelekomCloud.
skip_region_validation = true
skip_requesting_account_id = true
# (Required) Skip usage of EC2 Metadata API.
# It's mandatory for OpenTelekomCloud.
skip_metadata_api_check = true
# (Optional) Do not include checksum when uploading S3 Objects.
# Useful for some S3-Compatible APIs.
skip_s3_checksum = true
# Although the terraform block does not accept variables or locals and
# all backend configuration values must be hardcoded, you can provide
# the credentials via the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
# environment variables to access OBS, respectively:
#
# export AWS_ACCESS_KEY_ID="your accesskey"
# export AWS_SECRET_ACCESS_KEY="your secretkey"
#
# secret_key set env var: AWS_ACCESS_KEY_ID
# access_key set env var: AWS_SECRET_ACCESS_KEY
}
}
# ----------------------------------------------------------------------------
# Providers settings --> OTC
# We use the AKSK auth scheme
# See https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs
# ----------------------------------------------------------------------------
#
provider "opentelekomcloud" {
auth_url = "https://iam.eu-de.otc.t-systems.com/v3"
access_key = var.OTC_SDK_AK
secret_key = var.OTC_SDK_SK
domain_name = var.OTC_SDK_DOMAIN_NAME
tenant_name = var.OTC_SDK_PROJECTNAME
}
To deploy use:
terraform apply --auto-approve
References¶
In this sample the huaweicloud-sdk-java-obs is used to access OBS with following dependency added to the pom.xml:
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java</artifactId>
<version>3.25.5</version>
</dependency>
Documentation on the huaweicloud-sdk-java-obs can be found here: API Overview (SDK for Java)
Upload image file to source bucket¶
Linux/Ubuntu¶
Note
For s3cmd tool installation see: S3cmd on github.
To upload image to source bucket, following script an be used for Ubuntu users:
# https://github.com/opentelekomcloud/obs-s3/blob/master/s3cmd/README.md
s3cmd --access_key=${OTC_SDK_AK} --secret_key=${OTC_SDK_SK} --no-ssl \
put ./src/test/resources/otc.jpg \
s3://doc-sample-obs-thumbnail-createthumbnails-images/otc.jpg
Microsoft Windows¶
Note
For Microsoft Windows, see OBS Browser+
Alternatives (unsupported)¶
Huawei obsutil¶
Note
Huawei obsutil is available for Windows, Linux and Mac from Huawei, see: obsutil Introduction
REM ########################################################################
REM Sample to upload picture to obs bucket using Huawei obsutil.
REM Huawei obsutil is available, see:
REM https://support.huaweicloud.com/intl/en-us/utiltg-obs/obs_11_0001.html
REM ########################################################################
REM for proxy use, set following environment variables
REM set HTTP_PROXY=proxy:port
REM set HTTPS_PROXY=proxy:port
obsutil.exe cp .\src\test\resources\otc.jpg ^
obs://doc-sample-obs-thumbnail-createthumbnails-images/otc.jpg ^
-e=https://obs.eu-de.otc.t-systems.com ^
-i=%ACCESS_KEY% ^
-k=%SECRET_ACCESS_KEY%