magellan-gcs-proxy 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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