meshx-plugin-sdk 0.0.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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/sdk.rb +363 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9cafe1eb2bf825349ca1f92b832762ada2f7b8b0d6b28a667f5289705424670e
4
+ data.tar.gz: 50379ac299320c243787b63d10fa468161e93ba1c22b0b17f0bb408fd1e105eb
5
+ SHA512:
6
+ metadata.gz: 454eff71a88b624b3f368c45a2f0a22a5cf2c85faa0614ba3269ff04ef15ae504915c20111766e62e3d5c46ee94170992e812db6355d276caf25d209c73ffba2
7
+ data.tar.gz: d2a84168b1f70e0f451743bbe14d0398530d31c386784919c6103b77f7c804e71fa05c6697b427c615cb1f3ab1cbe487dde06375621d421da398d45b7a3f7394
data/lib/sdk.rb ADDED
@@ -0,0 +1,363 @@
1
+ require "ffi"
2
+ require "base64"
3
+ require "json"
4
+ require "logger"
5
+ require "base64"
6
+ require "uri"
7
+ require "open3"
8
+
9
+ ### sdk start
10
+ module GoApi
11
+ extend FFI::Library
12
+ ffi_lib "./foundation-api.so"
13
+
14
+ class Example < FFI::Struct
15
+ # This must be completely in sync with the C struct defined in Go code.
16
+ layout :id, :int, :prefix, :pointer
17
+
18
+ def initialize(prefix, id)
19
+ self[:prefix] = FFI::MemoryPointer.from_string(prefix)
20
+ self[:id] = id
21
+ end
22
+
23
+ # This feels convoluted, but it hides the fact that our function is loaded
24
+ # outside of the "struct mirror" class.
25
+ def greet
26
+ Portal.greet(self)
27
+ end
28
+ end
29
+
30
+ attach_function :send_file_event, [:string, :string, :string, :string], :strptr
31
+ attach_function :get_messages, [], :strptr
32
+ attach_function :send_message, [:string], :strptr
33
+ attach_function :file_cache_write, [:string], :strptr
34
+ attach_function :file_cache_read, [:string, :string], :strptr
35
+ attach_function :file_cache_read, [:string, :string], :strptr
36
+ attach_function :send_complete_events, [], :strptr
37
+ attach_function :send_folder_event, [:string, :string, :string, :string], :strptr
38
+ end
39
+
40
+ module Utils
41
+ class Subprocess
42
+ def initialize(cmd, &block)
43
+ Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
44
+ { :out => stdout, :err => stderr }.each do |key, stream|
45
+ Thread.new do
46
+ until (line = stream.gets).nil?
47
+ if key == :out
48
+ yield line, nil, thread if block_given?
49
+ else
50
+ yield nil, line, thread if block_given?
51
+ end
52
+ end
53
+ end
54
+ end
55
+ thread.join # don't exit until the external process is done
56
+ exit_code = thread.value
57
+ if (exit_code != 0)
58
+ puts("Failed to execute_cmd #{cmd} exit code: #{exit_code}")
59
+ Kernel.exit(false)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ class Helper
67
+ def self.run(cmd, chdir = File.dirname(__FILE__))
68
+ puts("run: #{cmd}")
69
+ Utils::Subprocess.new cmd do |stdout, stderr, thread|
70
+ puts "\t#{stdout}"
71
+ if (stderr.nil? == false)
72
+ puts "\t#{stderr}"
73
+ end
74
+ end
75
+ end
76
+
77
+ def self.get_env(name, default)
78
+ if "#{ENV[name]}" == ""
79
+ return default
80
+ end
81
+ return ENV[name]
82
+ end
83
+
84
+ def self.get_env_or_fail(name)
85
+ val = Helper.get_env(name, "")
86
+ if val == ""
87
+ puts("expected environment variable not set: #{name}")
88
+ exit(1)
89
+ end
90
+ return val
91
+ end
92
+
93
+ def self.valid_json?(json)
94
+ JSON.parse(json)
95
+ true
96
+ rescue JSON::ParserError, TypeError => e
97
+ false
98
+ end
99
+
100
+ def self.make_events_hash(b64event)
101
+ if "#{b64event}" == ""
102
+ puts("missing event data")
103
+ exit(1)
104
+ end
105
+ events = Base64.decode64(b64event)
106
+
107
+ if Helper.valid_json?(events) == false
108
+ puts("invalid event data")
109
+ exit(1)
110
+ end
111
+ eventsHash = JSON.parse(events)
112
+ return eventsHash
113
+ end
114
+ end
115
+
116
+ class Controller
117
+ def initialize(plugin)
118
+ @api = FoundationApi.new()
119
+ @log = Logger.new(STDOUT)
120
+ @config = Config.new()
121
+ @plugin = Plugin.new(@api, @log, @config)
122
+ end
123
+
124
+ def run()
125
+ keep_reading = true
126
+ @log.info("starting controller loop")
127
+ while keep_reading
128
+ rtn = @api.get_messages()
129
+ @log.info("rtn: #{rtn.message} #{rtn.error} #{rtn.exit_code}")
130
+ # convert message to fileevent
131
+ hash = JSON.parse(rtn.message)
132
+ hash["items"].each do |item|
133
+ @log.info("message kind: #{item["kind"]}")
134
+ case item["kind"]
135
+ when "FileEvent"
136
+ @log.info("FileEvent")
137
+ event = FileEvent.new(item)
138
+ @plugin.on_file_event(event)
139
+ when "FolderEvent"
140
+ @log.info("FolderEvent")
141
+ event = FolderEvent.new(item)
142
+ @plugin.on_folder_event(event)
143
+ when "CompleteEvent"
144
+ @log.info("CompleteEvent")
145
+ event = CompleteEvent.new(item)
146
+ @plugin.on_complete_event(event)
147
+ keep_reading = false
148
+ else
149
+ @log.info("unknown event kind: #{item["kind"]}")
150
+ end
151
+ end
152
+ end
153
+ @log.info("ending controller loop sending complete event")
154
+ res2 = @api.send_complete_events()
155
+ if res2.exit_code != 0
156
+ @log.error("failed to send complete event: #{res2.error} #{res2.exit_code}")
157
+ end
158
+ end
159
+ end
160
+
161
+ class Response
162
+ attr_accessor :payload, :error, :exit_code
163
+
164
+ def initialize(payload, error, exit_code)
165
+ @payload = payload
166
+ @error = error
167
+ @exit_code = exit_code
168
+ end
169
+ end
170
+
171
+ class FileWriteResult
172
+ attr_accessor :destination, :error, :exit_code
173
+
174
+ def initialize(response)
175
+ @error = response.error
176
+ @exit_code = response.exit_code
177
+ hash = JSON.parse(response.payload)
178
+ @destination = hash["destination"]
179
+ end
180
+ end
181
+
182
+ class MetaData
183
+ attr_accessor :name, :created, :id, :runid, :tags, :label
184
+
185
+ def initialize(hash)
186
+ @name = hash["name"]
187
+ @created = hash["created"]
188
+ @id = hash["id"]
189
+ @runid = hash["runid"]
190
+ @tags = hash["tags"]
191
+ @label = hash["label"]
192
+ end
193
+ end
194
+
195
+ class FolderEvent
196
+ attr_accessor :kind, :version, :metadata, :origin, :path, :folder, :originalpath, :origin
197
+
198
+ def initialize(hash)
199
+ @kind = hash["kind"]
200
+ @version = hash["version"]
201
+ @metadata = MetaData.new(hash["metadata"])
202
+ @origin = hash["origin"]
203
+ @path = hash["path"]
204
+ @folder = hash["folder"]
205
+ @originalpath = hash["originalpath"]
206
+ @origin = hash["origin"]
207
+ end
208
+ end
209
+
210
+ class FileEvent
211
+ attr_accessor :kind, :version, :metadata, :origin, :path, :filename, :originalpath, :origin
212
+
213
+ def initialize(hash)
214
+ @kind = hash["kind"]
215
+ @version = hash["version"]
216
+ @metadata = MetaData.new(hash["metadata"])
217
+ @origin = hash["origin"]
218
+ @path = hash["path"]
219
+ @filename = hash["filename"]
220
+ @originalpath = hash["originalpath"]
221
+ @origin = hash["origin"]
222
+ end
223
+ end
224
+
225
+ class FileReadResult
226
+ attr_accessor :error, :exit_code
227
+
228
+ def initialize(response)
229
+ @error = response.error
230
+ @exit_code = response.exit_code
231
+ end
232
+ end
233
+
234
+ class GetMessageResult
235
+ attr_accessor :message, :error, :exit_code
236
+
237
+ def initialize(response)
238
+ @error = response.error
239
+ @exit_code = response.exit_code
240
+ @message = response.payload
241
+ end
242
+ end
243
+
244
+ class SendMessageResult
245
+ attr_accessor :message, :error, :exit_code
246
+
247
+ def initialize(response)
248
+ @error = response.error
249
+ @exit_code = response.exit_code
250
+ @message = response.payload
251
+ end
252
+ end
253
+
254
+ class SendFolderResult
255
+ attr_accessor :message, :error, :exit_code
256
+
257
+ def initialize(response)
258
+ @error = response.error
259
+ @exit_code = response.exit_code
260
+ @message = response.payload
261
+ end
262
+ end
263
+
264
+ class SendCompleteResult
265
+ attr_accessor :message, :error, :exit_code
266
+
267
+ def initialize(response)
268
+ @error = response.error
269
+ @exit_code = response.exit_code
270
+ @message = response.payload
271
+ end
272
+ end
273
+
274
+ class Config
275
+ def initialize()
276
+ @config_path = Helper.get_env("X_CONFIG", "/etc/plugin/config.json")
277
+ @config = load()
278
+ end
279
+
280
+ def load()
281
+ file = File.read(@config_path)
282
+ config = JSON.parse(file)
283
+ return config
284
+ end
285
+
286
+ def get(name)
287
+ rtn = @config[name]
288
+ if rtn == ""
289
+ puts("plugin configuration is not valid, missing: #{name}")
290
+ exit(2)
291
+ end
292
+ return rtn
293
+ end
294
+ end
295
+
296
+ class FoundationApi
297
+ def initialize()
298
+ end
299
+
300
+ def pase_response(response)
301
+ data = JSON.parse(response)
302
+
303
+ rtn = Response.new(data["payload"], data["error"], data["exit_code"])
304
+ return rtn
305
+ end
306
+
307
+ def display_response(response)
308
+ puts("payload: #{response.payload}")
309
+ puts("error: #{response.error}")
310
+ puts("exit_code: #{response.exit_code}")
311
+ end
312
+
313
+ def get_messages()
314
+ d, e = GoApi.get_messages()
315
+ parsed = pase_response(d)
316
+ display_response(parsed)
317
+ return GetMessageResult.new(parsed)
318
+ end
319
+
320
+ def send_message(data)
321
+ d, e = GoApi.send_message(data)
322
+ parsed = pase_response(d)
323
+ display_response(parsed)
324
+ return SendMessageResult.new(parsed)
325
+ end
326
+
327
+ def send_file_event(path, filename, originalpath, origin)
328
+ d, e = GoApi.send_file_event(path, filename, originalpath, origin)
329
+ parsed = pase_response(d)
330
+ display_response(parsed)
331
+ return SendMessageResult.new(parsed)
332
+ end
333
+
334
+ def send_folder_event(path, folder, originalpath, origin)
335
+ d, e = GoApi.send_folder_event(path, folder, originalpath, origin)
336
+ parsed = pase_response(d)
337
+ display_response(parsed)
338
+ return SendFolderResult.new(parsed)
339
+ end
340
+
341
+ def file_cache_read(uri, destination)
342
+ d, e = GoApi.file_cache_read(uri, destination)
343
+ parsed = pase_response(d)
344
+ display_response(parsed)
345
+ return FileReadResult.new(parsed)
346
+ end
347
+
348
+ def file_cache_write(filename)
349
+ d, e = GoApi.file_cache_write(filename)
350
+ parsed = pase_response(d)
351
+ display_response(parsed)
352
+ return FileWriteResult.new(parsed)
353
+ end
354
+
355
+ def send_complete_events()
356
+ d, e = GoApi.send_complete_events()
357
+ parsed = pase_response(d)
358
+ display_response(parsed)
359
+ return SendCompleteResult.new(parsed)
360
+ end
361
+ end
362
+
363
+ ### sdk end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meshx-plugin-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Meshx
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2010-04-03 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'A '
14
+ email: owain@surfncode.io
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/sdk.rb
20
+ homepage: http://meshx
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubygems_version: 3.3.26
40
+ signing_key:
41
+ specification_version: 3
42
+ summary: meshx-plugin-sdk
43
+ test_files: []