adobe / adobe/asset-compute-example-workers
Update for @adobe/aio-cli-plugin-asset-compute version 1.5.0
- Dominant language
- JavaScript
- Stars
- 11
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
### Expected Behaviour
Works as produced in https://www.youtube.com/watch?v=6wdbd050UMM
### Actual Behaviour
Rendition is not created after deploy. Initial logs pointed out authentication error, but now logs no longer are produced. (aio app logs). Found some logs in dev server author logs (see below)
### Reproduce Scenario (including but not limited to)
Trying to test with example code in AEM Cloud Service dev environment.
#### Steps to Reproduce
Followed Git read me instructions.
#### Platform and Version
- local Node version .. Now using node v12.22.1 (npm v6.14.1
-
#### Sample Code that illustrates the problem
/*
* Copyright 2020 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
'use strict';
const { worker } = require('@adobe/asset-compute-sdk');
const sdk = require('@adobe/aio-lib-photoshop-api');
const libFiles = require('@adobe/aio-lib-files');
const { v4: uuidv4 } = require("uuid");
const { AioLibFilesMock } = require("../../lib/mock-aio-lib-files");
const path = require("path");
const { downloadFile } = require('@adobe/httptransfer');
/**
* Acquire authorization
*
* @param {*} params Worker parameters
* @returns {{orgId, clientId, accessToken}} authorization
*/
function getAuthorization(params) {
let orgId, clientId, accessToken;
if (process.env.WORKER_TEST_MODE) {
orgId = "test-ims-org-id";
clientId = "test-client-id";
accessToken = "test-access-token";
} else {
({ orgId, clientId, accessToken } = params.auth);
}
if (!orgId || !clientId || !accessToken) {
throw Error("Request is missing authorization information");
}
return { orgId, clientId, accessToken };
}
/**
* Set up Photoshop Action Options
*
* Resolve file types, add actionName parameter and
* set up options for Photoshop Actions Api request
*
* @param {*} client Photoshop Api Client instance
* @param {Object} instructions Rendition instructions
* @returns {Object} options for Photoshop Actions Api request
*/
async function setuphotoshopActionsOptions(client, instructions, files) {
if (!instructions || !instructions.photoshopActions) {
throw Error("Photoshop Action url not provided");
}
// workaround for action files from AEM
// we must download the action file and add the `.atn`
// extension to the file so Photoshop Service can
// recognize it
let photoshopActions = instructions.photoshopActions;
let ext;
try {
ext = path.extname(photoshopActions).substring(1).toLowerCase();
} catch (err) {
}
if (!ext) {
const tempActionFilename = `${uuidv4()}_temp.atn`;
const aioLibActionFilename = `${uuidv4()}/photoshopActions.atn`;
await downloadFile(photoshopActions, tempActionFilename);
await files.copy(tempActionFilename, aioLibActionFilename, { localSrc: true });
photoshopActions = aioLibActionFilename;
}
const options = {
actions: [{
href: photoshopActions
}]
}
if (options && Array.isArray(options.actions) && instructions.photoshopActionsName) {
options.actions[0].actionName = instructions.photoshopActionsName;
}
return options;
}
exports.main = worker(async (source, rendition, params) => {
// Authorization
const { orgId, clientId, accessToken } = getAuthorization(params);
// Initialize
let files;
if (process.env.WORKER_TEST_MODE) {
// Mock aio-lib-files in test mode in order to avoid having to mock
// the Azure and Token Vending Machine (TVM) APIs that aio-lib-files uses.
// The purpose of the tests is to make sure it uses the Photoshop APIs correctly.
files = new AioLibFilesMock();
} else {
files = await libFiles.init();
}
const client = await sdk.init(orgId, clientId, accessToken, files);
const fmt = rendition.instructions.fmt || "jpg";
const tempFilename = `${uuidv4()}/rendition.${fmt}`;
// call photoshopActions API
const options = await setuphotoshopActionsOptions(client, rendition.instructions, files);
const result = await client.applyPhotoshopActions(source.url, tempFilename, options);
console.log('Response from Photoshop API', result);
if (result && result.outputs && result.outputs[0].status === 'failed') {
const errors = result.outputs[0].errors;
console.error('Photoshop API failed:', errors);
throw new Error(`Photoshop API failed: ${errors.code} ${errors.title}`);
}
// Working with sources and renditions happens through local files,
// downloading and uploading is handled by the asset-compute-sdk.
await files.copy(tempFilename, rendition.path, { localDest: true });
await files.delete(tempFilename);
}, {
disableSourceDownload: true
});
#### Logs taken while reproducing problem
09.08.2021 19:36:49.914 [cm-p28510-e89206-aem-author-5d6c8ffd46-jq5tw] *INFO* [sling-threadpool-1e13b950-bf92-44f2-bd1f-ddf417fbfd6f-(com.adobe.cq.assetcompute.impl.assetcomputeserviceimpl)-3] com.adobe.cq.assetcompute.impl.connection.ConnectionServiceImpl Sending to Asset Compute https://asset-compute.adobe.io/process with processingId: 5a4761d0-575e-4d93-850d-080adcf3c401, request: '{"userData":"...REDACTED...","renditions":[{"wid":1280,"userData":"...REDACTED...","fmt":"jpeg","hei":1280,"target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/fbf5-4459-976d-4f41-a89a-1e148984d099-1628537809831 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"features":{"featureVector":true,"autoTags":false,"colorTags":false},"userData":"...REDACTED...","tier":"PRODUCTION","embedBinaryLimit":32768,"fmt":"machine-metadata-json","target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/3d1f-3d7c-b22d-442d-8e4e-2fe4d3167c68-1628537809833 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"wid":140,"userData":"...REDACTED...","fmt":"png","hei":100,"target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/adda-9f58-f824-42f8-8ecc-3401d4efa8b3-1628537809843 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"features":{"featureVector":false,"autoTags":{"image":false,"video":{"minimumActionConfidence":0.7,"minimumObjectConfidence":0.7},"text":{"minimumConfidence":0.7,"maximumWords":3}},"colorTags":false},"userData":"...REDACTED...","tier":"PRODUCTION","embedBinaryLimit":32768,"fmt":"machine-metadata-json","target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/0ef7-b2b7-ee6d-4e84-a046-d43a2b0f0dda-1628537809845 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"userData":"...REDACTED...","cqDamAttributes":true,"embedBinaryLimit":32768,"fmt":"metadata-xmp","target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/7f96-508e-e62c-4866-bbd0-14047a13f202-1628537809853 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"userData":"...REDACTED...","embedBinaryLimit":100,"fmt":"txt","target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/2d48-5fcf-fdeb-4006-9fac-9eca20ae246e-1628537809862 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"wid":2048,"userData":"...REDACTED...","featureToggle":"FT_CQ-4311564","fmt":"jpeg","hei":2048,"target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/ba7a-25e0-5abb-4c6e-86ac-b6677bdaa74d-1628537809870 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"userData":"...REDACTED...","photoshopActions":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/684f-0a6d-813e-4c33-a46b-4e50499e7b8d-1628365333132 ...REDACTED...","worker":"https://74839-psdassetcompute-development.adobeioruntime.net/api/v1/web/worker-cc-photoshop-1.1.1/worker-cc-photoshop ...REDACTED...","target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/19d8-096c-79b2-40aa-81f2-4f216ccc6410-1628537809872 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"wid":48,"userData":"...REDACTED...","fmt":"png","hei":48,"target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/a6fc-f095-ae8b-49e4-b265-5a10272d6577-1628537809880 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"wid":319,"userData":"...REDACTED...","fmt":"png","hei":319,"target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/fa0f-6c2b-1161-4c10-86af-e09cf2729527-1628537809883 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}},{"brightness":".1","userData":"...REDACTED...","size":"1000","contrast":".25","worker":"https://74839-rrdassetcompute1-development.adobeioruntime.net/api/v1/web/dx-asset-compute-worker-1/worker ...REDACTED...","target":{"urls":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/8d93-c407-2de9-420b-985f-33448802bdcc-1628537809885 ...REDACTED...","minPartSize":10485760,"maxPartSize":104857600}}],"source":{"url":"https://sa0285100shared0454cf89b.blob.core.windows.net/aem-blob-ns-team-aem-cm-prd-n21959-cm-p28510-e89206/3c18-ce7e-e4f5-4d39-805e-86deda403009-1628537808545 ...REDACTED..."}}'
09.08.2021 19:37:28.382 [cm-p28510-e89206-aem-author-5d6c8ffd46-9qnsc] *INFO* [sling-cq-asset-processing-5-adobe-io-assetcompute-events-consuming-job] com.adobe.cq.assetcompute.impl.event.AssetComputeRenditionEventImpl Asset Compute worker failed to generate rendition for asset '/content/dam/rrd/jay-test/rendition-test-2/9999_JAYTEST_8888.png', processingId: '5a4761d0-575e-4d93-850d-080adcf3c401', Reason: 'GenericError', Message: '[PhotoshopSDK:ERROR_AUTH_FORBIDDEN] 403 - Forbidden ({"error_code":"403003","message":"Api Key is invalid"})'.
Contributor guide
Research direction
Start with the sample worker entry point at exports.main and the README instructions, then compare the reported deployment setup with the Photoshop API authorization path in the example code. Reproduce the AEM Cloud Service scenario and use the provided Asset Compute and author logs; done means the deployed worker creates the rendition without the 403 invalid-API-key error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100