Skip to content

Commit 157dc2d

Browse files
authored
markup-cleanup fix (#239)
markup-cleanup action now unpublished url path that's no longer used.
1 parent d2f9c72 commit 157dc2d

4 files changed

Lines changed: 95 additions & 23 deletions

File tree

actions/check-product-changes/poller.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ const { Timings, aggregate } = require('../lib/benchmark');
1414
const { AdminAPI } = require('../lib/aem');
1515
const {
1616
requestSaaS,
17-
requestSpreadsheet,
1817
isValidUrl,
1918
getProductUrl,
2019
formatMemoryUsage,
2120
FILE_PREFIX,
2221
STATE_FILE_EXT,
2322
PDP_FILE_EXT,
23+
requestPublishedProductsIndex,
2424
} = require('../utils');
2525
const { GetLastModifiedQuery } = require('../queries');
2626
const { generateProductHtml } = require('../pdp-renderer/render');
@@ -293,7 +293,7 @@ async function processDeletedProducts(remainingSkus, state, context, adminApi) {
293293
const { filesLib } = aioLibs;
294294

295295
try {
296-
const deletedProducts = (await requestSpreadsheet('published-products-index', null, context))
296+
const deletedProducts = (await requestPublishedProductsIndex(context))
297297
.data.filter(({ sku }) => remainingSkus.includes(sku));
298298

299299
// Process in batches

actions/mark-up-clean-up/index.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ const { Core, Files } = require('@adobe/aio-sdk');
1414
const { ObservabilityClient } = require('../lib/observability');
1515
const { GetUrlKeyQuery } = require('../queries');
1616
const { getRuntimeConfig } = require('../lib/runtimeConfig');
17+
const { AdminAPI } = require('../lib/aem');
1718
const {
1819
requestSaaS,
19-
requestSpreadsheet,
20+
requestPublishedProductsIndex,
2021
PDP_FILE_EXT,
22+
createBatches,
2123
} = require('../utils');
2224

2325
/**
@@ -43,13 +45,13 @@ function urlkeymatch(publishedProduct, queriedProducts){
4345
* @param {Object} context - The context object with logger and other utilities
4446
* @param {Object} filesLib - The files library instance from '@adobe/aio-sdk'
4547
*/
46-
async function markUpCleanUP(context, filesLib, logger) {
48+
async function markUpCleanUP(context, filesLib, logger, adminApi) {
4749

4850
try {
49-
const publishedProducts = await requestSpreadsheet('published-products-index', null, context);
51+
const publishedProducts = await requestPublishedProductsIndex(context);
5052
const publishedSkus = publishedProducts.data.map((product) => product.sku);
5153
let queryResult = await requestSaaS(GetUrlKeyQuery, 'getUrlKey', { skus: publishedSkus }, context);
52-
queryResult = queryResult.data.products
54+
queryResult = queryResult.data.products;
5355

5456
const redundantpublishedProducts = publishedProducts.data.filter((product) => !urlkeymatch(product, queryResult))
5557
context.counts.detected = redundantpublishedProducts.length;
@@ -68,6 +70,20 @@ async function markUpCleanUP(context, filesLib, logger) {
6870
}
6971
}
7072
};
73+
const pendingJobs = [];
74+
const unpublishJobsBatches = createBatches(redundantpublishedProducts);
75+
for (let batchNumber = 0; batchNumber < unpublishJobsBatches.length; batchNumber++) {
76+
const batch = unpublishJobsBatches[batchNumber].map((product) => {
77+
return {
78+
sku: product.sku,
79+
path: product.path,
80+
};
81+
});
82+
const pendingJob = adminApi.unpublishAndDelete(batch, context.locale, batchNumber);
83+
context.counts.unpublished += batch.length;
84+
pendingJobs.push(pendingJob);
85+
}
86+
await Promise.all(pendingJobs);
7187
} catch (e) {
7288
logger.error('Error while cleanning up markup storage', e);
7389
}
@@ -99,7 +115,7 @@ async function main(params) {
99115
logIngestorEndpoint,
100116
} = cfg;
101117

102-
const counts = { detected: 0, deleted: 0 };
118+
const counts = { detected: 0, deleted: 0, unpublished: 0 };
103119

104120
const sharedContext = {
105121
storeUrl,
@@ -113,22 +129,30 @@ async function main(params) {
113129
logLevel,
114130
logIngestorEndpoint,
115131
}
132+
const adminApi = new AdminAPI({ org: params.ORG, site: params.SITE }, sharedContext, { authToken: params.AEM_ADMIN_AUTH_TOKEN });
116133

117134
let activationResult = {status: {}};
118135

119-
for (const locale of locales) {
120-
const context = { ...sharedContext, startTime: new Date() };
121-
let tempLocale = 'default';
122-
if (locale) {
123-
context.locale = locale;
124-
tempLocale = locale;
125-
}
136+
try {
137+
adminApi.startProcessing();
126138

127-
activationResult.status[tempLocale] = await markUpCleanUP(context, filesLib, logger);
128-
}
139+
for (const locale of locales) {
140+
const context = { ...sharedContext, startTime: new Date() };
141+
let tempLocale = 'default';
142+
if (locale) {
143+
context.locale = locale;
144+
tempLocale = locale;
145+
}
146+
activationResult.status[tempLocale] = await markUpCleanUP(context, filesLib, logger);
147+
}
129148

130-
await observabilityClient.sendActivationResult(activationResult);
131-
return activationResult;
149+
await observabilityClient.sendActivationResult(activationResult);
150+
return activationResult;
151+
} catch (e) {
152+
logger.error(e);
153+
} finally {
154+
await adminApi.stopProcessing();
155+
}
132156
}
133157

134158
exports.main = main

actions/utils.js

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,29 @@ governing permissions and limitations under the License.
1111
*/
1212
const deepmerge = require('@fastify/deepmerge')();
1313
const helixSharedStringLib = require('@adobe/helix-shared-string');
14+
const BATCH_SIZE = 50;
1415

1516
/* This file exposes some common utilities for your actions */
1617

1718
const FILE_PREFIX = 'check-product-changes';
1819
const [STATE_FILE_EXT, PDP_FILE_EXT] = ['csv', 'html'];
1920

21+
/**
22+
* Creates batches of products for processing
23+
* @param products
24+
* @param context
25+
* @returns {*}
26+
*/
27+
function createBatches(products) {
28+
return products.reduce((acc, product) => {
29+
if (!acc.length || acc[acc.length - 1].length === BATCH_SIZE) {
30+
acc.push([]);
31+
}
32+
acc[acc.length - 1].push(product);
33+
return acc;
34+
}, []);
35+
}
36+
2037
/**
2138
*
2239
* Returns the list of missing keys giving an object and its required keys.
@@ -176,13 +193,42 @@ async function request(name, url, req, timeout = 60000) {
176193
*
177194
* @returns {Promise<object>} spreadsheet data as JSON.
178195
*/
179-
async function requestSpreadsheet(name, sheet, context) {
196+
async function requestSpreadsheet(name, sheet, context, offset = 0) {
180197
const { contentUrl } = context;
181198
let sheetUrl = `${contentUrl}/${name}.json`
199+
const requestURL = new URL(sheetUrl);
200+
182201
if (sheet) {
183-
sheetUrl += `?sheet=${sheet}`;
202+
requestURL.searchParams.set('sheet', sheet);
184203
}
185-
return request('spreadsheet', sheetUrl);
204+
205+
if (offset > 0) {
206+
requestURL.searchParams.set('offset', offset);
207+
}
208+
209+
return request('spreadsheet', requestURL.toString());
210+
}
211+
212+
/**
213+
* Requests the published products index from the site.
214+
*
215+
* @param {string} name file name of the spreadsheet.
216+
* @param {string} [sheet] optional sheet name.
217+
* @param {object} context the context object.
218+
*
219+
* @returns {Promise<object>} spreadsheet data as JSON.
220+
*/
221+
async function requestPublishedProductsIndex(context) {
222+
223+
const publishedProductsIndex = await requestSpreadsheet('published-products-index', null, context, 0);
224+
225+
for (let offset = 1000; offset < publishedProductsIndex.total; offset += 1000) {
226+
const tempPublishedProductsIndex = await requestSpreadsheet('published-products-index', null, context, offset);
227+
publishedProductsIndex.data.push(...tempPublishedProductsIndex.data);
228+
}
229+
publishedProductsIndex.limit = publishedProductsIndex.total;
230+
231+
return publishedProductsIndex;
186232
}
187233

188234
async function requestConfigService(context) {
@@ -391,6 +437,7 @@ function formatMemoryUsage(data) {
391437
}
392438

393439
module.exports = {
440+
createBatches,
394441
errorResponse,
395442
getBearerToken,
396443
checkMissingRequestInputs,
@@ -402,6 +449,7 @@ module.exports = {
402449
getProductUrl,
403450
getDefaultStoreURL,
404451
formatMemoryUsage,
452+
requestPublishedProductsIndex,
405453
FILE_PREFIX,
406454
PDP_FILE_EXT,
407455
STATE_FILE_EXT,

tools/check-products-count.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require('dotenv').config();
1515
const fs = require('fs');
1616
const yaml = require('js-yaml');
1717
const path = require('path');
18-
const { requestSaaS, requestSpreadsheet } = require('../actions/utils');
18+
const { requestSaaS, requestPublishedProductsIndex } = require('../actions/utils');
1919
const { GetAllSkusPaginatedQuery } = require('../actions/queries');
2020
const filePath = path.resolve(__dirname, '..', 'app.config.yaml');
2121

@@ -42,7 +42,7 @@ async function main() {
4242
} = process.env;
4343

4444
const context = { storeCode: options.storecode, storeUrl: options.url, configName: options.config };
45-
const { total: actualCount } = await requestSpreadsheet('published-products-index', context);
45+
const { total: actualCount } = await requestPublishedProductsIndex(context);
4646
let [productsCount, currentPage, expectedCount] = [-1, 1, 0];
4747
while (productsCount !== 0) {
4848
const { data: { productSearch: { items: products } } } = await requestSaaS(GetAllSkusPaginatedQuery, 'getAllSkusPaginated', { currentPage }, context);

0 commit comments

Comments
 (0)