AWS SDK for Rubyでlocalstack + OpenSearch環境に接続する
ローカルのdocker環境に構築したlocalstack + OpenSearchにAWS SDK for Rubyを用いた接続方法です。 接続方法自体はAWS公式のデベロッパーガイドに記載されていますが、クライアントクラス化して使用します。 docs.aws.amazon.com
docker-compose.yml
# rubyを実行するコンテナに環境変数を追加 environment: OPENSEARCH_ENDPOINT: http://localstack:4566/my-custom-endpoint AWS_ACCESS_KEY_ID: dummy AWS_SECRET_ACCESS_KEY: dummy
クライアントクラス
require 'aws-sdk-opensearchservice' class OpenSearchClient def initialize end def request(http_method, api_path, document) uri = URI(endpoint + '/' + api_path) signature = generate_signature(http_method, api_path, document) http_client = Net::HTTP.new(uri.host, uri.port) http_client.use_ssl = Rails.env.production? http_client.start do |http| request = request_http_method(http_method, uri) request.body = document.to_json request['Host'] = signature.headers['host'] request['X-Amz-Date'] = signature.headers['x-amz-date'] request['X-Amz-Security-Token'] = signature.headers['x-amz-security-token'] request['X-Amz-Content-Sha256']= signature.headers['x-amz-content-sha256'] request['Authorization'] = signature.headers['authorization'] request['Content-Type'] = 'application/json' http.request(request) end end private def endpoint @endpoint ||= ENV['OPENSEARCH_ENDPOINT'] end def request_http_method(http_method, uri) case http_method when 'GET' Net::HTTP::Get.new(uri) when 'POST' Net::HTTP::Post.new(uri) when 'PUT' Net::HTTP::Put.new(uri) when 'DELETE' Net::HTTP::Delete.new(uri) end end def generate_signature(http_method, api_path, document) signer.sign_request( http_method: http_method, url: endpoint + '/' + api_path, body: document.to_json ) end def signer @signer ||= Aws::Sigv4::Signer.new( service: 'es', region: 'ap-northeast-1', access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], ) end end
インデックスの作成
document = { settings: { index: { analysis: { tokenizer: { kuromoji_tokenizer: { type: 'kuromoji_tokenizer' } }, analyzer: { analyzer: { type: 'custom', tokenizer: 'kuromoji_tokenizer' } } } } } } OpenSearchClient.new.request('PUT', 'sample-index', document) => "{\"acknowledged\":true,\"shards_acknowledged\":true,\"index\":\"sample-index\"}"