aliyun-opensearch-client 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.rubocop.yml +52 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +102 -0
- data/LICENSE.txt +21 -0
- data/README.md +60 -0
- data/Rakefile +8 -0
- data/aliyun-opensearch-client.gemspec +40 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/aliyun/opensearch/client.rb +77 -0
- data/lib/aliyun/opensearch/client_ext/management/.keep +0 -0
- data/lib/aliyun/opensearch/client_ext/traffic/behavior.rb +153 -0
- data/lib/aliyun/opensearch/client_ext/traffic/header/credentials.rb +82 -0
- data/lib/aliyun/opensearch/client_ext/traffic/header.rb +144 -0
- data/lib/aliyun/opensearch/client_ext/traffic.rb +6 -0
- data/lib/aliyun/opensearch/configuration.rb +29 -0
- data/lib/aliyun/opensearch/error.rb +99 -0
- data/lib/aliyun/opensearch/version.rb +7 -0
- data/lib/aliyun/opensearch.rb +22 -0
- metadata +156 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fecc8af0c41528c9deedd1a8164541e7dcf5391f99a21101a29c63ac8a75a06d
|
|
4
|
+
data.tar.gz: 16d08793ea28f0596062694fa89f534b2b04d193d26d75b8031bd622e27bc961
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d4595ccb2fa168a10055469017b5e1a260f7eb0e3300b5c8e8697d71343823fd81ffdf20fd7d34d1c12693d2c42e9ebe48f5f22bd1e29165bf870bd1f70bc7ed
|
|
7
|
+
data.tar.gz: 2b866f11590a288634ad4eec0b6d337433f68f3c4ea9e5296c540acc2211254ab02c218ed9598eb2f72f0d0bcbdfbc52b75ac44cc2c9280065ad0accdb0a029d
|
data/.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/.bundle/
|
|
2
|
+
/.yardoc
|
|
3
|
+
/_yardoc/
|
|
4
|
+
/coverage/
|
|
5
|
+
/doc/
|
|
6
|
+
/pkg/
|
|
7
|
+
/spec/reports/
|
|
8
|
+
/tmp/
|
|
9
|
+
|
|
10
|
+
# rspec failure tracking
|
|
11
|
+
.rspec_status
|
|
12
|
+
|
|
13
|
+
# ruby version
|
|
14
|
+
.ruby-gemset
|
|
15
|
+
.ruby-version
|
|
16
|
+
|
|
17
|
+
# test sample
|
|
18
|
+
bin/sample
|
|
19
|
+
|
|
20
|
+
# ignore generate gem
|
|
21
|
+
aliyun-openseach-client*.gem
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2022-06-29 03:29:43 UTC using RuboCop version 1.31.0.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 1
|
|
10
|
+
# Configuration parameters: Include.
|
|
11
|
+
# Include: **/*.gemspec
|
|
12
|
+
|
|
13
|
+
AllCops:
|
|
14
|
+
Exclude:
|
|
15
|
+
- 'spec/**/*'
|
|
16
|
+
NewCops: enable
|
|
17
|
+
SuggestExtensions: false
|
|
18
|
+
|
|
19
|
+
Gemspec/RequiredRubyVersion:
|
|
20
|
+
Include:
|
|
21
|
+
- 2.1.4
|
|
22
|
+
|
|
23
|
+
Layout/LineLength:
|
|
24
|
+
Max: 333
|
|
25
|
+
|
|
26
|
+
Metrics/AbcSize:
|
|
27
|
+
Enabled: true
|
|
28
|
+
Max: 50
|
|
29
|
+
|
|
30
|
+
Metrics/MethodLength:
|
|
31
|
+
Max: 50
|
|
32
|
+
|
|
33
|
+
Style/RedundantSelf:
|
|
34
|
+
Enabled: false
|
|
35
|
+
|
|
36
|
+
Style/RegexpLiteral:
|
|
37
|
+
Enabled: false
|
|
38
|
+
|
|
39
|
+
Style/TrailingCommaInHashLiteral:
|
|
40
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
41
|
+
|
|
42
|
+
Style/RedundantBegin:
|
|
43
|
+
Enabled: false
|
|
44
|
+
|
|
45
|
+
Style/AccessorGrouping:
|
|
46
|
+
Enabled: false
|
|
47
|
+
|
|
48
|
+
Style/SymbolArray:
|
|
49
|
+
Enabled: false
|
|
50
|
+
|
|
51
|
+
Style/FormatStringToken:
|
|
52
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
## Our Standards
|
|
13
|
+
|
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
|
15
|
+
include:
|
|
16
|
+
|
|
17
|
+
* Using welcoming and inclusive language
|
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
|
19
|
+
* Gracefully accepting constructive criticism
|
|
20
|
+
* Focusing on what is best for the community
|
|
21
|
+
* Showing empathy towards other community members
|
|
22
|
+
|
|
23
|
+
Examples of unacceptable behavior by participants include:
|
|
24
|
+
|
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
+
advances
|
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
+
* Public or private harassment
|
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
|
30
|
+
address, without explicit permission
|
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
+
professional setting
|
|
33
|
+
|
|
34
|
+
## Our Responsibilities
|
|
35
|
+
|
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
+
response to any instances of unacceptable behavior.
|
|
39
|
+
|
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
+
threatening, offensive, or harmful.
|
|
45
|
+
|
|
46
|
+
## Scope
|
|
47
|
+
|
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
+
when an individual is representing the project or its community. Examples of
|
|
50
|
+
representing a project or community include using an official project e-mail
|
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
|
53
|
+
further defined and clarified by project maintainers.
|
|
54
|
+
|
|
55
|
+
## Enforcement
|
|
56
|
+
|
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
+
reported by contacting the project team at shawn.han@rccchina.com. All
|
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
|
63
|
+
|
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
+
members of the project's leadership.
|
|
67
|
+
|
|
68
|
+
## Attribution
|
|
69
|
+
|
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
+
available at [https://contributor-covenant.org/version/1/4][version]
|
|
72
|
+
|
|
73
|
+
[homepage]: https://contributor-covenant.org
|
|
74
|
+
[version]: https://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
aliyun-opensearch-client (0.1.1)
|
|
5
|
+
faraday (>= 0.10.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
activesupport (6.1.6)
|
|
11
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
12
|
+
i18n (>= 1.6, < 2)
|
|
13
|
+
minitest (>= 5.1)
|
|
14
|
+
tzinfo (~> 2.0)
|
|
15
|
+
zeitwerk (~> 2.3)
|
|
16
|
+
addressable (2.8.0)
|
|
17
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
18
|
+
ast (2.4.2)
|
|
19
|
+
coderay (1.1.3)
|
|
20
|
+
concurrent-ruby (1.1.10)
|
|
21
|
+
crack (0.4.5)
|
|
22
|
+
rexml
|
|
23
|
+
diff-lcs (1.5.0)
|
|
24
|
+
docile (1.4.0)
|
|
25
|
+
faraday (2.3.0)
|
|
26
|
+
faraday-net_http (~> 2.0)
|
|
27
|
+
ruby2_keywords (>= 0.0.4)
|
|
28
|
+
faraday-net_http (2.0.3)
|
|
29
|
+
hashdiff (1.0.1)
|
|
30
|
+
i18n (1.10.0)
|
|
31
|
+
concurrent-ruby (~> 1.0)
|
|
32
|
+
method_source (1.0.0)
|
|
33
|
+
minitest (5.16.2)
|
|
34
|
+
parallel (1.22.1)
|
|
35
|
+
parser (3.1.2.0)
|
|
36
|
+
ast (~> 2.4.1)
|
|
37
|
+
pry (0.14.1)
|
|
38
|
+
coderay (~> 1.1)
|
|
39
|
+
method_source (~> 1.0)
|
|
40
|
+
public_suffix (4.0.7)
|
|
41
|
+
rainbow (3.1.1)
|
|
42
|
+
rake (12.3.3)
|
|
43
|
+
regexp_parser (2.1.1)
|
|
44
|
+
rexml (3.2.5)
|
|
45
|
+
ripper-tags (0.9.1)
|
|
46
|
+
rspec (3.11.0)
|
|
47
|
+
rspec-core (~> 3.11.0)
|
|
48
|
+
rspec-expectations (~> 3.11.0)
|
|
49
|
+
rspec-mocks (~> 3.11.0)
|
|
50
|
+
rspec-core (3.11.0)
|
|
51
|
+
rspec-support (~> 3.11.0)
|
|
52
|
+
rspec-expectations (3.11.0)
|
|
53
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
54
|
+
rspec-support (~> 3.11.0)
|
|
55
|
+
rspec-mocks (3.11.1)
|
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
57
|
+
rspec-support (~> 3.11.0)
|
|
58
|
+
rspec-support (3.11.0)
|
|
59
|
+
rubocop (1.31.0)
|
|
60
|
+
parallel (~> 1.10)
|
|
61
|
+
parser (>= 3.1.0.0)
|
|
62
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
63
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
64
|
+
rexml (>= 3.2.5, < 4.0)
|
|
65
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
|
66
|
+
ruby-progressbar (~> 1.7)
|
|
67
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
68
|
+
rubocop-ast (1.18.0)
|
|
69
|
+
parser (>= 3.1.1.0)
|
|
70
|
+
ruby-progressbar (1.11.0)
|
|
71
|
+
ruby2_keywords (0.0.5)
|
|
72
|
+
simplecov (0.21.2)
|
|
73
|
+
docile (~> 1.1)
|
|
74
|
+
simplecov-html (~> 0.11)
|
|
75
|
+
simplecov_json_formatter (~> 0.1)
|
|
76
|
+
simplecov-html (0.12.3)
|
|
77
|
+
simplecov_json_formatter (0.1.4)
|
|
78
|
+
tzinfo (2.0.4)
|
|
79
|
+
concurrent-ruby (~> 1.0)
|
|
80
|
+
unicode-display_width (2.0.0)
|
|
81
|
+
webmock (3.14.0)
|
|
82
|
+
addressable (>= 2.8.0)
|
|
83
|
+
crack (>= 0.3.2)
|
|
84
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
85
|
+
zeitwerk (2.6.0)
|
|
86
|
+
|
|
87
|
+
PLATFORMS
|
|
88
|
+
ruby
|
|
89
|
+
|
|
90
|
+
DEPENDENCIES
|
|
91
|
+
activesupport
|
|
92
|
+
aliyun-opensearch-client!
|
|
93
|
+
pry
|
|
94
|
+
rake (~> 12.0)
|
|
95
|
+
ripper-tags (~> 0.9.1)
|
|
96
|
+
rspec
|
|
97
|
+
rubocop
|
|
98
|
+
simplecov
|
|
99
|
+
webmock
|
|
100
|
+
|
|
101
|
+
BUNDLED WITH
|
|
102
|
+
2.1.4
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 shawn.han
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Aliyun::Opensearch::Client 🧯
|
|
2
|
+
|
|
3
|
+
本项目是阿里云Opensearch服务的ruby sdk, 定位类似[rsolr](https://github.com/rsolr/rsolr)之于solr
|
|
4
|
+
会根据[官方文档](https://help.aliyun.com/document_detail/54237.html)生成流量API的签名, 并发送请求
|
|
5
|
+
该gem最低支持的ruby版本为2.1.4
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
安装gem
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem install 'aliyun-opensearch-client'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
# 1. 添加配置
|
|
19
|
+
Aliyun::Opensearch::Configuration.endpoint = 'opensearch-cn-hangzhou.aliyuncs.com'
|
|
20
|
+
Aliyun::Opensearch::Configuration.access_key_id = 'A*****************z'
|
|
21
|
+
Aliyun::Opensearch::Configuration.access_key_secret = 'z*********************A'
|
|
22
|
+
|
|
23
|
+
# 2. 创建客户端实例
|
|
24
|
+
client = Aliyun::Opensearch::Client.new('your_app_name')
|
|
25
|
+
|
|
26
|
+
# 3. 发送请求
|
|
27
|
+
# 插入
|
|
28
|
+
puts client.insert('your_table', [ { id: 1, title: 'Cien años de soledad' }, { id: 2, title: 'Les Misérables' } ]) # true
|
|
29
|
+
puts client.insert('your_table', { id: 3, title: 'The Metamorphosis' }) # true
|
|
30
|
+
|
|
31
|
+
# 更新
|
|
32
|
+
puts client.update('your_table', [ { id: 1, title: 'Book - 百年孤独' }, { id: 2, title: 'Book - 悲惨世界' } ]) # true
|
|
33
|
+
puts client.update('your_table', { id: 3, title: 'Book - 变形记' }) # true
|
|
34
|
+
|
|
35
|
+
# 搜索
|
|
36
|
+
puts client.search({query: "query=default:'Book'"})
|
|
37
|
+
# {"searchtime"=>0.102566, "total"=>3, "num"=>3, "viewtotal"=>3, "compute_cost"=>[{"index_name"=>"your_app_name", "value"=>0.355}], "items"=>[{"id"=>"2", "index_name"=>"your_app_name"}, {"id"=>"1", "index_name"=>"your_app_name"}, {"id"=>"3", "index_name"=>"your_app_name"}], "facet"=>[]}
|
|
38
|
+
|
|
39
|
+
# 删除
|
|
40
|
+
puts client.delete('your_table', { id: 1 }) # true
|
|
41
|
+
puts client.delete('your_table', [{ id: 2 }, { id: 3 }]) # true
|
|
42
|
+
|
|
43
|
+
# 自定义接口请求
|
|
44
|
+
response = client.call(:get, '/v3/openapi/apps/your_app_name/suggest/your_suggest_name/search', { query: '...' })
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Feature
|
|
48
|
+
- 流量API签名认证
|
|
49
|
+
- 封装流量API的 数据处理 / 搜索处理 接口
|
|
50
|
+
- 兼容请求未封装的流量API接口
|
|
51
|
+
|
|
52
|
+
## RoadMap
|
|
53
|
+
- request日志追踪
|
|
54
|
+
- 支持流量API的 推送采集数据 / 下拉提示 / 热搜和底纹 接口
|
|
55
|
+
- 支持管控API (可以临时用Aliyun官方的OpenAPI解决问题)
|
|
56
|
+
- 支持STS认证
|
|
57
|
+
|
|
58
|
+
## 开源协议
|
|
59
|
+
|
|
60
|
+
[MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/aliyun/opensearch/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'aliyun-opensearch-client'
|
|
7
|
+
spec.version = Aliyun::Opensearch::VERSION
|
|
8
|
+
spec.authors = ['shawn.han']
|
|
9
|
+
spec.email = ['shawn.han@rccchina.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Aliyun Opensearch 服务客户端'
|
|
12
|
+
spec.description = '对接Aliyun Opensearch 的流量API HTTP接口, 生成签名并发送请求'
|
|
13
|
+
spec.homepage = 'https://github.com/rccgroup/aliyun-opensearch-client'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.1.4')
|
|
16
|
+
|
|
17
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
|
18
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
19
|
+
|
|
20
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
21
|
+
spec.metadata['source_code_uri'] = 'https://github.com/rccgroup/aliyun-opensearch-client'
|
|
22
|
+
spec.metadata['changelog_uri'] = 'https://github.com/rccgroup/aliyun-opensearch-client/blob/master/CHANGELOG.md'
|
|
23
|
+
|
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
26
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
27
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
28
|
+
end
|
|
29
|
+
spec.bindir = 'exe'
|
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
31
|
+
spec.require_paths = ['lib']
|
|
32
|
+
|
|
33
|
+
spec.add_dependency 'faraday', '>= 0.10.0'
|
|
34
|
+
|
|
35
|
+
spec.add_development_dependency 'activesupport'
|
|
36
|
+
spec.add_development_dependency 'rspec'
|
|
37
|
+
spec.add_development_dependency 'rubocop'
|
|
38
|
+
spec.add_development_dependency 'simplecov'
|
|
39
|
+
spec.add_development_dependency 'webmock'
|
|
40
|
+
end
|
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'aliyun/opensearch'
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require 'irb'
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# require client_ext folder ruby file
|
|
4
|
+
%w[traffic].each do |file|
|
|
5
|
+
require File.join(File.dirname(__FILE__), 'client_ext', file)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module Aliyun
|
|
9
|
+
module Opensearch
|
|
10
|
+
#
|
|
11
|
+
# Opensearch客户端
|
|
12
|
+
#
|
|
13
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
14
|
+
#
|
|
15
|
+
class Client
|
|
16
|
+
include ClientExt::Traffic::Behavior
|
|
17
|
+
|
|
18
|
+
# 允许请求的action
|
|
19
|
+
REQUEST_METHODS = [:get, :post].freeze
|
|
20
|
+
|
|
21
|
+
# 应用名称
|
|
22
|
+
attr_reader :app
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# 客户端初始化
|
|
26
|
+
#
|
|
27
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
28
|
+
#
|
|
29
|
+
# @param [String] app 应用名称, 即要访问的Opensearch应用的名称, 在实例管理里可以看到
|
|
30
|
+
#
|
|
31
|
+
def initialize(app)
|
|
32
|
+
@app = app
|
|
33
|
+
@connection = Faraday.new(url: Configuration.opensearch_url) do |faraday|
|
|
34
|
+
faraday.response :raise_error
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# 发送请求
|
|
40
|
+
#
|
|
41
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
42
|
+
#
|
|
43
|
+
# @param [String|Symbol] method 接口请求方法
|
|
44
|
+
# @param [String] path 接口地址
|
|
45
|
+
# @param [Hash] params 接口参数
|
|
46
|
+
#
|
|
47
|
+
# @return [Hash] 请求结果
|
|
48
|
+
#
|
|
49
|
+
def call(method, path, params)
|
|
50
|
+
raise ArgumentError, "Not Allow Request Method #{method}; Only Allowed #{REQUEST_METHODS}" unless REQUEST_METHODS.map { |e| [e, e.to_s, e.to_s.upcase] }.flatten.include?(method)
|
|
51
|
+
|
|
52
|
+
response = @connection.send(method.downcase, path, params) do |request|
|
|
53
|
+
api_params = (request.http_method == :get ? request.params : request.body)
|
|
54
|
+
request.headers = ClientExt::Traffic::Header.new(request.http_method, request.path, api_params: api_params).generate
|
|
55
|
+
end
|
|
56
|
+
body = response.body.empty? ? {} : JSON.parse(response.body)
|
|
57
|
+
|
|
58
|
+
valid_response(response, body)
|
|
59
|
+
body
|
|
60
|
+
rescue Error::AliyunService, Error::InvalidResponseBody => e
|
|
61
|
+
raise e
|
|
62
|
+
rescue Faraday::Error => e
|
|
63
|
+
raise Error::HttpBase, e
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# 返回结果校验
|
|
68
|
+
#
|
|
69
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
70
|
+
#
|
|
71
|
+
def valid_response(response, body)
|
|
72
|
+
raise Error::InvalidResponseBody, response if body.empty? || !body.keys.include?('status')
|
|
73
|
+
raise Error::AliyunService, response if body['status'] != 'OK'
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aliyun
|
|
4
|
+
module Opensearch
|
|
5
|
+
module ClientExt
|
|
6
|
+
module Traffic
|
|
7
|
+
#
|
|
8
|
+
# 各种接口行为
|
|
9
|
+
#
|
|
10
|
+
# @author shawn.han <shwan.han@rccchina.com>
|
|
11
|
+
#
|
|
12
|
+
module Behavior
|
|
13
|
+
API_SEARCH = '/v3/openapi/apps/%{app_name}/search'
|
|
14
|
+
API_ACTION = '/v3/openapi/apps/%{app_name}/%{table_name}/actions/bulk'
|
|
15
|
+
|
|
16
|
+
ACTION_CMD_KEY = 'cmd'
|
|
17
|
+
ACTION_CMD_INSERT = 'add'
|
|
18
|
+
ACTION_CMD_UPDATE = 'update'
|
|
19
|
+
ACTION_CMD_DELETE = 'delete'
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# 搜索接口
|
|
23
|
+
#
|
|
24
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
25
|
+
#
|
|
26
|
+
# @param [Hash] params 参数
|
|
27
|
+
# @see https://help.aliyun.com/document_detail/57155.html
|
|
28
|
+
#
|
|
29
|
+
# @return [Hash] 查询结果
|
|
30
|
+
#
|
|
31
|
+
def search(params)
|
|
32
|
+
raise Error::EmptyParam if params.nil? || params.empty?
|
|
33
|
+
|
|
34
|
+
self.call(:get, complete_path(API_SEARCH), params)['result']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# 插入操作
|
|
39
|
+
#
|
|
40
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
41
|
+
#
|
|
42
|
+
# @param [String] table_name 操作对象的表名
|
|
43
|
+
# @param [Hash] params 参数
|
|
44
|
+
# @see https://help.aliyun.com/document_detail/57154.html
|
|
45
|
+
#
|
|
46
|
+
# @return [Boolean] 处理结果
|
|
47
|
+
#
|
|
48
|
+
def insert(table_name, params)
|
|
49
|
+
action(table_name, ACTION_CMD_INSERT, params)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# 更新操作
|
|
54
|
+
#
|
|
55
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
56
|
+
#
|
|
57
|
+
# @param [String] table_name 操作对象的表名
|
|
58
|
+
# @param [Hash] params 参数
|
|
59
|
+
# @see https://help.aliyun.com/document_detail/57154.html
|
|
60
|
+
#
|
|
61
|
+
# @return [Boolean] 处理结果
|
|
62
|
+
#
|
|
63
|
+
def update(table_name, params)
|
|
64
|
+
action(table_name, ACTION_CMD_UPDATE, params)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# 删除操作
|
|
69
|
+
#
|
|
70
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
71
|
+
#
|
|
72
|
+
# @param [String] table_name 操作对象的表名
|
|
73
|
+
# @param [Hash] params 参数
|
|
74
|
+
# @see https://help.aliyun.com/document_detail/57154.html
|
|
75
|
+
#
|
|
76
|
+
# @return [Boolean] 处理结果
|
|
77
|
+
#
|
|
78
|
+
def delete(table_name, params)
|
|
79
|
+
action(table_name, ACTION_CMD_DELETE, params)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# 操作接口
|
|
84
|
+
# @note 操作接口的几个注意点(此为Aliyun Opensearch服务内部的处理)
|
|
85
|
+
# 1. add操作时, 如果数据已经存在, 会直接更新这条数据, 也不会报错
|
|
86
|
+
# 2. update操作时, 如果数据不存在, 不会直接新建数据, 也不会报错
|
|
87
|
+
# 3. delete操作时, 如果数据不存在, 不会进行操作, 也不会报错
|
|
88
|
+
#
|
|
89
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
90
|
+
#
|
|
91
|
+
# @param [String] table_name 操作对象的表名
|
|
92
|
+
# @param [String] action 操作类型
|
|
93
|
+
# @param [Array|Hash] params 参数
|
|
94
|
+
#
|
|
95
|
+
# @return [Boolean] 处理结果
|
|
96
|
+
#
|
|
97
|
+
def action(table_name, action, params)
|
|
98
|
+
raise Error::EmptyParam if params.nil? || params.empty?
|
|
99
|
+
|
|
100
|
+
self.call(:post, complete_path(API_ACTION, table_name: table_name), JSON.generate(complete_action_params(params, action)))['result']
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
#
|
|
106
|
+
# 返回完整的接口路径
|
|
107
|
+
#
|
|
108
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
109
|
+
#
|
|
110
|
+
# @param [String] path 接口路径
|
|
111
|
+
# @param [String] table_name 表名
|
|
112
|
+
#
|
|
113
|
+
# @return [String] 完整的接口路径
|
|
114
|
+
#
|
|
115
|
+
def complete_path(path, table_name: nil)
|
|
116
|
+
options = { app_name: self.app }
|
|
117
|
+
options.merge!(table_name: table_name) unless table_name.nil?
|
|
118
|
+
|
|
119
|
+
format(path, options)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# 返回完整的参数
|
|
124
|
+
#
|
|
125
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
126
|
+
#
|
|
127
|
+
# @param [Array|Hash] params 参数
|
|
128
|
+
# @param [String] action 操作类型
|
|
129
|
+
#
|
|
130
|
+
# @return [Array<Hash>] 完整的参数
|
|
131
|
+
#
|
|
132
|
+
def complete_action_params(params, action)
|
|
133
|
+
# 判断是否需要补充fields字段
|
|
134
|
+
need_cmplete_fields_key = proc { |param| (['fields', :fields] & param.keys).empty? || (!param['fields'].is_a?(Hash) && !param[:fields].is_a?(Hash)) }
|
|
135
|
+
|
|
136
|
+
# 添加操作类型
|
|
137
|
+
if params.is_a?(Array)
|
|
138
|
+
params = params.map do |e|
|
|
139
|
+
e = { 'fields' => e } if need_cmplete_fields_key.call(e)
|
|
140
|
+
e.merge(ACTION_CMD_KEY => action)
|
|
141
|
+
end
|
|
142
|
+
else
|
|
143
|
+
params = { 'fields' => params } if need_cmplete_fields_key.call(params)
|
|
144
|
+
params = [params.merge(ACTION_CMD_KEY => action)]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
params
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aliyun
|
|
4
|
+
module Opensearch
|
|
5
|
+
module ClientExt
|
|
6
|
+
module Traffic
|
|
7
|
+
class Header
|
|
8
|
+
#
|
|
9
|
+
# HTTP请求header - 请求认证模块
|
|
10
|
+
#
|
|
11
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
12
|
+
#
|
|
13
|
+
module Credentials
|
|
14
|
+
SIGN_PREFIX = 'OPENSEARCH'
|
|
15
|
+
|
|
16
|
+
def authorization
|
|
17
|
+
"#{SIGN_PREFIX} #{@access_key_id}:#{signature}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def signature
|
|
21
|
+
@signature ||= begin
|
|
22
|
+
sign_body = [@request_method, self.content_md5, self.content_type, self.date, canonicalized_open_search_headers, canonicalized_resource].join("\n")
|
|
23
|
+
|
|
24
|
+
Base64.encode64(
|
|
25
|
+
OpenSSL::HMAC.digest(
|
|
26
|
+
OpenSSL::Digest.new('sha1'),
|
|
27
|
+
@access_key_secret,
|
|
28
|
+
sign_body
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# 生成 CanonicalizedOpenSearchHeaders
|
|
36
|
+
#
|
|
37
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
38
|
+
#
|
|
39
|
+
# @see https://help.aliyun.com/document_detail/54237.html#section-92h-jsb-rlu
|
|
40
|
+
#
|
|
41
|
+
# @return [String] CanonicalizedOpenSearchHeaders
|
|
42
|
+
#
|
|
43
|
+
def canonicalized_open_search_headers
|
|
44
|
+
@canonicalized_open_search_headers ||= self.x_opensearch_headers.to_a.sort { |x, y| x[0] <=> y[0] }.map do |e|
|
|
45
|
+
"#{e[0].downcase}:#{e[1]}"
|
|
46
|
+
end.join("\n")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# 生成 CanonicalizedResource
|
|
51
|
+
#
|
|
52
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
53
|
+
#
|
|
54
|
+
# @see https://help.aliyun.com/document_detail/54237.htm
|
|
55
|
+
#
|
|
56
|
+
# @return [String] CanonicalizedResource
|
|
57
|
+
#
|
|
58
|
+
def canonicalized_resource
|
|
59
|
+
path = @path
|
|
60
|
+
query = nil
|
|
61
|
+
|
|
62
|
+
if @request_method == 'GET'
|
|
63
|
+
# 按照阿里云文档生成query, see: https://help.aliyun.com/document_detail/54237.htm#section-ni9-hgi-tal
|
|
64
|
+
query = @api_params.to_a.sort { |x, y| x[0] <=> y[0] }.map do |e|
|
|
65
|
+
unless e[1].nil?
|
|
66
|
+
[e[0], (e[1].to_s == '' ? nil : e[1].to_s)]
|
|
67
|
+
end
|
|
68
|
+
end.compact
|
|
69
|
+
|
|
70
|
+
# encode_www_form方法文档中描述一些字符不会转移, 这里手动进行处理
|
|
71
|
+
# This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP (ASCII space) to + and converts others to %XX.
|
|
72
|
+
query = URI.encode_www_form(query).gsub('+', '%20').gsub('*', '%2A')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
[path, query].compact.reject(&:empty?).join('?')
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# require header folder ruby file
|
|
4
|
+
%w[credentials].each do |file|
|
|
5
|
+
require File.join(File.dirname(__FILE__), 'header', file)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module Aliyun
|
|
9
|
+
module Opensearch
|
|
10
|
+
module ClientExt
|
|
11
|
+
module Traffic
|
|
12
|
+
#
|
|
13
|
+
# 流量API HTTP请求header
|
|
14
|
+
#
|
|
15
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
16
|
+
#
|
|
17
|
+
class Header
|
|
18
|
+
# 默认 conten-type
|
|
19
|
+
DEFAULT_CONTENT_TYPE = 'application/json'
|
|
20
|
+
# 默认 user-agent, 内容参考阿里云官方openapi sdk: https://github.com/aliyun/openapi-core-ruby-sdk/blob/master/lib/aliyunsdkcore.rb
|
|
21
|
+
DEFAULT_UA = "AlibabaCloud (#{Gem::Platform.local.os}; #{Gem::Platform.local.cpu}) Ruby/#{RUBY_VERSION} Core/ALiyunOpensearchClient-#{Aliyun::Opensearch::VERSION}"
|
|
22
|
+
|
|
23
|
+
# nonce后缀最小长度
|
|
24
|
+
NONCE_SUFFIX_MIN = 100_000
|
|
25
|
+
# nonce后缀最大长度
|
|
26
|
+
NONCE_SUFFIX_MAX = 999_999
|
|
27
|
+
|
|
28
|
+
include Credentials # 签名认证模块
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# 创建实例
|
|
32
|
+
#
|
|
33
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
34
|
+
#
|
|
35
|
+
# @param [String] request_method 接口请求方法(GET POST...)
|
|
36
|
+
# @param [String] path 请求资源路径
|
|
37
|
+
# @param [Hash] api_params 请求接口参数
|
|
38
|
+
# @param [String] access_key_id 阿里云 AccessKeyId
|
|
39
|
+
# @param [String] access_key_secret 阿里云 AccessKeySecret
|
|
40
|
+
#
|
|
41
|
+
def initialize(request_method, path, api_params: nil, access_key_id: nil, access_key_secret: nil)
|
|
42
|
+
@request_method = request_method.to_s.upcase
|
|
43
|
+
@path = path
|
|
44
|
+
|
|
45
|
+
@api_params = api_params
|
|
46
|
+
|
|
47
|
+
@access_key_id = access_key_id || Configuration.access_key_id
|
|
48
|
+
@access_key_secret = access_key_secret || Configuration.access_key_secret
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# 生成Header的Hash结构
|
|
53
|
+
#
|
|
54
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
55
|
+
#
|
|
56
|
+
# @return [Hash] 请求用到的所有Header内容
|
|
57
|
+
#
|
|
58
|
+
def generate
|
|
59
|
+
result = {
|
|
60
|
+
'User-Agent' => DEFAULT_UA,
|
|
61
|
+
'Content-Type' => content_type,
|
|
62
|
+
'Date' => date,
|
|
63
|
+
}.merge(x_opensearch_headers)
|
|
64
|
+
result.merge!('Content-Md5' => content_md5) if content_md5
|
|
65
|
+
result.merge!('Authorization' => authorization)
|
|
66
|
+
result
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# 以X-Opensearch开头的header
|
|
71
|
+
#
|
|
72
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
73
|
+
#
|
|
74
|
+
# @return [Hash] 以X-Opensearch开头的header
|
|
75
|
+
#
|
|
76
|
+
def x_opensearch_headers
|
|
77
|
+
{
|
|
78
|
+
'X-Opensearch-Nonce' => x_opensearch_nonce,
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# hearder中 Content-Type的值
|
|
84
|
+
#
|
|
85
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
86
|
+
#
|
|
87
|
+
# @return [String] Content-Type的值
|
|
88
|
+
#
|
|
89
|
+
def content_type
|
|
90
|
+
@content_type ||= DEFAULT_CONTENT_TYPE
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# 生成 header中 X-Opensearch-Nonce的值
|
|
95
|
+
#
|
|
96
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
97
|
+
#
|
|
98
|
+
# @see https://help.aliyun.com/document_detail/54237.html#section-92h-jsb-rlu
|
|
99
|
+
#
|
|
100
|
+
# @return [String] X-Opensearch-Nonce的值
|
|
101
|
+
#
|
|
102
|
+
def x_opensearch_nonce
|
|
103
|
+
@x_opensearch_nonce ||= "#{time_now.to_i}#{rand(NONCE_SUFFIX_MIN..NONCE_SUFFIX_MAX)}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# 生成 header中 Date的值
|
|
108
|
+
#
|
|
109
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
110
|
+
#
|
|
111
|
+
# @return [String] Date的值
|
|
112
|
+
#
|
|
113
|
+
def date
|
|
114
|
+
@date ||= time_now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# 生成 header中 Content-MD5的值
|
|
119
|
+
#
|
|
120
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
121
|
+
#
|
|
122
|
+
# @return [String] Content-MD5的值
|
|
123
|
+
#
|
|
124
|
+
def content_md5
|
|
125
|
+
Digest::MD5.hexdigest(@api_params.to_json) if @request_method == 'POST' && @api_params
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
#
|
|
131
|
+
# 当前时间
|
|
132
|
+
#
|
|
133
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
134
|
+
#
|
|
135
|
+
# @return [Time] 当前时间
|
|
136
|
+
#
|
|
137
|
+
def time_now
|
|
138
|
+
@time_now ||= Time.now
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aliyun
|
|
4
|
+
module Opensearch
|
|
5
|
+
#
|
|
6
|
+
# 服务配置
|
|
7
|
+
#
|
|
8
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
9
|
+
#
|
|
10
|
+
class Configuration
|
|
11
|
+
class << self
|
|
12
|
+
attr_accessor :endpoint # Opensearch服务地址
|
|
13
|
+
attr_accessor :access_key_id # 阿里云申请的ak
|
|
14
|
+
attr_accessor :access_key_secret # 阿里云申请的ak secret
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# 根据设置的endpoint获取服务的url, 如果没有协议头默认设置为https
|
|
18
|
+
#
|
|
19
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
20
|
+
#
|
|
21
|
+
# @return [String] 服务url
|
|
22
|
+
#
|
|
23
|
+
def opensearch_url
|
|
24
|
+
endpoint =~ /^https?:\/\// ? endpoint : "https://#{endpoint}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aliyun
|
|
4
|
+
module Opensearch
|
|
5
|
+
#
|
|
6
|
+
# 异常模块
|
|
7
|
+
#
|
|
8
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
9
|
+
#
|
|
10
|
+
module Error
|
|
11
|
+
#
|
|
12
|
+
# 请求异常基类
|
|
13
|
+
#
|
|
14
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
15
|
+
#
|
|
16
|
+
class HttpBase < Faraday::Error
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# 阿里云异常基类
|
|
21
|
+
#
|
|
22
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
23
|
+
#
|
|
24
|
+
class AliyunService < HttpBase
|
|
25
|
+
ERRCODE_ALIYUN_SYS = (1000..1999).freeze # 系统级别(1000-1999)
|
|
26
|
+
ERRCODE_ALIYUN_APP = (2000..2999).freeze # 应用相关(2000-2999)
|
|
27
|
+
ERRCODE_ALIYUN_DOC = (3000..3999).freeze # 文档相关(3000-3999)
|
|
28
|
+
ERRCODE_ALIYUN_AUTH = (4000..4999).freeze # 授权相关(4000-4999)
|
|
29
|
+
ERRCODE_ALIYUN_USER = (5000..5999).freeze # 用户相关(5000-5999)
|
|
30
|
+
ERRCODE_ALIYUN_SEARCH = (6000..6999).freeze # 搜索相关(6000-6999)
|
|
31
|
+
ERRCODE_ALIYUN_CMD = (7000..7999).freeze # 数据处理相关(7000-7999)
|
|
32
|
+
ERRCODE_ALIYUN_COMMON = (8000..8999).freeze # 文档错误内部通知(8000-8999)
|
|
33
|
+
ERRCODE_ALIYUN_TEMPLETE = (9000..9999).freeze # 模板相关(9000-9999)
|
|
34
|
+
ERRCODE_ALIYUN_SYNC = (10_000..).freeze # 数据同步相关(10000-)
|
|
35
|
+
|
|
36
|
+
attr_reader :response
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# 初始化
|
|
40
|
+
#
|
|
41
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
42
|
+
#
|
|
43
|
+
# @param [Faraday::Response] response 接口返回结果
|
|
44
|
+
#
|
|
45
|
+
def initialize(response)
|
|
46
|
+
@response = response
|
|
47
|
+
@body = JSON.parse(response.body)
|
|
48
|
+
|
|
49
|
+
super("RequestId:#{@body['request_id']} Message:#{errors_message}", response)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# 获取错误信息
|
|
54
|
+
#
|
|
55
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
56
|
+
#
|
|
57
|
+
# @return [String] 错误消息
|
|
58
|
+
#
|
|
59
|
+
def errors_message
|
|
60
|
+
@body['errors'].map do |error|
|
|
61
|
+
"[#{error['code']}] #{error['message']}"
|
|
62
|
+
end.join("\n")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# 空参数异常
|
|
68
|
+
#
|
|
69
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
70
|
+
#
|
|
71
|
+
class EmptyParam < ArgumentError
|
|
72
|
+
#
|
|
73
|
+
# 初始化
|
|
74
|
+
#
|
|
75
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
76
|
+
#
|
|
77
|
+
def initialize
|
|
78
|
+
super('Param Can Not Be Empty')
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# 无效返回结果异常
|
|
84
|
+
#
|
|
85
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
86
|
+
#
|
|
87
|
+
class InvalidResponseBody < HttpBase
|
|
88
|
+
#
|
|
89
|
+
# 初始化
|
|
90
|
+
#
|
|
91
|
+
# @author shawn.han <shawn.han@rccchina.com>
|
|
92
|
+
#
|
|
93
|
+
def initialize(response)
|
|
94
|
+
super('Response Body is Invalid', response)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'digest'
|
|
5
|
+
require 'faraday'
|
|
6
|
+
require 'json'
|
|
7
|
+
require 'openssl'
|
|
8
|
+
|
|
9
|
+
require 'aliyun/opensearch/client'
|
|
10
|
+
require 'aliyun/opensearch/configuration'
|
|
11
|
+
require 'aliyun/opensearch/error'
|
|
12
|
+
require 'aliyun/opensearch/version'
|
|
13
|
+
|
|
14
|
+
module Aliyun
|
|
15
|
+
#
|
|
16
|
+
# Aliyun Opensearch SDK
|
|
17
|
+
#
|
|
18
|
+
# @author shawn.han <shawn.han@rccchina.coms>
|
|
19
|
+
#
|
|
20
|
+
module Opensearch
|
|
21
|
+
end
|
|
22
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: aliyun-opensearch-client
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- shawn.han
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2022-07-15 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.10.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.10.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activesupport
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubocop
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: simplecov
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: webmock
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description: 对接Aliyun Opensearch 的流量API HTTP接口, 生成签名并发送请求
|
|
98
|
+
email:
|
|
99
|
+
- shawn.han@rccchina.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".gitignore"
|
|
105
|
+
- ".rspec"
|
|
106
|
+
- ".rubocop.yml"
|
|
107
|
+
- ".travis.yml"
|
|
108
|
+
- CHANGELOG.md
|
|
109
|
+
- CODE_OF_CONDUCT.md
|
|
110
|
+
- Gemfile
|
|
111
|
+
- Gemfile.lock
|
|
112
|
+
- LICENSE.txt
|
|
113
|
+
- README.md
|
|
114
|
+
- Rakefile
|
|
115
|
+
- aliyun-opensearch-client.gemspec
|
|
116
|
+
- bin/console
|
|
117
|
+
- bin/setup
|
|
118
|
+
- lib/aliyun/opensearch.rb
|
|
119
|
+
- lib/aliyun/opensearch/client.rb
|
|
120
|
+
- lib/aliyun/opensearch/client_ext/management/.keep
|
|
121
|
+
- lib/aliyun/opensearch/client_ext/traffic.rb
|
|
122
|
+
- lib/aliyun/opensearch/client_ext/traffic/behavior.rb
|
|
123
|
+
- lib/aliyun/opensearch/client_ext/traffic/header.rb
|
|
124
|
+
- lib/aliyun/opensearch/client_ext/traffic/header/credentials.rb
|
|
125
|
+
- lib/aliyun/opensearch/configuration.rb
|
|
126
|
+
- lib/aliyun/opensearch/error.rb
|
|
127
|
+
- lib/aliyun/opensearch/version.rb
|
|
128
|
+
homepage: https://github.com/rccgroup/aliyun-opensearch-client
|
|
129
|
+
licenses:
|
|
130
|
+
- MIT
|
|
131
|
+
metadata:
|
|
132
|
+
allowed_push_host: https://rubygems.org/
|
|
133
|
+
rubygems_mfa_required: 'true'
|
|
134
|
+
homepage_uri: https://github.com/rccgroup/aliyun-opensearch-client
|
|
135
|
+
source_code_uri: https://github.com/rccgroup/aliyun-opensearch-client
|
|
136
|
+
changelog_uri: https://github.com/rccgroup/aliyun-opensearch-client/blob/master/CHANGELOG.md
|
|
137
|
+
post_install_message:
|
|
138
|
+
rdoc_options: []
|
|
139
|
+
require_paths:
|
|
140
|
+
- lib
|
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: 2.1.4
|
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '0'
|
|
151
|
+
requirements: []
|
|
152
|
+
rubygems_version: 3.1.6
|
|
153
|
+
signing_key:
|
|
154
|
+
specification_version: 4
|
|
155
|
+
summary: Aliyun Opensearch 服务客户端
|
|
156
|
+
test_files: []
|