Как я могу использовать облачную функцию Google, чтобы передать файл из хранилища Cloud Storage в экземпляр? - PullRequest
0 голосов
/ 21 января 2019

Мне была поручена задача найти способ настроить облачную функцию в GCP, которая выполняет следующие действия:

  • Отслеживает корзину Google Cloud Storage для новых файлов

  • Пуски, когда он обнаруживает новый файл в корзине

  • Копирует этот файл в каталог внутри Compute Instance (Ubuntu)

Я проводил некоторые исследования и собираюсь опустеть.Я знаю, что могу легко настроить работу cron, которая синхронизирует каталог / папку каждую минуту или что-то в этом роде, но одна из философий проектирования системы, которую мы создаем, - это запуск триггеров, а не таймеров.

Возможно ли то, что я спрашиваю?

1 Ответ

0 голосов
/ 21 января 2019

Вы можете запускать облачную функцию из корзины Google Cloud Storage и, выбрав тип события Завершить / Создать , каждый раз, когда файл загружается в корзину,будет вызываться функция Cloud.

Каждый раз, когда в корзине создается новый объект, облачная функция получает уведомление в формате Cloud Storage .

Теперь, на втором шаге, я не смог найти API, который мог бы загружать файлы из облачного хранилища на виртуальную машину экземпляра.Однако в качестве обходного пути я сделал следующее, предполагая, что на виртуальной машине вашего экземпляра настроен сервер, который может принимать HTTP-запросы (например, Apache или Nginx):

main.py

import requests
from google.cloud import storage

def hello_gcs(data, context):
    """Background Cloud Function to be triggered by Cloud Storage.  
    Args:
        data (dict): The Cloud Functions event payload.
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the file is sent as a request to 
    """
    print('Bucket: {}'.format(data['bucket']))
    print('File: {}'.format(data['name']))

    client = storage.Client()
    bucket = client.get_bucket(format(data['bucket']))
    blob = bucket.get_blob(format(data['name']))

    contents = blob.download_as_string()

    headers = {
        'Content-type': 'text/plain',
    }

    data = '{"text":"{}"}'.format(contents)
    response = requests.post('https://your-instance-server/endpoint-to-download-files', headers=headers, data=data)
    return "Request sent to your instance with the data of the object"

needs.txt

google-cloud-storage
requests

Скорее всего, было бы лучше просто отправить имя объекта и имя сегмента в конечную точку вашего сервера и оттуда скачатьфайлы с использованием Cloud Client Library .

Теперь вы можете спросить ...

Как создать экземпляр Compute Engine для обработки запроса?

  1. Создание виртуальной машины экземпляра Compute Engine.Убедитесь, что он находится в том же регионе, что и облачная функция, и при создании разрешите HTTP-подключения к нему. Документация .Для этого теста я использовал образ debian-9.

  2. SSH в экземпляре и запустил следующие команды:

    • Установить сервер Apache

      sudo apt-get update
      sudo apt-get install apache2
      sudo apt-get install libapache2-mod-wsgi
      
    • Установите также следующие библиотеки Python:

      sudo apt-get install python-pip
      sudo pip install flask
      
  3. Настройка среды для вашего приложения:

    cd ~/
    mkdir app
    sudo ln -sT ~/app /var/www/html/app
    

Последняя строка должна указывать путь к папке, из которой apache отправляет файл index.html из.

Создайте свое приложение в /home/<user_name>/app:

main.py

from flask import Flask, request
app = Flask(__name__)

@app.route('/', methods=['POST'])
def receive_file():
    file_content = request.form['data']
    # TODO
    # Implement process to save this data onto a file
    return 'Hello from Flask!'

if __name__ == '__main__':
  app.run()
Создать точку входа сервера wsgi в том же каталоге:

main.wsgi

import sys
sys.path.insert(0, '/var/www/html/app')

from main import app as application

Добавьте следующую строку в /etc/apache2/sites-enabled/000-default.conf после тега DocumentRoot:

    WSGIDaemonProcess flaskapp threads=5
    WSGIScriptAlias / /var/www/html/app/main.wsgi

    <Directory app>
            WSGIProcessGroup main
            WSGIApplicationGroup %{GLOBAL}
            Order deny,allow
            Allow from all
    </Directory>

Выполнить sudo apachectl restart.Вы должны иметь возможность отправлять пост-запросы в ваше приложение, на внутренний IP-адрес экземпляра виртуальной машины (вы можете увидеть это в консоли, в разделе Compute Engine).Если у вас есть это, в вашей облачной функции вы должны изменить строку ответа на:

response = requests.post('<INTERNAL_INSTANCE_IP>/', headers=headers, data=data)

return "Request sent to your instance with the data of the object"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...