magellan-gcs-proxy 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bca7eb4b15232e1190e59339f68cca01ef9929eb
4
- data.tar.gz: c1d15432f65404b91aabae522b18ce2cac1fa172
3
+ metadata.gz: e2d9990ba10bfc49119dc24969dac164773e526b
4
+ data.tar.gz: 135838363859a7755d687ec3f9ec5f6d17639383
5
5
  SHA512:
6
- metadata.gz: 59fa94585e7f984de73fd5d1cd36f5f499dcfa252e9def885effb9881fca87c4e7dd84d703d22d500c3358918216a0108c152e132ba93528507cce11f4b3736f
7
- data.tar.gz: e27613b66bee86d93148171851cc19e0ec0a7a7a316d3600f457f6a9150a8660db8956bd064dade9c259bcf3d0bcbf6aa18f9fc8ad0d712ace7082e6d16e310c
6
+ metadata.gz: 3c6176dc804d2ddb6c913973296c6c343e8faaf11ceb9dedc4ce17875b7f0353c1f166cd68602ee2444390b99eb61f3372d3439444fea0cd5decd607577867da
7
+ data.tar.gz: 51772e727ad2ea9a7c813d4f62efa041a5c770f7f4713b4bd613d81943a4f8dadd7061ac346eaef9a8f1d079fd9e8e351d7e4b6e2ad57e7bf28c3500cb551518
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
- # Magellan::Gcs::Proxy
1
+ # magellang-gcs-proxy
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/magellan/gcs/proxy`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ magellang-gcs-proxy is a gem for MAGELLAN BLOCKS "Batch type" IoT board.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
6
5
 
7
6
  ## Installation
8
7
 
@@ -22,7 +21,42 @@ Or install it yourself as:
22
21
 
23
22
  ## Usage
24
23
 
25
- TODO: Write usage instructions here
24
+ ```
25
+ magellan-gcs-proxy COMMAND ARGS...
26
+ ```
27
+
28
+ ### TODO How it works
29
+
30
+ ### TODO Expanding variables
31
+
32
+
33
+ ## Debugging with gcloud
34
+
35
+ ### Setup
36
+
37
+ ```
38
+ export PROJECT_ID=[Project ID]
39
+ export TOPIC=projects/$PROJECT_ID/topics/[Topic name]
40
+ export SUB=projects/$PROJECT_ID/subscriptions/[Subscription name of topic]
41
+ $ gcloud beta pubsub topics create projects/$PROJECT_ID/topics/$TOPIC
42
+ $ gcloud beta pubsub topics list
43
+ $ gcloud beta pubsub subscriptions create $SUB --topic $TOPIC
44
+ $ gcloud beta pubsub subscriptions list
45
+ ```
46
+
47
+ ### Publish message
48
+
49
+ ```
50
+ $ gcloud beta pubsub topics publish $TOPIC "" --attribute='download_files=["gs://bucket1/path/to/file"]'
51
+ ```
52
+
53
+
54
+ ### Run application
55
+
56
+ ```
57
+ $ magellan-gcs-proxy COMMAND ARGS...
58
+ ```
59
+
26
60
 
27
61
  ## Development
28
62
 
@@ -1,15 +1,16 @@
1
1
  require "magellan/gcs/proxy"
2
- require "magellan/gcs/proxy/pubsub_operation"
2
+ require "magellan/gcs/proxy/log"
3
3
 
4
4
  require 'json'
5
5
  require 'logger'
6
6
  require 'tmpdir'
7
+ require 'logger_pipe'
7
8
 
8
9
  module Magellan
9
10
  module Gcs
10
11
  module Proxy
11
12
  class Cli
12
- include PubsubOperation
13
+ include Log
13
14
 
14
15
  attr_reader :cmd_template
15
16
  def initialize(*args)
@@ -18,11 +19,14 @@ module Magellan
18
19
 
19
20
  def run
20
21
  logger.info("Start listening")
21
- sub.listen do |msg|
22
+ GCP.subscription.listen do |msg|
22
23
  begin
23
24
  process(msg)
24
25
  rescue => e
25
26
  logger.error("[#{e.class.name}] #{e.message}")
27
+ if ENV['VERBOSE'] =~ /true|yes|on|1/i
28
+ logger.debug("Backtrace\n " << e.backtrace.join("\n "))
29
+ end
26
30
  end
27
31
  end
28
32
  rescue => e
@@ -34,32 +38,31 @@ module Magellan
34
38
  logger.info("Processing message: #{msg.inspect}")
35
39
  Dir.mktmpdir 'workspace' do |dir|
36
40
  dfiles = parse(msg.attributes['download_files'])
37
- ufiles = parse(msg.attributes['upload_files'])
41
+ logger.info("dfiles: #{dfiles}")
38
42
 
39
- context = Context.new(dir, dfiles, ufiles)
43
+ context = Context.new(dir, dfiles)
40
44
  context.setup
45
+ logger.info("context.setup done.")
41
46
 
42
47
  context.download
48
+ logger.info("context.download done.")
49
+ logger.info("msg: #{msg}")
50
+ logger.info("context: #{context}")
43
51
 
44
52
  cmd = build_command(msg, context)
45
53
 
46
- logger.info("Executing command: #{cmd.inspect}")
47
-
48
- if system(cmd)
54
+ begin
55
+ LoggerPipe.run(logger, cmd, returns: :none, logging: :both)
56
+ rescue => e
57
+ logger.error("Error: #{cmd.inspect}")
58
+ else
49
59
  context.upload
50
-
51
- sub.acknowledge msg
60
+ msg.acknowledge!
52
61
  logger.info("Complete processing and acknowledged")
53
- else
54
- logger.error("Error: #{cmd.inspect}")
55
62
  end
56
63
  end
57
64
  end
58
65
 
59
- def logger
60
- @logger ||= Logger.new($stdout)
61
- end
62
-
63
66
  def parse(str)
64
67
  return nil if str.nil? || str.empty?
65
68
  JSON.parse(str)
@@ -1,27 +1,28 @@
1
+ # coding: utf-8
1
2
  require "magellan/gcs/proxy"
2
- require "magellan/gcs/proxy/file_operation"
3
+ require "magellan/gcs/proxy/log"
3
4
 
5
+ require 'fileutils'
4
6
  require 'uri'
5
7
 
6
8
  module Magellan
7
9
  module Gcs
8
10
  module Proxy
9
11
  class Context
10
- include FileOperation
11
-
12
- attr_reader :workspace, :remote_download_files, :remote_upload_files
13
- def initialize(workspace, remote_download_files, remote_upload_files)
12
+ include Log
13
+
14
+ attr_reader :workspace, :remote_download_files
15
+ def initialize(workspace, remote_download_files)
14
16
  @workspace = workspace
15
17
  @remote_download_files = remote_download_files
16
- @remote_upload_files = remote_upload_files
17
18
  end
18
19
 
19
20
  KEYS = [
20
21
  :workspace,
21
22
  :downloads_dir, :uploads_dir,
22
- :download_files, :upload_files,
23
- :local_download_files, :local_upload_files,
24
- :remote_download_files, :remote_upload_files
23
+ :download_files,
24
+ :local_download_files,
25
+ :remote_download_files,
25
26
  ].freeze
26
27
 
27
28
  def [](key)
@@ -52,35 +53,33 @@ module Magellan
52
53
  File.join(workspace, 'uploads')
53
54
  end
54
55
 
55
- def upload_mapping
56
- @upload_mapping ||= build_mapping(uploads_dir, remote_upload_files)
57
- end
58
-
59
- def local_upload_files
60
- @local_upload_files ||= build_local_files_obj(remote_upload_files, upload_mapping)
61
- end
62
- alias_method :upload_files, :local_upload_files
63
-
64
56
  def setup
65
57
  setup_dirs
66
58
  end
67
59
 
68
60
  def download
69
61
  download_mapping.each do |url, path|
70
- logger.info("Downloading: #{url}")
62
+ FileUtils.mkdir_p File.dirname(path)
63
+ logger.debug("Downloading: #{url} to #{path}")
71
64
  uri = parse_uri(url)
72
- bucket = storage.bucket(uri.host)
65
+ @last_bucket_name = uri.host
66
+ bucket = GCP.storage.bucket(@last_bucket_name)
73
67
  file = bucket.file uri.path.sub(/\A\//, '')
74
68
  file.download(path)
69
+ logger.info("Download OK: #{url} to #{path}")
75
70
  end
76
71
  end
77
72
 
78
73
  def upload
79
- upload_mapping.each do |url, path|
80
- logger.info("Uploading: #{url}")
81
- uri = parse_uri(url)
82
- bucket = storage.bucket(uri.host)
83
- bucket.create_file path, uri.path.sub(/\A\//, '')
74
+ Dir.chdir(uploads_dir) do
75
+ Dir.glob('**/*') do |path|
76
+ next if File.directory?(path)
77
+ url = "gs://#{@last_bucket_name}/#{path}"
78
+ logger.info("Uploading: #{path} to #{url}")
79
+ bucket = GCP.storage.bucket(@last_bucket_name)
80
+ bucket.create_file path, path
81
+ logger.info("Upload OK: #{path} to #{url}")
82
+ end
84
83
  end
85
84
  end
86
85
 
@@ -97,6 +96,7 @@ module Magellan
97
96
 
98
97
  def flatten_values(obj)
99
98
  case obj
99
+ when nil then []
100
100
  when Hash then flatten_values(obj.values)
101
101
  when Array then obj.map{|i| flatten_values(i) }
102
102
  else obj
@@ -0,0 +1,60 @@
1
+ # coding: utf-8
2
+ require 'magellan/gcs/proxy'
3
+
4
+ require "google/cloud/pubsub"
5
+ require "google/cloud/storage"
6
+ require 'net/http'
7
+
8
+ module Magellan
9
+ module Gcs
10
+ module Proxy
11
+ module GCP
12
+ extend Log
13
+ include Log
14
+
15
+ module_function
16
+
17
+ def project_id
18
+ @project_id ||= retrieve_project_id
19
+ end
20
+
21
+ def retrieve_project_id
22
+ ENV['BLOCKS_BATCH_PROJECT_ID'] || retrieve_metadata('project/project-id')
23
+ end
24
+
25
+ METADATA_HOST = 'metadata.google.internal'.freeze
26
+ METADATA_PATH_BASE = '/computeMetadata/v1/'.freeze
27
+ METADATA_HEADER = {"Metadata-Flavor" => "Google"}.freeze
28
+
29
+ def retrieve_metadata(key)
30
+ http = Net::HTTP.new(METADATA_HOST)
31
+ res = http.get(METADATA_PATH_BASE + key, METADATA_HEADER)
32
+ case res.code
33
+ when /\A2\d{2}\z/ then res.body
34
+ else raise "[#{res.code}] #{res.body}"
35
+ end
36
+ end
37
+
38
+ def storage
39
+ @storage ||= Google::Cloud::Storage.new(project: project_id)
40
+ end
41
+
42
+ def pubsub
43
+ @pubsub ||= Google::Cloud::Pubsub.new(project: project_id)
44
+ end
45
+
46
+ def subscription
47
+ unless @subscription
48
+ @subscription = pubsub.subscription(ENV['BLOCKS_BATCH_PUBSUB_SUBSCRIPTION'] || 'test-subscription')
49
+ logger.info("subscription: #{@subscription.inspect}")
50
+ end
51
+ @subscription
52
+ end
53
+
54
+ def reset
55
+ instance_variables.each {|ivar| instance_variable_set(ivar, nil)}
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,12 @@
1
+ require 'logger'
2
+ module Magellan
3
+ module Gcs
4
+ module Proxy
5
+ module Log
6
+ def logger
7
+ @logger ||= Logger.new($stdout)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,7 +1,7 @@
1
1
  module Magellan
2
2
  module Gcs
3
3
  module Proxy
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
6
6
  end
7
7
  end
@@ -2,9 +2,9 @@ require "magellan/gcs/proxy/version"
2
2
  require 'magellan/gcs/proxy/cli'
3
3
  require 'magellan/gcs/proxy/context'
4
4
  require 'magellan/gcs/proxy/expand_variable'
5
- require 'magellan/gcs/proxy/file_operation'
5
+ require 'magellan/gcs/proxy/gcp'
6
+ require 'magellan/gcs/proxy/log'
6
7
  require 'magellan/gcs/proxy/message_wrapper'
7
- require 'magellan/gcs/proxy/pubsub_operation'
8
8
 
9
9
  module Magellan
10
10
  module Gcs
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_runtime_dependency "google-cloud-pubsub"
25
25
  spec.add_runtime_dependency "google-cloud-storage"
26
+ spec.add_runtime_dependency "logger_pipe"
26
27
 
27
28
  spec.add_development_dependency "bundler", "~> 1.13"
28
29
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magellan-gcs-proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - akm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-21 00:00:00.000000000 Z
11
+ date: 2016-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-pubsub
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: logger_pipe
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -104,9 +118,9 @@ files:
104
118
  - lib/magellan/gcs/proxy/cli.rb
105
119
  - lib/magellan/gcs/proxy/context.rb
106
120
  - lib/magellan/gcs/proxy/expand_variable.rb
107
- - lib/magellan/gcs/proxy/file_operation.rb
121
+ - lib/magellan/gcs/proxy/gcp.rb
122
+ - lib/magellan/gcs/proxy/log.rb
108
123
  - lib/magellan/gcs/proxy/message_wrapper.rb
109
- - lib/magellan/gcs/proxy/pubsub_operation.rb
110
124
  - lib/magellan/gcs/proxy/version.rb
111
125
  - magellan-gcs-proxy.gemspec
112
126
  homepage: https://github.com/groovenauts/magellan-gcs-proxy
@@ -1,46 +0,0 @@
1
- require "magellan/gcs/proxy"
2
-
3
- require 'uri'
4
- require "google/cloud/storage"
5
-
6
- module Magellan
7
- module Gcs
8
- module Proxy
9
- module FileOperation
10
- def storage
11
- @storage ||= Google::Cloud::Storage.new(
12
- # default credential を利用するため、プロジェクトの指定はしない
13
- # project: ENV['GOOGLE_PROJECT'] || 'dummy-project-id',
14
- # keyfile: ENV['GOOGLE_KEY_JSON_FILE'],
15
- )
16
- end
17
-
18
- def download(base_dir, urls)
19
- (urls || []).each do |url|
20
- logger.info("Downloading: #{url}")
21
- uri = parse_uri(url)
22
- bucket = storage.bucket(uri.host)
23
- file = bucket.file uri.path.sub(/\A\//, '')
24
- file.download File.join(base_dir, uri.path)
25
- end
26
- end
27
-
28
- def upload(base_dir, urls)
29
- (urls || []).each do |url|
30
- logger.info("Uploading: #{url}")
31
- uri = parse_uri(url)
32
- bucket = storage.bucket(uri.host)
33
- bucket.create_file File.join(base_dir, uri.path), uri.path.sub(/\A\//, '')
34
- end
35
- end
36
-
37
- def parse_uri(str)
38
- uri = URI.parse(str)
39
- raise "Unsupported scheme #{uri.scheme.inspect} of #{str}" unless uri.scheme == 'gs'
40
- uri
41
- end
42
-
43
- end
44
- end
45
- end
46
- end
@@ -1,38 +0,0 @@
1
- require "magellan/gcs/proxy"
2
-
3
- require "google/cloud/pubsub"
4
-
5
- module Magellan
6
- module Gcs
7
- module Proxy
8
- module PubsubOperation
9
- def pubsub
10
- @pubsub ||= Google::Cloud::Pubsub.new(
11
- # default credential を利用するため、プロジェクトの指定はしない
12
- # project: ENV['GOOGLE_PROJECT'] || 'dummy-project-id',
13
- # keyfile: ENV['GOOGLE_KEY_JSON_FILE'],
14
- )
15
- end
16
-
17
- def topic
18
- unless @topic
19
- topic_name = ENV['BATCH_TOPIC_NAME'] || 'test-topic'
20
- @topic = pubsub.topic(topic_name) || pubsub.create_topic(topic_name)
21
- logger.info("topic: #{@topic.inspect}")
22
- end
23
- @topic
24
- end
25
-
26
- def sub
27
- unless @sub
28
- sub_name = ENV['BATCH_SUBSCRIPTION_NAME'] || 'test-subscription'
29
- @sub = topic.subscription(sub_name) || topic.subscribe(sub_name)
30
- logger.info("subscription: #{@sub.inspect}")
31
- end
32
- @sub
33
- end
34
-
35
- end
36
- end
37
- end
38
- end