Node.js: в ожидании запроса - PullRequest
0 голосов
/ 05 марта 2019

Я новичок Node.js, и я работаю с примером проекта сторонним поставщиком, и я пытаюсь использовать хранилище ключей Azure для хранения значений конфигурации.

Явозникли проблемы с получением процесса до wait перед выполнением остальных.Я постараюсь подробно описать столько, сколько знаю.

Пример проекта содержит файл с именем agent.js, который является стартовой страницей / файлом.В строке 16 (agent_config = require('./config/config.js')[process.env.LP_ACCOUNT][process.env.LP_USER]) он вызывает файл конфигурации со значениями.Я пытаюсь установить эти значения с помощью Key Vault.Я перепробовал множество комбинаций вызывающих функций и даже реализовал async / await, но значение для agent_config всегда содержит объект [Promise], а не данные, возвращаемые Key Vault.

Если я правэто происходит потому, что само хранилище ключей также использует async / await, и файл конфигурации возвращается до того, как возвращаются значения хранилища ключей.

Как можно добавить / внедрить хранилище ключей в такой ситуации?

Вот что я попробовал:

Первое обновление agent.js до

let agent_config = {};
try {
  agent_config = require('./config/config.js')['123']['accountName'];
} catch (ex) {
  log.warn(`[agent.js] Error loading config: ${ex}`)
}

console.log(agent_config);

Тест 1

. / Config/config.js

const KeyVault = require('azure-keyvault');
const msRestAzure = require('ms-rest-azure');
const KEY_VAULT_URI = 'https://' + '{my vault}' + '.vault.azure.net/' || process.env['KEY_VAULT_URI'];

function getValue(secretName, secretVersion) {
  msRestAzure.loginWithAppServiceMSI({ resource: 'https://vault.azure.net' }).then((credentials) => {
    const client = new KeyVault.KeyVaultClient(credentials);
    client.getSecret(KEY_VAULT_URI, secretName, secretVersion).then(
      function (response) {
        return response.Value;
      });
  });
}

module.exports = {
    '123': {
        'accountName': {
            accountId: getValue('mySecretName', '')
         }
     }
};

Результаты

{accountId: undefined}

Тест 2

Сделал getValue async и обернул ее вокруг другой функции (пробовал без переноса и тоже не работал)

. / Config / config.js

const KeyVault = require('azure-keyvault');
const msRestAzure = require('ms-rest-azure');
const KEY_VAULT_URI = 'https://' + '{my vault}' + '.vault.azure.net/' || process.env['KEY_VAULT_URI'];

async function getValue(secretName, secretVersion) {
  msRestAzure.loginWithAppServiceMSI({ resource: 'https://vault.azure.net' }).then((credentials) => {
    const client = new KeyVault.KeyVaultClient(credentials);
    client.getSecret(KEY_VAULT_URI, secretName, secretVersion).then(
      function (response) {
        return response.Value;
      });
  });
}

async function config() {
    module.exports = {
        '123': {
            'accountName': {
                accountId: await getValue('mySecretName', '')
             }
         }
    };
}

config();

Результаты

{}

Тест 3

Сделано getValue и async functiи обернул его вокруг другой функции (пробовал без переноса и тоже не работал)

. / config / config.js

const KeyVault = require('azure-keyvault');
const msRestAzure = require('ms-rest-azure');
const KEY_VAULT_URI = 'https://' + '{my vault}' + '.vault.azure.net/' || process.env['KEY_VAULT_URI'];

async function getValue(secretName, secretVersion) {
  return msRestAzure.loginWithAppServiceMSI({ resource: 'https://vault.azure.net' })
    .then((credentials) => {
      const client = new KeyVault.KeyVaultClient(credentials);
      return client.getSecret(KEY_VAULT_URI, secretName, secretVersion).then(
        function (response) {
          return response.Value;
        });
    });
}

module.exports = {
    '123': {
        'accountName': {
            accountId: getValue('mySecretName', '')
        }
    }
};

config();

Результаты

{accountId: {}}

Other

Я пробовал много других способов, таких как module.exports = async (value) =< {...} (другие вопросы / решения найдены безуспешно.

Я начинаю думать, что мне нужно немного подождать с agent.js, но я не нашел хорошей информации по этому вопросу.

Любая помощь будет отличной!

1 Ответ

0 голосов
/ 05 марта 2019

Одна из проблем заключается в том, что ваша функция getValue ничего не возвращает, так как ваши возвраты должны быть явными.

(и без возврата обещания ждать нечего)

async function getValue(secretName, secretVersion) {
  return msRestAzure.loginWithAppServiceMSI({ resource: 'https://vault.azure.net' })
    .then((credentials) => {
      const client = new KeyVault.KeyVaultClient(credentials);
      return client.getSecret(KEY_VAULT_URI, secretName, secretVersion).then(
        function (response) {
          return response.Value;
        });
    });
}

Вы также можете обойтись без менее явных возвратов, используя функции стрелок.

const getValue = async (secretName, secretVersion) => 
  msRestAzure.loginWithAppServiceMSI({ resource: 'https://vault.azure.net' })
    .then(credentials => {
      const client = new KeyVault.KeyVaultClient(credentials);
      return client.getSecret(KEY_VAULT_URI, secretName, secretVersion)
        .then(response => response.Value);
    });

Представление чтения хранилища ключей Azure, которое является асинхронным, означает, что все чтение конфигурации является асинхронным.Там нет ничего, что вы можете сделать, чтобы обойти это.Это будет означать, что код, который использует конфигурацию, должен будет обрабатывать его соответствующим образом.Вы начинаете с экспорта асинхронной функции, которая будет возвращать конфигурацию ..

async function getConfig() {
  return {
    '123': {
      'accountName': {
        accountId: await getValue('mySecretName', '')
      }
    }
  };
}

module.exports = getConfig;

В коде вашего агента вы вызываете эту функцию.Это будет означать, что ваш агентский код тоже нужно будет обернуть в функцию, так что, может быть, что-то вроде этого ..

const Bot = require('./bot/bot.js');
const getConfig = require('./config/config.js');

getConfig().then(agentConfig => {
    const agent = new Bot(agentConfig);

    agent.on(Bot.const.CONNECTED, data => {
        log.info(`[agent.js] CONNECTED ${JSON.stringify(data)}`);
    });
});
...