Как получить ARN очереди AWS SQS в nodeJS?

Я пытаюсь создать приложение с базовой инфраструктурой клиент-сервер. Инфраструктура сервера размещается на AWS, и когда клиент входит в систему, он отправляет сообщение на сервер, чтобы настроить различные параметры инфраструктуры. Одна из частей инфраструктуры - это очередь SQS, из которой клиент может опрашивать, чтобы получать обновления с сервера (в конечном итоге я хотел бы создать службу push, но пока не знаю, как это сделать).

Я создаю это приложение на NodeJS с помощью Node AWS SDK. Проблема, с которой я столкнулся, заключается в том, что мне нужна очередь ARN, чтобы делать различные вещи, например, подписывать очередь SQS на тему SNS, которую использует приложение, но API создания очереди возвращает URL-адрес очереди, а не ARN. Таким образом, я могу получить ARN из URL-адреса с помощью API getQueueAttributes, но, похоже, он не работает. Всякий раз, когда я его вызываю, я получаю неопределенный ответ. Вот мой код, скажите, пожалуйста, что я делаю не так:

exports.handler = (event, context, callback) => {

    new aws.SQS({apiVersion: '2012-11-05'}).createQueue({
            QueueName: event.userId
        }).promise()
    )
    .then(data => { /* This has the Queue URL */
        new aws.SQS({apiVersion: '2012-11-05'}).getQueueAttributes({
            QueueUrl: data.QueueUrl,
            AttributeNames: ['QueueArn']
        }).promise()
    })
    .then(data => {
        console.log(JSON.stringify(data)); /* prints "undefined" */
    })
/* Some more code down here that's irrelevant */
}

Спасибо!


person Ertai87    schedule 22.04.2020    source источник
comment
вы пробовали All вместо QueueArn, что он возвращает?   -  person Ersoy    schedule 23.04.2020
comment
Я пробовал «Все», [«Все»], [«QueueArn»] и «QueueArn». Все они возвращаются undefined.   -  person Ertai87    schedule 23.04.2020
comment
Вы пытались вызвать getQueueAttributes в существующей очереди - я имею в виду, что если aws создает очередь асинхронно, вы можете не получить ее обратно, даже если createQueue завершен.   -  person Ersoy    schedule 23.04.2020
comment
Да, я попытался создать очередь, а затем закомментировать часть создания очереди и жестко указать URL-адрес очереди из консоли AWS. Это тоже не сработало. Кстати, поскольку это, вероятно, будет ваш следующий вопрос, я попытался использовать AWS CLI с консоли, и он отлично сработал.   -  person Ertai87    schedule 23.04.2020
comment
да :) - как насчет роли выполнения этой лямбды - разрешает ли эта роль лямбды доступ к SQS?   -  person Ersoy    schedule 23.04.2020
comment
поскольку вы создаете очередь, у вас, вероятно, есть полный доступ, но, возможно, в политиках чего-то не хватает для чтения.   -  person Ersoy    schedule 23.04.2020
comment
Я только что привязал роль полного доступа AWS SQS по умолчанию к моей роли выполнения лямбда.   -  person Ertai87    schedule 23.04.2020
comment
Мне удалось попробовать свою консоль aws и успешно получить arn - я поделюсь кодом в качестве ответа для форматирования и размера   -  person Ersoy    schedule 23.04.2020


Ответы (2)


const AWS = require('aws-sdk');
const sqs = new AWS.SQS();

exports.handler = async(event, context, callback) => {

    var params = {
        QueueUrl: 'my-queue-url',
        AttributeNames: ['QueueArn']
    };

    let fo = await sqs.getQueueAttributes(params).promise();
    console.log(fo);
};

и он напечатал

{
    ResponseMetadata: { RequestId: '123456-1234-1234-1234-12345' },
    Attributes: {
        QueueArn: 'arn:aws:sqs:eu-west-1:12345:my-queue-name'
    }
}
person Ersoy    schedule 22.04.2020
comment
Лямбда-консоль (частичный вывод): errorMessage: SyntaxError: await допустимо только в асинхронной функции, - person Ertai87; 23.04.2020
comment
проверьте ›exports.handler = async (event, context, callback) =› { - person Ersoy; 23.04.2020
comment
Когда я изменил ожидание на Promise.then (), это сработало. Я потратил на это слишком много времени сегодня, я постараюсь расширить это завтра и вернуться к вам. Вы пытались связать обещания так, как я пытаюсь это сделать, создав очередь, а затем пытаясь читать из нее? Я собираюсь попробовать это завтра, когда вернусь к этому. - person Ertai87; 23.04.2020
comment
не пробовал, просто пытался получить с текущим кодом. вы можете использовать async / await внутри лямбды, что может избавить вас от обратных вызовов. AFAIK почти все методы библиотеки aws-sdk поддерживают async / await. - person Ersoy; 23.04.2020
comment
Хорошо, если я сделаю свою функцию асинхронной, а затем разделю цепочку Promise.then на кучу вызовов await, тогда она сработает. Мне было бы интересно узнать, почему это так (я вроде как новичок в NodeJS, поэтому не понимаю этого). - person Ertai87; 23.04.2020
comment
Пожалуйста, проверьте stackoverflow.com/a/34401662/2188922 и medium.com/front-end-weekly/ (я не являюсь автором обоих сообщений, объясняют они хорошо) - person Ersoy; 23.04.2020
comment
Проголосовал за всю вашу помощь, но на самом деле это был не ответ. Ответ я выложил сам. - person Ertai87; 23.04.2020

С помощью Ersoy я понял, что использую блочное форматирование (с {}) для написания своих обещаний, но я никогда ничего не возвращал из этих блоков. Я думал, что последнее значение в блоке Promise было возвращаемым значением по умолчанию, но похоже, что это не так. Когда я добавил return перед командой SQS API, он работал (без использования async / await).

person Ertai87    schedule 23.04.2020