Skip to content

problem using in akamai edgworkers #54

Description

@blueo

Expected Behaviour

I expect I can use the sdk in an akamai edgeworker

Actual Behaviour

Edgeworker static validation fails

Reproduce Scenario (including but not limited to)

Steps to Reproduce

import sdk version > 2.1.1 to an akamai edgworker js file
Upload edgworker using cli (eg akamai ew upload --codeDir ./ [workerID]
reported error:

{
  "type": "/edgeworkers/error-types/edgeworkers-invalid-argument",
  "title": "Invalid Argument.",
  "detail": "Tarball validation failed: static validation failed : main.js::12:24 Unknown built-in module: \"crypto\".",
  "instance": "/edgeworkers/error-instances/124d6da6-ebb0-4153-a145-ca67704ae8fc",
  "status": 400,
  "errorCode": "EW1108",
  "traceId": "f01b60cc2d1f1c55"
}

Platform and Version

akamai edgeworker

Sample Code that illustrates the problem

main.js :

import { httpRequest } from "http-request";
import { createResponse } from "create-response";
import { logger } from "log";
import { Cookies } from "cookies";
/** end provided modules */
import TargetClient from "@adobe/target-nodejs-sdk";

const clientCode = "xxxx";
const organizationId = "xxxx;
const rulesUrl = `https://assets.adobetarget.com/${clientCode}/production/v1/rules.json`;

function createTargetClient(rules) {
  return new Promise((resolve) => {
    const result = TargetClient.create({
      client: clientCode,
      organizationId: organizationId,
      decisioningMethod: "on-device",
      artifactPayload: rules,
      pollingInterval: 0, // "0" prevents polling, if artifactPayload is provided
      targetLocationHint: "<location hint>", // prevent cluster discovery
      logger: logger, // use Akamai EdgeWorker provided logger
      fetchApi: httpRequest,
      events: {
        clientReady: () => resolve(result),
      },
    });
  });
}

export async function responseProvider(request) {
  try {
    const deliveryRequest = {
      execute: {
        mboxes: [
          {
            address: { url: request.host + request.url },
            name: "a1-serverside-ab",
          },
        ],
      },
    };

    const rules = await httpRequest(rulesUrl).then((response) => response.json());
    const client = await createTargetClient(rules);
    const cookies = new Cookies(request.getHeader("Cookie"));
    const visitorCookie = cookies.get(TargetClient.getVisitorCookieName(organizationId));
    const targetCookie = cookies.get(TargetClient.TargetCookieName);
    const { response } = await client.getOffers({ request: deliveryRequest, visitorCookie, targetCookie });

    return createResponse(200, {}, JSON.stringify(response));
  } catch (e) {
    logger.log(e);
    return createResponse(400, {}, JSON.stringify(e));
  }
}

i'm working from this example: https://github.com/artur-ciocanu/odd-akamai-edge-workers/

if I pin my version to 2.1.1 then I can avoid the issue

Logs taken while reproducing problem

Activity

  1. artur-ciocanu commented on Jun 21, 2021

    @artur-ciocanu
    Contributor

    @blueo thanks a lot of for reporting the issue. We will take a look and see what can be done. As workaround you could provide your own window.crypto implementation, until we figure out how to properly fix it for EdgeWorker environment.

  2. blueo commented on Jun 21, 2021

    @blueo
    Author

    Thanks @artur-ciocanu I'll give it a go - at the moment I've pegged back a few versions but ideally I could just provide it as you say.

  3. daminisinha commented on Dec 17, 2021

    @daminisinha

    Hi, for the above issue which I also facing please code provide the code snippet for workaround because I tried creating a polyfill for crypto , nothing works for me. Thanks

    rollup.config.js

    import nodeResolve from '@rollup/plugin-node-resolve'
    import typescript from '@rollup/plugin-typescript'
    import json from '@rollup/plugin-json'
    import commonjs from '@rollup/plugin-commonjs'
    import babel from 'rollup-plugin-babel'
    import filesize from 'rollup-plugin-filesize'
    import polyfill from 'rollup-plugin-polyfill'
    
    function getPlugins(babelConfig) {
      return [
        json(),
        nodeResolve({
          browser: true
        }),
        commonjs(),
        polyfill(['./cryptoPolyfill.js']),
        babel(babelConfig),
        typescript(),
        filesize()
      ]
    }
    
    export default [
      {
        input: 'src/index.ts',
        external: [
          'http-request',
          'create-response',
          'log',
          'text-encode-transform',
          'streams',
          'cookies'
        ],
        output: {
          name: 'main',
          file: 'dist/main.js',
          format: 'esm',
          sourcemap: false
        },
        plugins: getPlugins({
          inputSourceMap: true,
          sourceMaps: true,
          runtimeHelpers: true,
          exclude: ['node_modules/**', /\/core-js\//],
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',
                corejs: 3,
                modules: false,
                targets: {
                  browsers: [
                    'last 2 Chrome versions',
                    'last 2 Firefox versions',
                    'last 2 Safari versions'
                  ]
                }
              }
            ]
          ],
          plugins: ['@babel/plugin-transform-runtime']
        })
      }
    ]
    

    crypto polyfill -

    const cryptoPolyfill = require('polyfill-crypto.getrandomvalues')
    if (window && window.crypto && !window.crypto.getRandomValues) {
      window.crypto.getRandomValues = cryptoPolyfill
    }
    
    if (crypto && !crypto.getRandomValues) {
      crypto.getRandomValues = cryptoPolyfill
    }
    
  4. daminisinha commented on Dec 17, 2021

    @daminisinha

    Hi, for the above issue which I also facing please code provide the code snippet for workaround because I tried creating a polyfill for crypto , nothing works for me. Thanks

    rollup.config.js

    import nodeResolve from '@rollup/plugin-node-resolve'
    import typescript from '@rollup/plugin-typescript'
    import json from '@rollup/plugin-json'
    import commonjs from '@rollup/plugin-commonjs'
    import babel from 'rollup-plugin-babel'
    import filesize from 'rollup-plugin-filesize'
    import polyfill from 'rollup-plugin-polyfill'
    
    function getPlugins(babelConfig) {
      return [
        json(),
        nodeResolve({
          browser: true
        }),
        commonjs(),
        polyfill(['./cryptoPolyfill.js']),
        babel(babelConfig),
        typescript(),
        filesize()
      ]
    }
    
    export default [
      {
        input: 'src/index.ts',
        external: [
          'http-request',
          'create-response',
          'log',
          'text-encode-transform',
          'streams',
          'cookies'
        ],
        output: {
          name: 'main',
          file: 'dist/main.js',
          format: 'esm',
          sourcemap: false
        },
        plugins: getPlugins({
          inputSourceMap: true,
          sourceMaps: true,
          runtimeHelpers: true,
          exclude: ['node_modules/**', /\/core-js\//],
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',
                corejs: 3,
                modules: false,
                targets: {
                  browsers: [
                    'last 2 Chrome versions',
                    'last 2 Firefox versions',
                    'last 2 Safari versions'
                  ]
                }
              }
            ]
          ],
          plugins: ['@babel/plugin-transform-runtime']
        })
      }
    ]
    

    crypto polyfill -

    const cryptoPolyfill = require('polyfill-crypto.getrandomvalues')
    if (window && window.crypto && !window.crypto.getRandomValues) {
      window.crypto.getRandomValues = cryptoPolyfill
    }
    
    if (crypto && !crypto.getRandomValues) {
      crypto.getRandomValues = cryptoPolyfill
    }
    

    @blueo please code you help me out maybe? Thanks

  5. blueo commented on Dec 19, 2021

    @blueo
    Author

    @daminisinha that looks like it could be a good way around the problem - this is a while ago so I can't quite remember but I had a similar problem trying to pollyfill. I think the main issue was trying to pollyfill the 'import 'crypto' statement in /packages/target-tools/src/uuid/rng.js but this might have been my lack of rollup experience. I ended up manually editing the compiled/minified JS to 'patch' it so I could get a proof of concept going but ultimately just used an older version.

    However I ran into another road block shortly after - it turns out there are some performance limits in edgworkers - particularly the JavaScript initialization timeout. No matter what I did with the code example above just having this library in the bundle meant that I hit the initialisation limit on a cold start. This pretty much made it unworkable for us so we ended up using the Akamai Audience Segmentation product instead. Not perfect but got us there in the end - sorry this isn't more helpful 🤷

  6. daminisinha commented on Dec 20, 2021

    @daminisinha

    @daminisinha that looks like it could be a good way around the problem - this is a while ago so I can't quite remember but I had a similar problem trying to pollyfill. I think the main issue was trying to pollyfill the 'import 'crypto' statement in /packages/target-tools/src/uuid/rng.js but this might have been my lack of rollup experience. I ended up manually editing the compiled/minified JS to 'patch' it so I could get a proof of concept going but ultimately just used an older version.

    However I ran into another road block shortly after - it turns out there are some performance limits in edgworkers - particularly the JavaScript initialization timeout. No matter what I did with the code example above just having this library in the bundle meant that I hit the initialisation limit on a cold start. This pretty much made it unworkable for us so we ended up using the Akamai Audience Segmentation product instead. Not perfect but got us there in the end - sorry this isn't more helpful 🤷

    Thanks @blueo for your response :) .

  7. daminisinha commented on Dec 21, 2021

    @daminisinha

    Somehow crypto error has gone and I started getting new error while using a package
    "@adobe/target-nodejs-sdk": "^2.3.0"

    Seems like when we do yarn build this package throws an error.

    [!] Error: 'default' is not exported by node_modules/@adobe/target-nodejs-sdk/dist/targetclient.browser.js, imported by src/index.ts
    https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module
    src/index.ts (8:7)

    import TargetClient from '@adobe/target-nodejs-sdk';

    Does anybody know the fix about the same? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions