vcap_common 1.0.10 → 2.0.8

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.
@@ -2,6 +2,7 @@
2
2
  module VCAP
3
3
  module Services
4
4
  module Api
5
+ SDS_UPLOAD_TOKEN_HEADER = 'X-VCAP-SDS-Upload-Token'
5
6
  GATEWAY_TOKEN_HEADER = 'X-VCAP-Service-Token'
6
7
  SERVICE_LABEL_REGEX = /^\S+-\S+$/
7
8
  end
@@ -2,6 +2,7 @@
2
2
  require 'uri'
3
3
 
4
4
  require 'services/api/const'
5
+ require 'membrane'
5
6
  require 'json_message'
6
7
 
7
8
  module VCAP
@@ -17,21 +18,26 @@ module VCAP
17
18
  # NB: Deleting an offering takes all args in the url
18
19
  #
19
20
  class ServiceOfferingRequest < JsonMessage
20
- required :label, SERVICE_LABEL_REGEX
21
- required :url, URI::regexp(%w(http https))
21
+ required :label, SERVICE_LABEL_REGEX
22
+ required :url, URI::regexp(%w(http https))
23
+ required :supported_versions, [String]
24
+ required :version_aliases, Hash
22
25
 
23
- optional :description, String
24
- optional :info_url, URI::regexp(%w(http https))
25
- optional :tags, [String]
26
- optional :plans, [String]
26
+ optional :description, String
27
+ optional :info_url, URI::regexp(%w(http https))
28
+ optional :tags, [String]
29
+ optional :plans, [String]
30
+ optional :cf_plan_id
27
31
  optional :plan_options
28
32
  optional :binding_options
29
33
  optional :acls
30
34
  optional :active
31
- optional :timeout, Integer
35
+ optional :timeout, Integer
36
+ optional :provider, String
37
+ optional :default_plan, String
32
38
  end
33
39
 
34
- class BrokeredServiceOfferingRequest < JsonMessage
40
+ class ProxiedServiceOfferingRequest < JsonMessage
35
41
  required :label, SERVICE_LABEL_REGEX
36
42
  required :options, [{"name" => String, "credentials" => Hash}]
37
43
  optional :description, String
@@ -44,11 +50,11 @@ module VCAP
44
50
  end
45
51
 
46
52
  class ListHandlesResponse < JsonMessage
47
- required :handles, [::JsonSchema::WILDCARD]
53
+ required :handles, [Object]
48
54
  end
49
55
 
50
- class ListBrokeredServicesResponse < JsonMessage
51
- required :brokered_services, [{"label" => String, "description" => String, "acls" => {"users" => [String], "wildcards" => [String]}}]
56
+ class ListProxiedServicesResponse < JsonMessage
57
+ required :proxied_services, [{"label" => String, "description" => String, "acls" => {"users" => [String], "wildcards" => [String]}}]
52
58
  end
53
59
 
54
60
  #
@@ -59,8 +65,10 @@ module VCAP
59
65
  required :label, SERVICE_LABEL_REGEX
60
66
  required :name, String
61
67
  required :plan, String
68
+ required :version, String
62
69
 
63
70
  optional :plan_option
71
+ optional :provider, String
64
72
  end
65
73
 
66
74
  class GatewayProvisionRequest < JsonMessage
@@ -68,13 +76,15 @@ module VCAP
68
76
  required :name, String
69
77
  required :plan, String
70
78
  required :email, String
79
+ required :version, String
71
80
 
72
81
  optional :plan_option
73
82
  end
74
83
 
75
- class GatewayProvisionResponse < JsonMessage
84
+ # Provision and bind response use the same format
85
+ class GatewayHandleResponse < JsonMessage
76
86
  required :service_id, String
77
- required :data
87
+ required :configuration
78
88
  required :credentials
79
89
  end
80
90
 
@@ -105,12 +115,6 @@ module VCAP
105
115
  required :binding_token, String
106
116
  end
107
117
 
108
- class GatewayBindResponse < JsonMessage
109
- required :service_id, String
110
- required :configuration
111
- required :credentials
112
- end
113
-
114
118
  # Bind app_name using binding_token
115
119
  class BindExternalRequest < JsonMessage
116
120
  required :binding_token, String
@@ -126,10 +130,15 @@ module VCAP
126
130
  required :snapshot_id, String
127
131
  required :date, String
128
132
  required :size, Integer
133
+ required :name, String
129
134
  end
130
135
 
131
136
  class SnapshotList < JsonMessage
132
- required :snapshots, [::JsonSchema::WILDCARD]
137
+ required :snapshots, [Object]
138
+ end
139
+
140
+ class UpdateSnapshotNameRequest < JsonMessage
141
+ required :name, String
133
142
  end
134
143
 
135
144
  class Job < JsonMessage
@@ -138,7 +147,7 @@ module VCAP
138
147
  required :start_time, String
139
148
  optional :description, String
140
149
  optional :complete_time, String
141
- optional :result, ::JsonSchema::WILDCARD
150
+ optional :result, Object
142
151
  end
143
152
 
144
153
  class SerializedURL < JsonMessage
@@ -148,6 +157,11 @@ module VCAP
148
157
  class SerializedData < JsonMessage
149
158
  required :data, String
150
159
  end
160
+
161
+ class ServiceErrorResponse < JsonMessage
162
+ required :code, Integer
163
+ required :description, String
164
+ end
151
165
  end
152
166
  end
153
167
  end
@@ -0,0 +1,191 @@
1
+ # Copyright (c) 2009-2011 VMware, Inc.
2
+ require 'eventmachine'
3
+ require 'em-http-request'
4
+
5
+ # monkey-patch for em-http-request to support multipart file upload
6
+
7
+ module EventMachine
8
+ class StreamUploadIO
9
+ attr_reader :args, :filename, :basename, :size, :content_type
10
+ def initialize(filename, content_type, args={})
11
+ # disable http chunking
12
+ @args = args.merge({:http_chunks => false})
13
+ @filename = filename
14
+ # FIXME how to catch exception and log it
15
+ begin
16
+ @basename = File.basename(filename)
17
+ @size = File.size(filename)
18
+ rescue => e
19
+ # size == 0, the part will be injected
20
+ @size = 0
21
+ end
22
+ @content_type = content_type
23
+ end
24
+
25
+ def add_extra_size(extra_size)
26
+ @size += extra_size
27
+ end
28
+
29
+ def length
30
+ @size
31
+ end
32
+
33
+ def stream_file_data
34
+ true
35
+ end
36
+ end
37
+
38
+ module Part
39
+ def self.create(boundary, k, v)
40
+ if v.respond_to?(:stream_file_data)
41
+ FilePart.new(boundary, k, v)
42
+ else
43
+ ParamPart.new(boundary, k, v)
44
+ end
45
+ end
46
+
47
+ def to_io
48
+ @io
49
+ end
50
+
51
+ def length
52
+ @io.size
53
+ end
54
+
55
+ def send_part(conn, parts, idx)
56
+ end
57
+
58
+ def get_next_part(parts, idx)
59
+ next_idx = idx.to_i + 1
60
+ if parts && next_idx < parts.size && next_idx >=0
61
+ next_part = parts[next_idx]
62
+ else
63
+ nil
64
+ end
65
+ next_part
66
+ end
67
+
68
+ def send_next_part(conn, parts, idx)
69
+ next_part = get_next_part(parts, idx)
70
+ next_part.send_part(conn, parts, idx+1) if next_part
71
+ end
72
+
73
+ end
74
+
75
+ class ParamPart
76
+ include Part
77
+ def initialize(boundary, name, value)
78
+ @boundary = boundary
79
+ @name = name
80
+ part = ''
81
+ part << "--#{@boundary}\r\n"
82
+ part << "Content-Disposition: form-data; name=\"#{@name.to_s}\"\r\n"
83
+ part << "\r\n"
84
+ part << "#{value.to_s}\r\n"
85
+ @io = StringIO.new(part)
86
+ end
87
+
88
+ def send_part(conn, parts, idx)
89
+ conn.send_data @io.string if conn
90
+ send_next_part(conn, parts, idx)
91
+ end
92
+ end
93
+
94
+ class EpiloguePart
95
+ include Part
96
+ def initialize(boundary)
97
+ @io = StringIO.new("--#{boundary}--\r\n") #\r\n or \r\n\r\n
98
+ end
99
+
100
+ def send_part(conn, parts, idx)
101
+ conn.send_data @io.string if conn
102
+ # this part should be the last part
103
+ end
104
+ end
105
+
106
+ class FilePart
107
+ include Part
108
+ def initialize(boundary, name, upload_io)
109
+ @boundary = boundary
110
+ @name = name
111
+ @io = upload_io
112
+ @part = ''
113
+ @part << "--#{boundary}\r\n"
114
+ @part << "Content-Disposition: form-data; name=\"#{name.to_s}\"; filename=\"#{@io.filename}\"\r\n"
115
+ @part << "Content-Length: #{@io.size}\r\n"
116
+ @part << "Content-Type: #{@io.content_type}\r\n"
117
+ @part << "Content-Transfer-Encoding: binary\r\n"
118
+ @part << "\r\n"
119
+ @end_part ="\r\n"
120
+ @io.add_extra_size(@part.size + @end_part.size)
121
+ end
122
+
123
+ def send_part(conn, parts, idx)
124
+ conn.send_data @part
125
+ streamer = EM::FileStreamer.new(conn, @io.filename, @io.args)
126
+ streamer.callback {
127
+ conn.send_data @end_part
128
+ send_next_part(conn, parts, idx)
129
+ }
130
+ end
131
+ end
132
+
133
+ class Multipart
134
+ DEFAULT_BOUNDARY = "-----------RubyEMMultiPartPost"
135
+ attr_reader :parts, :ps, :content_type, :content_length, :boundary, :headers
136
+ def initialize(params, headers={}, boundary=DEFAULT_BOUNDARY)
137
+ @parts = params.map{ |k,v| Part.create(boundary, k, v) }
138
+ @parts << EpiloguePart.new(boundary)
139
+ # inject the part with length = 0
140
+ @ps = @parts.select{ |part| part.length > 0 }
141
+ @content_type = "multipart/form-data; boundary=#{boundary}"
142
+ @content_length = 0
143
+ @parts.each do |part|
144
+ @content_length += part.length
145
+ end
146
+ @boundary = boundary
147
+ @headers = headers
148
+ end
149
+
150
+ def send_body(conn)
151
+ if conn && conn.error.nil? && @parts.size > 0
152
+ part = @parts.first
153
+ part.send_part(conn, @parts, 0)
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ ## Support to streaming the file when sending body
160
+ ## TODO FIXME this patch whether depends on specified version???
161
+ module EventMachine
162
+ class HttpClient
163
+ alias_method :original_send_request, :send_request
164
+ def multipart_request?
165
+ (@req.method == 'POST' or @req.method == 'PUT') and @options[:multipart]
166
+ end
167
+
168
+ def send_request(head, body)
169
+ unless multipart_request?
170
+ original_send_request(head, body)
171
+ else
172
+ body = normalize_body(body)
173
+ multipart = @options[:multipart]
174
+ query = @options[:query]
175
+
176
+ head['content-length'] = multipart.content_length
177
+ head['content-type'] = multipart.content_type
178
+ extra_headers = {}
179
+ extra_headers = multipart.headers.reject { |k, v| %w(content-length content-type).include?(k.to_s.downcase) }
180
+ head.merge! extra_headers
181
+
182
+ request_header ||= encode_request(@req.method, @req.uri, query, @conn.opts.proxy)
183
+ request_header << encode_headers(head)
184
+ request_header << CRLF
185
+ @conn.send_data request_header
186
+
187
+ multipart.send_body(@conn)
188
+ end
189
+ end
190
+ end
191
+ end
@@ -45,7 +45,7 @@ module VCAP
45
45
  class Component
46
46
 
47
47
  # We will suppress these from normal varz reporting by default.
48
- CONFIG_SUPPRESS = Set.new([:mbus, :service_mbus, :keys, :database_environment, :mysql, :password])
48
+ CONFIG_SUPPRESS = Set.new([:mbus, :service_mbus, :keys, :database_environment, :password, :pass, :token])
49
49
 
50
50
  class << self
51
51
 
data/lib/vcap/config.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  require 'yaml'
3
3
 
4
4
  require 'vcap/common'
5
- require 'vcap/json_schema'
5
+ require 'membrane'
6
6
 
7
7
  module VCAP
8
8
  class Config
@@ -10,13 +10,13 @@ module VCAP
10
10
  attr_reader :schema
11
11
 
12
12
  def define_schema(&blk)
13
- @schema = VCAP::JsonSchema.build(&blk)
13
+ @schema = Membrane::SchemaParser.parse(&blk)
14
14
  end
15
15
 
16
16
  def from_file(filename, symbolize_keys=true)
17
17
  config = YAML.load_file(filename)
18
- @schema.validate(config)
19
18
  config = VCAP.symbolize_keys(config) if symbolize_keys
19
+ @schema.validate(config)
20
20
  config
21
21
  end
22
22
 
@@ -27,6 +27,5 @@ module VCAP
27
27
  end
28
28
  end
29
29
  end
30
-
31
30
  end
32
31
  end
@@ -0,0 +1,42 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+ #
3
+ # These two methods provide support for transfering an integer sorted set to/from
4
+ # array. When encoded into JSON format, the to_int_array method is space efficient
5
+ # comparing to the native to_a method of sorted set.
6
+ #
7
+ # For example, the following set
8
+ # [12345, 12456, 13457, 13567, 14203, 14214]
9
+ #
10
+ # After encoded by to_int_array, it becomes
11
+ # [12345, 111, 1, 90, 636, 11]
12
+ #
13
+ # The JSON format will save lots of space
14
+ #
15
+
16
+ require 'set'
17
+
18
+ class SortedSet
19
+ def to_int_array
20
+ array = []
21
+
22
+ former = 0
23
+ self.each do |i|
24
+ array << i - former
25
+ former = i
26
+ end
27
+
28
+ array
29
+ end
30
+
31
+ def self.from_int_array(array)
32
+ set = SortedSet.new
33
+
34
+ current = 0
35
+ array.each do |i|
36
+ current += i
37
+ set << current
38
+ end
39
+
40
+ set
41
+ end
42
+ end
@@ -11,7 +11,7 @@ end
11
11
  class VCAP::Spec::ForkedComponent::Base
12
12
  attr_reader :pid, :pid_filename, :output_basedir, :name, :cmd
13
13
 
14
- attr_accessor :reopen_stdio
14
+ attr_accessor :reopen_stdio, :daemon
15
15
 
16
16
  # @param cmd String Command to run
17
17
  # @param name String Short name for this component (e.g. 'redis')
@@ -25,6 +25,7 @@ class VCAP::Spec::ForkedComponent::Base
25
25
  @pid_filename = pid_filename
26
26
 
27
27
  @reopen_stdio = true
28
+ @daemon = false
28
29
 
29
30
  end
30
31
 
@@ -53,8 +54,12 @@ class VCAP::Spec::ForkedComponent::Base
53
54
 
54
55
  def stop
55
56
  return unless @pid && VCAP.process_running?(@pid)
56
- Process.kill('TERM', @pid)
57
- Process.waitpid(@pid, 0)
57
+ if @daemon
58
+ Process.kill('KILL', @pid)
59
+ else
60
+ Process.kill('TERM', @pid)
61
+ Process.waitpid(@pid, 0)
62
+ end
58
63
  FileUtils.rm_f(@pid_filename) if @pid_filename
59
64
  @pid = nil
60
65