Class: Etre::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/etre-client/client.rb,
lib/etre-client/errors.rb,
lib/etre-client/version.rb

Defined Under Namespace

Classes: EntityIdSet, EntityNotProvided, EntityTypeMismatch, IdNotProvided, LabelNotSet, PatchIdSet, PatchNotProvided, QueryNotProvided, RequestFailed, UnexpectedResponseCode

Constant Summary collapse

API_ROOT =
"/api/v1"
META_LABEL_ID =
"_id"
META_LABEL_TYPE =
"_type"
VERSION =
"0.8.6"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(entity_type:, url:, query_timeout: '5s', retry_count: 0, retry_wait: 1, options: {}) ⇒ Client

Returns a new instance of Client.



14
15
16
17
18
19
20
21
22
23
# File 'lib/etre-client/client.rb', line 14

def initialize(entity_type:, url:, query_timeout: '5s', retry_count: 0, retry_wait: 1, options: {})
  @entity_type = entity_type
  @url = url
  @query_timeout = query_timeout # http request timeout in seconds
  @retry_count = retry_count # retry count on network or API error
  @retry_wait = retry_wait # wait time between retries in seconds
  @options = options

  @logger = Logger.new(STDOUT)
end

Instance Attribute Details

#entity_typeObject (readonly)

Returns the value of attribute entity_type.



8
9
10
# File 'lib/etre-client/client.rb', line 8

def entity_type
  @entity_type
end

#urlObject (readonly)

Returns the value of attribute url.



8
9
10
# File 'lib/etre-client/client.rb', line 8

def url
  @url
end

Instance Method Details

#delete(query) ⇒ Object

delete deletes the entities that satisfy the given query.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/etre-client/client.rb', line 160

def delete(query)
  if query.nil? || query.empty?
    raise QueryNotProvided
  end

  # Always escape the query.
  query = CGI::escape(query)

  begin
    resp = etre_delete("/entities/#{@entity_type}?query=#{query}")
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if resp.code != 200
    raise UnexpectedResponseCode, "expected 200, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#delete_label(id, label) ⇒ Object

delete_label deletes the given label on the provided entity id.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/etre-client/client.rb', line 220

def delete_label(id, label)
  if id.nil? || id.empty?
    raise IdNotProvided
  end

  if label.nil? || label.empty?
    raise LabelNotSet
  end

  begin
    resp = etre_delete("/entity/#{@entity_type}/#{id}/labels/#{label}")
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if resp.code != 200
    raise UnexpectedResponseCode, "expected 200, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#delete_one(id) ⇒ Object

delete_one deletes the entity with the given id.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/etre-client/client.rb', line 182

def delete_one(id)
  if id.nil? || id.empty?
    raise IdNotProvided
  end

  begin
    resp = etre_delete("/entity/#{@entity_type}/#{id}")
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if resp.code != 200
    raise UnexpectedResponseCode, "expected 200, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#insert(entities) ⇒ Object

insert inserts an array of entities.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/etre-client/client.rb', line 63

def insert(entities)
  if entities.nil? || !entities.any?
    raise EntityNotProvided
  end

  entities.each do |e|
    if e.key?(META_LABEL_ID)
      raise EntityIdSet, "entity: #{e}"
    end

    if e.key?(META_LABEL_TYPE) && e[META_LABEL_TYPE] != @entity_type
      raise EntityTypeMismatch, "only valid type is '#{@entity_type}', but " +
        "entity has type '#{e[META_LABEL_TYPE]}'"
    end
  end

  begin
    resp = etre_post("/entities/#{@entity_type}", entities)
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if ![200, 201].include?(resp.code)
    raise UnexpectedResponseCode, "expected 200 or 201, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#labels(id) ⇒ Object

labels returns an array of labels for the given entity id.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/etre-client/client.rb', line 201

def labels(id)
  if id.nil? || id.empty?
    raise IdNotProvided
  end

  begin
    resp = etre_get("/entity/#{@entity_type}/#{id}/labels")
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if resp.code != 200
    raise UnexpectedResponseCode, "expected 200, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#query(query, filter = nil) ⇒ Object

query returns an array of entities that satisfy a query.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/etre-client/client.rb', line 26

def query(query, filter = nil)
  if query.nil? || query.empty?
    raise QueryNotProvided
  end

  # @todo: translate filter to query params

  # Do the normal GET /entities?query unless the query is ~2k characters
  # becuase that brings the entire URL length close to the max supported
  # limit across most HTTP servers. In that case, switch to alternate
  # endpoint to POST the long query.
  if query.length < 2000
    # Always escape the query.
    query = CGI::escape(query)

    begin
      resp = etre_get("/entities/#{@entity_type}?query=#{query}")
    rescue RestClient::ExceptionWithResponse => e
      raise RequestFailed, e.response
    end
  else
    # DO NOT ESCAPE THE QUERY! It's not sent via URL, so no escaping needed.
    begin
      resp = etre_post("/query/#{@entity_type}", query)
    rescue RestClient::ExceptionWithResponse => e
      raise RequestFailed, e.response
    end
  end

  if resp.code != 200
    raise UnexpectedResponseCode, "expected 200, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#update(query, patch) ⇒ Object

update updates entities with the given patch that satisfy the given query.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/etre-client/client.rb', line 93

def update(query, patch)
  if query.nil? || query.empty?
    raise QueryNotProvided
  end

  # Always escape the query.
  query = CGI::escape(query)

  if patch.nil? || !patch.any?
    raise PatchNotProvided
  end

  if patch.key?(META_LABEL_ID)
    raise PatchIdSet, "patch: #{patch}"
  end

  if patch.key?(META_LABEL_TYPE) && patch[META_LABEL_TYPE] != @entity_type
    raise EntityTypeMismatch, "only valid type is '#{@entity_type}', but " +
      "patch has type '#{patch[META_LABEL_TYPE]}'"
  end

  begin
    resp = etre_put("/entities/#{@entity_type}?query=#{query}", patch)
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if ![200, 201].include?(resp.code)
    raise UnexpectedResponseCode, "expected 200 or 201, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end

#update_one(id, patch) ⇒ Object

update_one updates the given entity id with the provided patch.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/etre-client/client.rb', line 128

def update_one(id, patch)
  if id.nil? || id.empty?
    raise IdNotProvided
  end

  if patch.nil? || !patch.any?
    raise PatchNotProvided
  end

  if patch.key?(META_LABEL_ID)
    raise PatchIdSet, "patch: #{patch}"
  end

  if patch.key?(META_LABEL_TYPE) && patch[META_LABEL_TYPE] != @entity_type
    raise EntityTypeMismatch, "only valid type is '#{@entity_type}', but " +
      "patch has type '#{patch[META_LABEL_TYPE]}'"
  end

  begin
    resp = etre_put("/entity/#{@entity_type}/#{id}", patch)
  rescue RestClient::ExceptionWithResponse => e
    raise RequestFailed, e.response
  end

  if ![200, 201].include?(resp.code)
    raise UnexpectedResponseCode, "expected 200 or 201, got #{resp.code}"
  end

  return JSON.parse(resp.body)
end