在开始开发自定义应用程序之前:
确保在本地安装Adobe I/O CLI。
要创建自定义应用程序,请创建Firefly应用程序。 为此,请在终端中执行aio app init <app-name>
。
如果您尚未登录,此命令将提示浏览器要求您使用Adobe ID登录到Adobe开发人员控制台。 有关从cli登录的详细信息,请参阅此处。
Adobe建议您登录。 如果您遇到问题,请按照说明创建应用程序,而无需登录。
登录后,按照CLI中的提示操作,选择Organization
、Project
和Workspace
以用于应用程序。 选择在设置环境时创建的项目和工作区。
$ aio app init <app-name>
Retrieving information from Adobe I/O Console.
? Select Org My Adobe Org
? Select Project MyFireflyProject
? Select Workspace myworkspace
create console.json
出现Which Adobe I/O App features do you want to enable for this project?
提示时,选择Actions
。 请确保取消选择Web Assets
选项,因为Web资产使用不同的身份验证和授权检查。
? Which Adobe I/O App features do you want to enable for this project?
select components to include (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Actions: Deploy Runtime actions
◯ Events: Publish to Adobe I/O Events
◯ Web Assets: Deploy hosted static assets
◯ CI/CD: Include GitHub Actions based workflows for Build, Test and Deploy
出现提示Which type of sample actions do you want to create?
时,请确保选择Adobe Asset Compute Worker
:
? Which type of sample actions do you want to create?
Select type of actions to generate
❯◉ Adobe Asset Compute Worker
◯ Generic
按照其余提示操作,在Visual Studio代码(或您喜爱的代码编辑器)中打开新应用程序。 它包含自定义应用程序的基架和示例代码。
请在此处阅读有关Firefly应用程序🔗的主要组件。
模板应用程序利用我们的Asset computeSDK来上传、下载和编排应用程序演绎版,因此开发人员只需实施自定义应用程序逻辑。 在actions/<worker-name>
文件夹内, index.js
文件是添加自定义应用程序代码的位置。
有关自定义应用程序的示例和想法,请参阅示例自定义应用程序。
当您在创建应用程序时登录时,大多数Firefly凭据都会在您的ENV文件中收集。 但是,使用开发人员工具需要其他凭据。
使用实际的Asset Compute service测试自定义应用程序的开发人员工具需要一个云存储容器,用于托管测试文件以及接收和显示应用程序生成的演绎版。
这与作为Cloud Service的Adobe Experience Manager的云存储分开。 它仅适用于使用Asset compute开发人员工具进行开发和测试。
确保有权访问支持的云存储容器。 此容器可由多个开发人员根据需要跨不同项目共享。
将开发人员工具的以下凭据添加到Firefly项目根目录的ENV文件:
将服务添加到Firefly项目时创建的私钥文件的绝对路径添加到:
ASSET_COMPUTE_PRIVATE_KEY_FILE_PATH=
从Adobe开发人员控制台下载文件。 转到项目的根目录,然后单击右上角的“Download All”(全部下载)。 下载的文件文件名为<namespace>-<workspace>.json
。 执行下列操作之一:
将文件重命名为console.json
,并将其移到项目的根中。
或者,您也可以选择将绝对路径添加到Adobe开发人员控制台集成JSON文件。 这与在项目工作区中下载的console.json
文件相同。
ASSET_COMPUTE_INTEGRATION_FILE_PATH=
添加S3或Azure存储凭据。 您只需要访问一个云存储解决方案。
# S3 credentials
S3_BUCKET=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
# Azure Storage credentials
AZURE_STORAGE_ACCOUNT=
AZURE_STORAGE_KEY=
AZURE_STORAGE_CONTAINER_NAME=
config.json
文件包含凭据。 从项目中,将JSON文件添加到.gitignore
文件中,以阻止共享该文件。 这同样适用于.env和.aio文件。
在使用Asset compute开发人员工具执行应用程序之前,请正确配置凭据。
要在开发人员工具中运行应用程序,请使用aio app run
命令。 它将操作部署到Adobe I/O运行时,并在本地计算机上启动开发工具。 此工具用于在开发过程中测试应用程序请求。 以下是演绎版请求示例:
"renditions": [
{
"worker": "https://1234_my_namespace.adobeioruntime.net/api/v1/web/example-custom-worker-master/worker",
"name": "image.jpg"
}
]
请勿在run
命令中使用--local
标记。 它不适用于Asset Compute自定义应用程序和Asset compute开发人员工具。 自定义应用程序由Asset Compute Service调用,该应用程序无法访问开发人员本地计算机上运行的操作。
请参阅此处如何测试和调试应用程序。 完成自定义应用程序的开发后,部署自定义应用程序。
以下是示例自定义应用程序:
worker-basic是模板应用程序。 它只需复制源文件即可生成演绎版。 此应用程序的内容是在创建aio应用程序时选择Adobe Asset Compute
时收到的模板。
应用程序文件worker-basic.js
使用asset-compute-sdk
下载源文件、编排每个演绎版处理,并将生成的演绎版上传回云存储。
应用程序代码内定义的renditionCallback
是执行所有应用程序处理逻辑的位置。 worker-basic
中的演绎版回调仅将源文件内容复制到演绎版文件。
const { worker } = require('@adobe/asset-compute-sdk');
const fs = require('fs').promises;
exports.main = worker(async (source, rendition) => {
// copy source to rendition to transfer 1:1
await fs.copyFile(source.path, rendition.path);
});
在应用程序代码中,您可以进行外部API调用以帮助进行应用程序处理。 以下是调用外部API的示例应用程序文件。
exports.main = worker(async function (source, rendition) {
const response = await fetch('https://adobe.com', {
method: 'GET',
Authorization: params.AUTH_KEY
})
});
例如, worker-animal-pictures
使用node-httptransfer
库从Wikimedia向静态URL发出获取请求。
您可以通过演绎版对象传递自定义参数。 可以在rendition
说明的应用程序内引用这些参数。 呈现版本对象的示例如下:
"renditions": [
{
"worker": "https://1234_my_namespace.adobeioruntime.net/api/v1/web/example-custom-worker-master/worker",
"name": "image.jpg",
"my-custom-parameter": "my-custom-parameter-value"
}
]
应用程序文件访问自定义参数的示例如下:
exports.main = worker(async function (source, rendition) {
const customParam = rendition.instructions['my-custom-parameter'];
console.log('Custom paramter:', customParam);
// should print out `Custom parameter: "my-custom-parameter-value"`
});
example-worker-animal-pictures
传递一个自定义参数animal
,以确定要从Wiki媒体获取的文件。
默认情况下,Asset compute自定义应用程序附带Firefly应用程序的授权和身份验证检查。 可通过在manifest.yml
中将require-adobe-auth
注释设置为true
来启用此功能。
将API服务添加到在安装程序中创建的Asset Compute控制台工作区。 这些服务是Asset Compute Service生成的JWT访问令牌的一部分。 令牌和其他凭据可在应用程序操作params
对象中访问。
const accessToken = params.auth.accessToken; // JWT token for Technical Account with entitlements from the console workspace to the API service
const clientId = params.auth.clientId; // Technical Account client Id
const orgId = params.auth.orgId; // Experience Cloud Organization
要处理其他外部服务的凭据,请在操作中将这些作为默认参数传递。 在传输中会自动加密这些数据。 有关更多信息,请参阅运行时开发人员指南🔗中的创建操作。 然后,在部署期间使用环境变量进行设置。 可以在操作内的params
对象中访问这些参数。
在manifest.yml
的inputs
内设置默认参数:
packages:
__APP_PACKAGE__:
actions:
worker:
function: 'index.js'
runtime: 'nodejs:10'
web: true
inputs:
secretKey: $SECRET_KEY
annotations:
require-adobe-auth: true
$VAR
表达式从名为VAR
的环境变量中读取值。
在开发过程中,该值可以在本地ENV文件中设置为:除了从调用外壳中设置的变量之外,aio
还会自动从ENV文件中读取环境变量。 在此示例中,ENV文件如下所示:
#...
SECRET_KEY=secret-value
对于生产部署,您可以在CI系统中设置环境变量,例如在GitHub操作中使用密钥。 最后,访问应用程序内的默认参数,如下所示:
const key = params.secretKey;
应用程序在Adobe I/O运行时的容器中执行,并且limits可通过manifest.yml
进行配置:
actions:
myworker:
function: /actions/myworker/index.js
limits:
timeout: 300000
memorySize: 512
concurrency: 1
由于Asset compute应用程序通常进行的处理范围更广,因此更有可能必须调整这些限制以获得最佳性能(足够大以处理二进制资产)和效率(不会因未使用的容器内存而浪费资源)。
运行时中操作的默认超时为一分钟,但可以通过设置timeout
限制(以毫秒为单位)来增加。 如果希望处理较大的文件,请增加此次。 考虑下载源、处理文件和上传演绎版所花费的总时间。 如果某个操作超时,即在指定的超时限制前不返回激活,则运行时会丢弃该容器且不会重复使用。
Asset compute应用程序从本质上讲往往是网络和磁盘输入或输出绑定。 必须先下载源文件,处理过程通常占用大量资源,然后会再次上载生成的演绎版。
操作容器可用的内存由memorySize
指定(MB)。 目前,它还定义容器获得的CPU访问量,最重要的是,它是使用运行时成本的关键因素(容器较大,成本更高)。 当您的处理需要更多内存或CPU时,请在此处使用较大的值,但请注意不要浪费资源,因为容器越大,整体吞吐量就越低。
此外,还可以使用concurrency
设置控制容器内的操作并发。 这是单个容器(具有相同操作)获取的并发激活数。 在此模型中,操作容器与接收多个并发请求的Node.js服务器类似,只有此限制。 如果未设置,则运行时中的默认值为200,这对于较小的Firefly操作非常有用,但对于Asset compute应用程序来说通常太大,因为它们的本地处理和磁盘活动更为密集。 某些应用程序(取决于其实施)在并发活动中也可能无法正常工作。 asset computeSDK通过将文件写入不同的唯一文件夹来确保激活的分隔。
测试应用程序以找到concurrency
和memorySize
的最佳数字。 较大的容器=内存限制越高,可能会允许更多并发,但对于较低的流量也可能是浪费。