Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problem using in akamai edgworkers #54

Open
blueo opened this issue Jun 18, 2021 · 7 comments
Open

problem using in akamai edgworkers #54

blueo opened this issue Jun 18, 2021 · 7 comments

Comments

@blueo
Copy link

blueo commented Jun 18, 2021

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

@artur-ciocanu
Copy link
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.

@blueo
Copy link
Author

blueo commented Jun 21, 2021

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.

@daminisinha
Copy link

daminisinha commented Dec 17, 2021

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
}

@daminisinha
Copy link

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

@blueo
Copy link
Author

blueo commented Dec 19, 2021

@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 🤷

@daminisinha
Copy link

@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 :) .

@daminisinha
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants