haipa_rest 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ff597bbe79f2fab568de046de5378015b60b2b756f3ed2b4111786b21f4af208
4
+ data.tar.gz: f2958344b3891002fdd3241707e8995218e9ede792292c0fe4762c4b6e5396e3
5
+ SHA512:
6
+ metadata.gz: d73c9bf85d5082dce938a67e4f0a0eda038e6d57f0496eb7bdaec71c29a4b3e9797d116e1ff9f95ed6301594bc1cb854d55cf379bbde9a27cb022e78b251825e
7
+ data.tar.gz: aff4f952f9b3678647e1e56c360dc210646237e86dc40a3cf855cff951aedcbbc9da174efa7c86c3b0c17bb0be3946930bcb08bc8098c965f831062a435168b2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 dbosoft GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Intro
2
+
3
+ haipa_rest is a library which supports the Haipa clients generated with Autorest tool. It contains core logic and helper classes for error handling and authentication.
4
+ Usually it is not supposed to be used as a standalone gem but only as a dependency for generated client gems.
5
+
6
+ This project has been forked from the Microsoft Azure ruby client (https://github.com/Azure/azure-sdk-for-ruby)
7
+
8
+ # Supported Ruby Versions
9
+
10
+ * Ruby 2.0
11
+ * Ruby 2.1
12
+ * Ruby 2.2
13
+
14
+ Note: x64 Ruby for Windows is known to have some compatibility issues.
15
+
16
+ # Installation
17
+
18
+ install the appropriate gem:
19
+
20
+ ```
21
+ gem install haipa_rest
22
+ ```
23
+
24
+ and reference it in your code:
25
+
26
+ ```Ruby
27
+ require 'haipa_rest'
28
+ ```
29
+
30
+ # Running tests
31
+
32
+ haipa_rest has only unit tests which doesn't require any preparation, just run 'rspec' command from the gem directory.
33
+
34
+ # Contribution
35
+
36
+ To start working on the gem the only additional dev dependecy is required - rspec. After you've added a new feature and all specs pass - you're good to go with PR. But before starting any bug/feature - please make sure you've thoroughly discussed it with repository maintainers. This gem already powers a few SDKs and backward compatibility should taken in account.
37
+
38
+ # Adding gem to you generated SDK
39
+
40
+ Reference it in the gemfile and also add this line to your client's gemspec file:
41
+
42
+ ```ruby
43
+ spec.add_runtime_dependency 'haipa_rest', '~> 0.11.1'
44
+ ```
45
+ Don't forget to correct the version.
46
+
47
+
data/lib/haipa_rest.rb ADDED
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ require 'ms_rest'
6
+ require 'haipa_rest/async_operation_status.rb'
7
+ require 'haipa_rest/Haipa_operation_error.rb'
8
+ require 'haipa_rest/Haipa_operation_response.rb'
9
+ require 'haipa_rest/Haipa_service_client.rb'
10
+ require 'haipa_rest/cloud_error_data.rb'
11
+ require 'haipa_rest/final_state_via.rb'
12
+ require 'haipa_rest/credentials/application_token_provider.rb'
13
+ require 'haipa_rest/polling_state.rb'
14
+ require 'haipa_rest/serialization.rb'
15
+ require 'haipa_rest/typed_error_info.rb'
16
+ require 'haipa_rest/version'
17
+ require 'haipa_rest/common/configurable'
18
+ require 'haipa_rest/common/default'
19
+
20
+ module Haipa end
21
+ module Haipa::Client end
22
+ module Haipa::Client::Serialization end
23
+ module Haipa::Client::Common end
24
+ module Haipa::Client::Common::Configurable end
25
+ module Haipa::Client::Common::Default end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Defines values for AsyncOperationStatus enum.
8
+ #
9
+ class AsyncOperationStatus
10
+ ACCEPTED = 'Accepted'
11
+ IN_PROGRESS_STATUS = 'InProgress'
12
+ RUNNING = 'Running'
13
+ SUCCESS_STATUS = 'Succeeded'
14
+ FAILED_STATUS = 'Failed'
15
+ CANCELED_STATUS = 'Canceled'
16
+
17
+ ALL_STATUSES = [ACCEPTED, FAILED_STATUS, CANCELED_STATUS, SUCCESS_STATUS, IN_PROGRESS_STATUS, RUNNING]
18
+ FAILED_STATUSES = [FAILED_STATUS, CANCELED_STATUS]
19
+ TERMINAL_STATUSES = [FAILED_STATUS, CANCELED_STATUS, SUCCESS_STATUS]
20
+
21
+ DEFAULT_DELAY = 30
22
+
23
+ # @return [Integer] delay in seconds which should be used for polling for result of async operation.
24
+ attr_accessor :retry_after
25
+
26
+ # @return [Haipa::Client::CloudErrorData] error information about async operation.
27
+ attr_accessor :error
28
+
29
+ # @return [Stirng] status of polling.
30
+ attr_accessor :status
31
+
32
+ #
33
+ # Checks if given status is terminal one.
34
+ # @param status [String] status to verify
35
+ #
36
+ # @return [Boolean] True if given status is terminal one, false otherwise.
37
+ def self.is_terminal_status(status)
38
+ TERMINAL_STATUSES.any? { |st| st.casecmp(status) == 0 }
39
+ end
40
+
41
+ #
42
+ # Checks if given status is failed one.
43
+ # @param status [String] status to verify
44
+ #
45
+ # @return [Boolean] True if given status is failed one, false otherwise.
46
+ def self.is_failed_status(status)
47
+ FAILED_STATUSES.any? { |st| st.casecmp(status) == 0 }
48
+ end
49
+
50
+ #
51
+ # Checks if given status is successful one.
52
+ # @param status [String] status to verify
53
+ #
54
+ # @return [Boolean] True if given status is successful one, false otherwise.
55
+ def self.is_successful_status(status)
56
+ return (status.casecmp(SUCCESS_STATUS) == 0)
57
+ end
58
+
59
+ #
60
+ # Deserializes given hash into AsyncOperationStatus object.
61
+ # @param object [Hash] object to deserialize.
62
+ #
63
+ # @return [AsyncOperationStatus] deserialized object.
64
+ def self.deserialize_object(object)
65
+ return if object.nil?
66
+ output_object = AsyncOperationStatus.new
67
+
68
+ output_object.status = object['status']
69
+
70
+ output_object.error = CloudErrorData.deserialize_object(object['error'])
71
+
72
+ output_object.retry_after = Integer(object['retryAfter']) unless object['retryAfter'].nil?
73
+
74
+ output_object
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents keeps aux data about Haipa invalid response.
8
+ #
9
+ class CloudErrorData
10
+
11
+ # @return [String] the error code parsed from the body of the http error response.
12
+ attr_accessor :code
13
+
14
+ # @return [String] the error message parsed from the body of the http error response.
15
+ attr_accessor :message
16
+
17
+ # @return [String] the error target parsed from the body of the http error response.
18
+ attr_accessor :target
19
+
20
+ # @return [Array<TypedErrorInfo>] the list of additional error info parsed from the body of the http error response.
21
+ attr_accessor :additionalInfo
22
+
23
+ #
24
+ # Deserializes given hash into CloudErrorData object.
25
+ # @param object [Hash] object to deserialize.
26
+ #
27
+ # @return [CloudErrorData] deserialized object.
28
+ def self.deserialize_object(object)
29
+ return if object.nil?
30
+ output_object = CloudErrorData.new
31
+
32
+ output_object.code = object['code']
33
+
34
+ output_object.message = object['message']
35
+
36
+ output_object.target = object['target']
37
+
38
+ unless object['additionalInfo'].nil?
39
+ output_object.additionalInfo = []
40
+ object['additionalInfo'].each do |info|
41
+ output_object.additionalInfo << Haipa::Client::TypedErrorInfo.deserialize_object(info)
42
+ end
43
+ end
44
+
45
+ output_object
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ require 'openssl'
6
+
7
+ module Haipa::Client::Common
8
+ # The Haipa::Common::Configurable module provides basic configuration for Haipa activities.
9
+ module Configurable
10
+
11
+ # @return [MsRest::ServiceClientCredentials] credentials to authorize HTTP requests made by the service client.
12
+ attr_accessor :credentials
13
+
14
+ # @return [String] client id.
15
+ attr_accessor :client_id
16
+
17
+ # @return [String] path to client key file
18
+ attr_accessor :client_key_file
19
+
20
+ # @return [String] client key
21
+ attr_accessor :client_key
22
+
23
+ # @return [String] url to identity endpoint.
24
+ attr_accessor :identity_endpoint
25
+
26
+ class << self
27
+ #
28
+ # List of configurable keys for {Haipa::Client::Common::Client}.
29
+ # @return [Array] of option keys.
30
+ #
31
+ def keys
32
+ @keys ||= [:client_id, :client_key_file, :identity_endpoint ]
33
+ end
34
+ end
35
+
36
+ #
37
+ # Set configuration options using a block.
38
+ #
39
+ def configure
40
+ yield self
41
+ end
42
+
43
+ #
44
+ # Resets the configurable options to provided options or defaults.
45
+ # This will also creates MsRest::TokenCredentials to be used for subsequent clients.
46
+ #
47
+ def reset!(options = {})
48
+ Haipa::Client::Common::Configurable.keys.each do |key|
49
+ default_value = Haipa::Client::Common::Default.options[key]
50
+ instance_variable_set(:"@#{key}", options.fetch(key, default_value))
51
+ end
52
+
53
+ if(options[:client_key].nil?)
54
+ # The user has not passed in the client key. try to read it from client_key_file
55
+ self.client_key = OpenSSL::PKey::RSA.new File.read self.client_key_file unless self.client_key_file.nil?
56
+ end
57
+
58
+ if(options[:credentials].nil?)
59
+ # The user has not passed in the credentials. So, the api has to
60
+ # build the credentials itself.
61
+ fail ArgumentError, 'client_id is nil' if self.client_id.nil?
62
+ fail ArgumentError, 'client_key is nil' if self.client_key.nil?
63
+ fail ArgumentError, 'identity_endpoint is nil' if self.identity_endpoint.nil?
64
+
65
+ self.credentials = MsRest::TokenCredentials.new(
66
+ Haipa::Client::ApplicationTokenProvider.new(
67
+ self.client_id, self.client_key, self.identity_endpoint))
68
+ else
69
+ self.credentials = options[:credentials]
70
+ end
71
+
72
+ self
73
+ end
74
+
75
+ def config
76
+ self
77
+ end
78
+
79
+ private
80
+
81
+ #
82
+ # configures configurable options to default values
83
+ #
84
+ def setup_default_options
85
+ opts = {}
86
+ Haipa::Client::Common::Configurable.keys.map do |key|
87
+ opts[key] = Haipa::Client::Common::Default.options[key]
88
+ end
89
+
90
+ opts
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client::Common
6
+ module Default
7
+ class << self
8
+
9
+ #
10
+ # Default Haipa Client Id.
11
+ # @return [String] Haipa Client Id.
12
+ #
13
+ def client_id
14
+ ENV['HAIPA_CLIENT_ID']
15
+ end
16
+
17
+ #
18
+ # Default Haipa Client Secret.
19
+ # @return [String] Haipa Client Secret.
20
+ #
21
+ def client_key_file
22
+ ENV['HAIPA_CLIENT_KEY_FILE']
23
+ end
24
+
25
+ #
26
+ # Default Haipa identity endpoint.
27
+ # @return [String] Haipa identiy endpoint
28
+ #
29
+ def identity_endpoint
30
+ ENV['HAIPA_IDENTITY_ENDPOINT']
31
+ end
32
+
33
+ #
34
+ # Configuration options.
35
+ # @return [Hash] Configuration options.
36
+ #
37
+ def options
38
+ Hash[Haipa::Client::Common::Configurable.keys.map { |key| [key, send(key)]}]
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ require 'jwt'
6
+
7
+ module Haipa::Client
8
+ #
9
+ # Class that provides access to authentication token.
10
+ #
11
+ class ApplicationTokenProvider < MsRest::TokenProvider
12
+
13
+ private
14
+
15
+ TOKEN_ACQUIRE_URL = '{identity_endpoint}/connect/token'
16
+ DEFAULT_SCHEME = 'Bearer'
17
+
18
+ # @return [String] client id.
19
+ attr_accessor :client_id
20
+
21
+ # @return [String] client key
22
+ attr_accessor :client_key
23
+
24
+ # @return [String] url to identity endpoint.
25
+ attr_accessor :identity_endpoint
26
+
27
+ # @return [String] auth token.
28
+ attr_accessor :token
29
+
30
+ # @return [Time] the date when the current token expires.
31
+ attr_accessor :token_expires_on
32
+
33
+ # @return [Integer] the amount of time we refresh token before it expires.
34
+ attr_reader :expiration_threshold
35
+
36
+ # @return [String] the type of token.
37
+ attr_reader :token_type
38
+
39
+ public
40
+
41
+ #
42
+ # Creates and initialize new instance of the ApplicationTokenProvider class.
43
+ # @param client_id [String] client id.
44
+ # @param client_key [String] client key.
45
+ # @param identity_endpoint [String] url of identity endpoint.
46
+ # @param ca_file [String] path to additional ca file.
47
+ def initialize(client_id, client_key, identity_endpoint)
48
+ fail ArgumentError, 'Client id cannot be nil' if client_id.nil?
49
+ fail ArgumentError, 'Client key cannot be nil' if client_key.nil?
50
+ fail ArgumentError, 'Identity_endpoint url cannot be nil' if identity_endpoint.nil?
51
+
52
+ @client_id = client_id
53
+ @client_key = client_key
54
+ @identity_endpoint = identity_endpoint
55
+
56
+ @expiration_threshold = 5 * 60
57
+ end
58
+
59
+ #
60
+ # Returns the string value which needs to be attached
61
+ # to HTTP request header in order to be authorized.
62
+ #
63
+ # @return [String] authentication headers.
64
+ def get_authentication_header
65
+ acquire_token if token_expired
66
+ "#{token_type} #{token}"
67
+ end
68
+
69
+ private
70
+
71
+ #
72
+ # Checks whether token is about to expire.
73
+ #
74
+ # @return [Bool] True if token is about to expire, false otherwise.
75
+ def token_expired
76
+ @token.nil? || Time.now >= @token_expires_on + expiration_threshold
77
+ end
78
+
79
+ #
80
+ # Retrieves a new authentication token.
81
+ #
82
+ # @return [String] new authentication token.
83
+ def acquire_token
84
+ token_acquire_url = TOKEN_ACQUIRE_URL.dup
85
+ token_acquire_url['{identity_endpoint}'] = @identity_endpoint
86
+
87
+ url = URI.parse(token_acquire_url)
88
+
89
+ connection = Faraday.new(:url => url, :ssl => MsRest.ssl_options)
90
+ exp = Time.now.to_i + @expiration_threshold
91
+
92
+ payload = { iss: client_id,
93
+ aud: token_acquire_url,
94
+ sub: @client_id,
95
+ exp: exp
96
+ }
97
+
98
+ signed_payload = JWT.encode payload, client_key, 'RS256'
99
+
100
+ response = connection.post url.path, {
101
+ :grant_type => 'client_credentials',
102
+ :client_id => client_id,
103
+ :client_assertion_type => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
104
+ :client_assertion => signed_payload,
105
+ :scope => 'compute_api' }
106
+
107
+ fail HaipaOperationError,
108
+ 'Couldn\'t login to Haipa, please verify your client id and client key' unless response.status == 200
109
+
110
+ response_body = JSON.load(response.body)
111
+ @token = response_body['access_token']
112
+ @token_expires_on = Time.now + Integer(response_body['expires_in'])
113
+ @token_type = response_body['token_type']
114
+
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents a final state via of Haipa long running operation.
8
+ #
9
+ class FinalStateVia
10
+ NONE = -1
11
+ DEFAULT = 0
12
+ ASYNC_OPERATION = 0
13
+ LOCATION = 1
14
+ ORIGINAL_URI = 2
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents an error with the Haipa CLI.
8
+ #
9
+ class HaipaCliError < StandardError
10
+
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents an Haipa error.
8
+ #
9
+ class HaipaOperationError < MsRest::HttpOperationError
10
+
11
+ # @return [String] the error message.
12
+ attr_accessor :error_message
13
+
14
+ # @return [String] the error code.
15
+ attr_accessor :error_code
16
+
17
+ #
18
+ # Creates and initialize new instance of the HaipaOperationError class.
19
+ # @param [Hash] the HTTP request data (uri, body, headers).
20
+ # @param [Faraday::Response] the HTTP response object.
21
+ # @param [String] body the HTTP response body.
22
+ # @param [String] error message.
23
+ #
24
+ def initialize(*args)
25
+ super(*args)
26
+
27
+ # Try to parse @body to find useful error message and code
28
+ # Body should meet the error condition response requirements for Microsoft REST API Guidelines
29
+ # https://github.com/Microsoft/api-guidelines/blob/master/Guidelines.md#7102-error-condition-responses
30
+ begin
31
+ unless @body.nil?
32
+ @error_message = @body['error']['message']
33
+ @error_code = @body['error']['code']
34
+ @msg = "#{@msg}: #{@error_code}: #{@error_message}"
35
+ end
36
+ rescue
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents the data received and deserialized from Haipa service.
8
+ #
9
+ class HaipaOperationResponse < MsRest::HttpOperationResponse
10
+
11
+ # @return [String] identificator of the request.
12
+ attr_accessor :request_id
13
+
14
+ # @return [String] Correlation Id of the request.
15
+ attr_accessor :correlation_request_id
16
+
17
+ # @return [String] Client Request Id of the request.
18
+ attr_accessor :client_request_id
19
+ end
20
+ end
@@ -0,0 +1,304 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents a point of access to the REST API.
8
+ #
9
+ class HaipaServiceClient < MsRest::ServiceClient
10
+
11
+ # @return [Integer] execution interval for long running operations.
12
+ attr_accessor :long_running_operation_retry_timeout
13
+
14
+ # @return [String] api version of the Haipa service in string format.
15
+ attr_accessor :api_version
16
+
17
+ def initialize(credentials, options = nil)
18
+ super(credentials, options)
19
+ # This is the current default for Haipa services, and content-type
20
+ # and accept supported by Autorest
21
+ @request_headers = {
22
+ 'Content-Type' => 'application/json;charset=utf-8',
23
+ 'Accept' => 'application/json'
24
+ }
25
+ add_user_agent_information("haipa_rest/#{Haipa::Client::REST_VERSION}")
26
+ add_user_agent_information("Haipa client for Ruby")
27
+ end
28
+
29
+ #
30
+ # Retrieves the result of 'POST','DELETE','PUT' or 'PATCH' operation. Performs polling of required.
31
+ # @param haipa_response [Haipa::Client::HaipaOperationResponse] response from Haipa service.
32
+ # @param custom_deserialization_block [Proc] custom logic for response deserialization.
33
+ # @param final_state_via [Haipa::Client::FinalStateVia] Final State via value
34
+ #
35
+ # @return [MsRest::HttpOperationResponse] the response.
36
+ #
37
+ def get_long_running_operation_result(haipa_response, custom_deserialization_block, final_state_via = FinalStateVia::DEFAULT)
38
+ check_for_status_code_failure(haipa_response)
39
+
40
+ http_method = haipa_response.request.method
41
+
42
+ polling_state = PollingState.new(haipa_response, @long_running_operation_retry_timeout)
43
+ request = haipa_response.request
44
+
45
+ if !AsyncOperationStatus.is_terminal_status(polling_state.status)
46
+ task = Concurrent::TimerTask.new do
47
+ begin
48
+ if !polling_state.Haipa_async_operation_header_link.nil?
49
+ update_state_from_Haipa_async_operation_header(polling_state.get_request(headers: request.headers, base_uri: request.base_uri, user_agent_extended: user_agent_extended), polling_state)
50
+ elsif !polling_state.location_header_link.nil?
51
+ update_state_from_location_header(polling_state.get_request(headers: request.headers, base_uri: request.base_uri, user_agent_extended: user_agent_extended), polling_state, custom_deserialization_block, final_state_via)
52
+ elsif http_method === :put
53
+ get_request = MsRest::HttpOperationRequest.new(request.base_uri, request.build_path.to_s, :get, {query_params: request.query_params, headers: request.headers, user_agent_extended: user_agent_extended})
54
+ update_state_from_get_resource_operation(get_request, polling_state, custom_deserialization_block)
55
+ else
56
+ task.shutdown
57
+ if final_state_via == FinalStateVia::LOCATION
58
+ if !polling_state.response.body.to_s.empty?
59
+ body = JSON.load(polling_state.response.body)
60
+ polling_state.resource = custom_deserialization_block.call(body)
61
+ else
62
+ fail HaipaOperationError, 'Location header is missing from long running operation'
63
+ end
64
+ else
65
+ fail HaipaOperationError, 'Location header is missing from long running operation'
66
+ end
67
+ end
68
+
69
+ if AsyncOperationStatus.is_terminal_status(polling_state.status)
70
+ task.shutdown
71
+ end
72
+ rescue Exception => e
73
+ task.shutdown
74
+ e
75
+ end
76
+ end
77
+
78
+ polling_delay = polling_state.get_delay
79
+ polling_delay = 0.1 if polling_delay.nil? || polling_delay == 0
80
+
81
+ task.execution_interval = polling_delay
82
+ task.execute
83
+ task.wait_for_termination
84
+
85
+ polling_error = task.value
86
+ fail polling_error if polling_error.is_a?(Exception)
87
+ end
88
+
89
+ if AsyncOperationStatus.is_successful_status(polling_state.status)
90
+ # Process long-running PUT/PATCH
91
+ if (http_method === :put || http_method === :patch) && polling_state.resource.nil?
92
+ get_request = MsRest::HttpOperationRequest.new(request.base_uri, request.build_path.to_s, :get, {query_params: request.query_params, headers: request.headers})
93
+ update_state_from_get_resource_operation(get_request, polling_state, custom_deserialization_block)
94
+ end
95
+
96
+ if final_state_via == FinalStateVia::LOCATION
97
+ if((http_method === :post || http_method === :delete) && !polling_state.location_header_link.nil?)
98
+ update_state_from_location_header(polling_state.get_request(headers: request.headers, base_uri: request.base_uri, user_agent_extended: user_agent_extended), polling_state, custom_deserialization_block, final_state_via)
99
+ end
100
+ end
101
+
102
+ # Process long-running POST/DELETE operation with schema defined on success status codes
103
+ if (http_method === :post || http_method === :delete) && custom_deserialization_block && polling_state.response
104
+ unless polling_state.response.body.to_s.empty?
105
+ body = JSON.load(polling_state.response.body)
106
+ polling_state.resource = custom_deserialization_block.call(body)
107
+ end
108
+ end
109
+ end
110
+
111
+ if AsyncOperationStatus.is_failed_status(polling_state.status)
112
+ fail polling_state.get_operation_error
113
+ end
114
+
115
+ polling_state.get_operation_response
116
+ end
117
+
118
+ #
119
+ # Verifies for unexpected polling status code
120
+ # @param haipa_response [Haipa::Client::HaipaOperationResponse] response from Haipa service.
121
+ #
122
+ def check_for_status_code_failure(haipa_response)
123
+ fail MsRest::ValidationError, 'Haipa response cannot be nil' if haipa_response.nil?
124
+ fail MsRest::ValidationError, 'Haipa response cannot have empty response object' if haipa_response.response.nil?
125
+ fail MsRest::ValidationError, 'Haipa response cannot have empty request object' if haipa_response.request.nil?
126
+
127
+ status_code = haipa_response.response.status
128
+ http_method = haipa_response.request.method
129
+
130
+ fail HaipaOperationError, "Unexpected polling status code from long running operation #{status_code}" unless status_code === 200 || status_code === 202 ||
131
+ (status_code === 201 && http_method === :put) ||
132
+ (status_code === 204 && (http_method === :delete || http_method === :post))
133
+ end
134
+
135
+ #
136
+ # Updates polling state based on location header for PUT HTTP requests.
137
+ # @param request [MsRest::HttpOperationRequest] The url retrieve data from.
138
+ # @param polling_state [Haipa::Client::PollingState] polling state to update.
139
+ # @param custom_deserialization_block [Proc] custom deserialization method for parsing response.
140
+ #
141
+ def update_state_from_get_resource_operation(request, polling_state, custom_deserialization_block)
142
+ result = get_async_with_custom_deserialization(request, custom_deserialization_block)
143
+
144
+ fail HaipaOperationError, 'The response from long running operation does not contain a body' if result.response.body.nil? || result.response.body.empty?
145
+
146
+ # On non flattened resource, we should find provisioning_state inside 'properties'
147
+ if result.body.respond_to?(:properties) && result.body.properties.respond_to?(:provisioning_state) && !result.body.properties.provisioning_state.nil?
148
+ polling_state.status = result.body.properties.provisioning_state
149
+ # On flattened resource, we should find provisioning_state at the top level
150
+ elsif result.body.respond_to?(:provisioning_state) && !result.body.provisioning_state.nil?
151
+ polling_state.status = result.body.provisioning_state
152
+ else
153
+ polling_state.status = AsyncOperationStatus::SUCCESS_STATUS
154
+ end
155
+
156
+ error_data = CloudErrorData.new
157
+ error_data.code = polling_state.status
158
+ error_data.message = "Long running operation failed with status #{polling_state.status}"
159
+
160
+ polling_state.error_data = error_data
161
+ polling_state.update_response(result.response)
162
+ polling_state.request = result.request
163
+ polling_state.resource = result.body
164
+ end
165
+
166
+ #
167
+ # Updates polling state based on location header for HTTP requests.
168
+ # @param request [MsRest::HttpOperationRequest] The url retrieve data from.
169
+ # @param polling_state [Haipa::Client::PollingState] polling state to update.
170
+ # @param custom_deserialization_block [Proc] custom deserialization method for parsing response.
171
+ # @param final_state_via [Haipa::Client::FinalStateVia] Final State via value
172
+ #
173
+ def update_state_from_location_header(request, polling_state, custom_deserialization_block, final_state_via = FinalStateVia::DEFAULT)
174
+ result = get_async_with_custom_deserialization(request, custom_deserialization_block)
175
+
176
+ polling_state.update_response(result.response)
177
+ polling_state.request = result.request
178
+ status_code = result.response.status
179
+ http_method = request.method
180
+
181
+ if status_code === 202
182
+ polling_state.status = AsyncOperationStatus::IN_PROGRESS_STATUS
183
+ elsif status_code === 200 || (status_code === 201 && http_method === :put) ||
184
+ (status_code === 204 && (http_method === :delete || http_method === :post || http_method === :get))
185
+ polling_state.status = AsyncOperationStatus::SUCCESS_STATUS
186
+
187
+ error_data = CloudErrorData.new
188
+ error_data.code = polling_state.status
189
+ error_data.message = "Long running operation failed with status #{polling_state.status}"
190
+
191
+ polling_state.error_data = error_data
192
+ polling_state.resource = result.body
193
+ elsif final_state_via == FinalStateVia::LOCATION && status_code === 404 && http_method === :delete && !polling_state.Haipa_async_operation_header_link.nil? && !polling_state.location_header_link.nil?
194
+ polling_state.status = AsyncOperationStatus::SUCCESS_STATUS
195
+ else
196
+ fail HaipaOperationError, "The response from long running operation does not have a valid status code. Method: #{http_method}, Status Code: #{status_code}"
197
+ end
198
+ end
199
+
200
+ #
201
+ # Updates polling state from Haipa async operation header.
202
+ # @param polling_state [Haipa::Client::PollingState] polling state.
203
+ #
204
+ def update_state_from_Haipa_async_operation_header(request, polling_state)
205
+ result = get_async_with_async_operation_deserialization(request)
206
+
207
+ fail HaipaOperationError, 'The response from long running operation does not contain a body' if result.body.nil? || result.body.status.nil?
208
+
209
+ polling_state.status = result.body.status
210
+ polling_state.error_data = result.body.error
211
+ polling_state.response = result.response
212
+ polling_state.request = result.request
213
+ polling_state.resource = nil
214
+
215
+ polling_state
216
+ end
217
+
218
+ #
219
+ # Retrieves data by given URL.
220
+ # @param request [MsRest::HttpOperationRequest] the URL.
221
+ # @param custom_deserialization_block [Proc] function to perform deserialization of the HTTP response.
222
+ #
223
+ # @return [MsRest::HttpOperationResponse] the response.
224
+ #
225
+ def get_async_with_custom_deserialization(request, custom_deserialization_block)
226
+ result = get_async_common(request)
227
+
228
+ if !result.body.nil? && !custom_deserialization_block.nil?
229
+ begin
230
+ result.body = custom_deserialization_block.call(result.body)
231
+ rescue Exception => e
232
+ fail MsRest::DeserializationError.new("Error occured in deserializing the response", e.message, e.backtrace, http_response.body)
233
+ end
234
+ end
235
+
236
+ result
237
+ end
238
+
239
+ #
240
+ # Retrieves data by given URL.
241
+ # @param request [MsRest::HttpOperationRequest] the URL.
242
+ #
243
+ # @return [MsRest::HttpOperationResponse] the response.
244
+ #
245
+ def get_async_with_async_operation_deserialization(request)
246
+ result = get_async_common(request)
247
+
248
+ result.body = AsyncOperationStatus.deserialize_object(result.body)
249
+
250
+ result
251
+ end
252
+
253
+ #
254
+ # Retrieves data by given URL.
255
+ # @param request [MsRest::HttpOperationRequest] the URL.
256
+ #
257
+ # @return [MsRest::HttpOperationResponse] the response.
258
+ #
259
+ def get_async_common(request)
260
+ fail ValidationError, 'Request cannot be nil' if request.nil?
261
+
262
+ request.middlewares = [[MsRest::RetryPolicyMiddleware, times: 3, retry: 0.02], [:cookie_jar]]
263
+ request.headers.merge!({'x-ms-client-request-id' => SecureRandom.uuid}) unless request.headers.key?('x-ms-client-request-id')
264
+ request.headers.merge!({'Content-Type' => 'application/json'}) unless request.headers.key?('Content-Type')
265
+
266
+ # Send Request
267
+ http_response = request.run_promise do |req|
268
+ @credentials.sign_request(req) unless @credentials.nil?
269
+ end.execute.value!
270
+
271
+ status_code = http_response.status
272
+
273
+ if status_code != 200 && status_code != 201 && status_code != 202 && status_code != 204
274
+ json_error_data = JSON.load(http_response.body)
275
+ error_data = CloudErrorData.deserialize_object(json_error_data)
276
+
277
+ fail HaipaOperationError.new request, http_response, error_data, "Long running operation failed with status #{status_code}"
278
+ end
279
+
280
+ result = MsRest::HttpOperationResponse.new(request, http_response, http_response.body)
281
+
282
+ begin
283
+ result.body = JSON.load(http_response.body) unless http_response.body.to_s.empty?
284
+ rescue Exception => e
285
+ fail MsRest::DeserializationError.new("Error occured in deserializing the response", e.message, e.backtrace, result)
286
+ end
287
+
288
+ result
289
+ end
290
+
291
+ private
292
+ #
293
+ # Retrieves a new instance of the HaipaOperationResponse class.
294
+ # @param [MsRest::HttpOperationRequest] request the HTTP request object.
295
+ # @param [Faraday::Response] response the HTTP response object.
296
+ # @param [String] body the HTTP response body.
297
+ # @return [Haipa::Client::HaipaOperationResponse] the operation response.
298
+ #
299
+ def create_response(request, http_response, body = nil)
300
+ HaipaOperationResponse.new(request, http_response, body)
301
+ end
302
+ end
303
+
304
+ end
@@ -0,0 +1,139 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents a state of Haipa long running operation.
8
+ #
9
+ class PollingState
10
+
11
+ # @return [Net::HTTPRequest] the HTTP request.
12
+ attr_accessor :request
13
+
14
+ # @return the resource
15
+ attr_accessor :resource
16
+
17
+ # @return [Net::HTTPResponse] the HTTP response.
18
+ attr_accessor :response
19
+
20
+ # @return [HaipaOperationError] the Haipa error data.
21
+ attr_accessor :error_data
22
+
23
+ # @return [String] the latest value captured from Haipa-AsyncOperation header.
24
+ attr_accessor :Haipa_async_operation_header_link
25
+
26
+ # @return [String] the latest value captured from Location header.
27
+ attr_accessor :location_header_link
28
+
29
+ # @return [String] status of the long running operation.
30
+ attr_accessor :status
31
+
32
+ def initialize(haipa_response, retry_timeout)
33
+ @retry_timeout = retry_timeout
34
+ @request = haipa_response.request
35
+ update_response(haipa_response.response)
36
+ @resource = haipa_response.body
37
+
38
+ case @response.status
39
+ when 200
40
+ provisioning_state = get_provisioning_state
41
+ @status = provisioning_state.nil?? (AsyncOperationStatus::SUCCESS_STATUS):provisioning_state
42
+ when 201
43
+ provisioning_state = get_provisioning_state
44
+ @status = provisioning_state.nil?? (AsyncOperationStatus::IN_PROGRESS_STATUS):provisioning_state
45
+ when 202
46
+ @status = AsyncOperationStatus::IN_PROGRESS_STATUS
47
+ when 204
48
+ @status = AsyncOperationStatus::SUCCESS_STATUS
49
+ else
50
+ @status = AsyncOperationStatus::FAILED_STATUS
51
+ end
52
+ end
53
+
54
+ #
55
+ # Returns the provisioning status of the resource
56
+ #
57
+ # @return [String] provisioning status of the resource
58
+ def get_provisioning_state
59
+ # On non flattened resource, we should find provisioning_state inside 'properties'
60
+ if (!@resource.nil? && @resource.respond_to?(:properties) && @resource.properties.respond_to?(:provisioning_state) && !@resource.properties.provisioning_state.nil?)
61
+ @resource.properties.provisioning_state
62
+ # On flattened resource, we should find provisioning_state at the top level
63
+ elsif !@resource.nil? && @resource.respond_to?(:provisioning_state) && !@resource.provisioning_state.nil?
64
+ @resource.provisioning_state
65
+ else
66
+ nil
67
+ end
68
+ end
69
+
70
+ #
71
+ # Returns the amount of time in seconds for long running operation polling delay.
72
+ #
73
+ # @return [Integer] Amount of time in seconds for long running operation polling delay.
74
+ def get_delay
75
+ return @retry_timeout unless @retry_timeout.nil?
76
+
77
+ if !response.nil? && !response.headers['Retry-After'].nil?
78
+ return response.headers['Retry-After'].to_i
79
+ end
80
+
81
+ return AsyncOperationStatus::DEFAULT_DELAY
82
+ end
83
+
84
+ #
85
+ # Updates the polling state from the fields of given response object.
86
+ # @param response [Net::HTTPResponse] the HTTP response.
87
+ def update_response(response)
88
+ @response = response
89
+
90
+ unless response.nil?
91
+ @Haipa_async_operation_header_link = response.headers['Haipa-AsyncOperation'] unless response.headers['Haipa-AsyncOperation'].nil?
92
+ @location_header_link = response.headers['Location'] unless response.headers['Location'].nil?
93
+ end
94
+ end
95
+
96
+ #
97
+ # returns the Haipa's response.
98
+ #
99
+ # @return [Haipa::Client::HaipaOperationResponse] Haipa's response.
100
+ def get_operation_response
101
+ haipa_response = HaipaOperationResponse.new(@request, @response, @resource)
102
+ haipa_response
103
+ end
104
+
105
+ #
106
+ # Composes and returns cloud error.
107
+ #
108
+ # @return [HaipaOperationError] the cloud error.
109
+ def get_operation_error
110
+ HaipaOperationError.new @request, @response, @error_data, "Long running operation failed with status #{@status}"
111
+ end
112
+
113
+ def get_request(options = {})
114
+ link = @Haipa_async_operation_header_link || @location_header_link
115
+ options[:connection] = create_connection(options[:base_uri])
116
+ MsRest::HttpOperationRequest.new(nil, link, :get, options)
117
+ end
118
+
119
+ private
120
+
121
+ # @return [Integer] retry timeout.
122
+ attr_accessor :retry_timeout
123
+
124
+ attr_accessor :connection
125
+
126
+ def create_connection(base_url)
127
+ @connection ||= Faraday.new(:url => base_url, :ssl => MsRest.ssl_options) do |faraday|
128
+ [[MsRest::RetryPolicyMiddleware, times: 3, retry: 0.02], [:cookie_jar]].each{ |args| faraday.use(*args) }
129
+ faraday.adapter Faraday.default_adapter
130
+ faraday.headers = request.headers
131
+ logging = ENV['HAIPA_HTTP_LOGGING'] || request.log
132
+ if logging
133
+ faraday.response :logger, nil, { :bodies => logging == 'full' }
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ # Base module for Haipa Ruby serialization and deserialization.
7
+ #
8
+ # Provides methods to serialize Ruby object into Ruby Hash and
9
+ # to deserialize Ruby Hash into Ruby object.
10
+ module Serialization
11
+ include MsRest::Serialization
12
+
13
+ private
14
+
15
+ #
16
+ # Builds serializer
17
+ #
18
+ def build_serializer
19
+ Serialization.new(self)
20
+ end
21
+
22
+ #
23
+ # Class to handle serialization & deserialization.
24
+ #
25
+ class Serialization < MsRest::Serialization::Serialization
26
+
27
+ #
28
+ # Retrieves model of the model_name
29
+ #
30
+ # @param model_name [String] Name of the model to retrieve.
31
+ #
32
+ def get_model(model_name)
33
+ begin
34
+ Object.const_get(@context.class.to_s.split('::')[0...-1].join('::') + "::Models::#{model_name}")
35
+ rescue NameError
36
+ # Look into Haipa::Client namespace if model name not found in the models namespace
37
+ Object.const_get("Haipa::Client::#{model_name}")
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa::Client
6
+ #
7
+ # Class which represents the error type and information.
8
+ #
9
+ class TypedErrorInfo
10
+
11
+ # @return [String] the error type parsed from the body of the http error response.
12
+ attr_accessor :type
13
+
14
+ # @return [Object] the error info parsed from the body of the http error response.
15
+ attr_accessor :info
16
+
17
+ #
18
+ # Deserializes given hash into TypedErrorInfo object.
19
+ # @param object [Hash] object to deserialize.
20
+ #
21
+ # @return [TypedErrorInfo] deserialized object.
22
+ def self.deserialize_object(object)
23
+ return if object.nil?
24
+ output_object = TypedErrorInfo.new
25
+
26
+ output_object.type = object['type']
27
+
28
+ output_object.info = object['info']
29
+
30
+ output_object
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) dbosoft GmbH and Haipa Contributors. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+
5
+ module Haipa end
6
+ module Haipa::Client
7
+ REST_VERSION = '0.11.1'
8
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haipa_rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.11.1
5
+ platform: ruby
6
+ authors:
7
+ - Haipa Contributors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: concurrent-ruby
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: unf_ext
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.0.7.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.0.7.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.9'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.9'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ms_rest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.7.4
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.7.4
111
+ description: Haipa Client Library for Ruby.
112
+ email: package-maintainers@haipa.io
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - LICENSE.txt
118
+ - README.md
119
+ - lib/haipa_rest.rb
120
+ - lib/haipa_rest/async_operation_status.rb
121
+ - lib/haipa_rest/cloud_error_data.rb
122
+ - lib/haipa_rest/common/configurable.rb
123
+ - lib/haipa_rest/common/default.rb
124
+ - lib/haipa_rest/credentials/application_token_provider.rb
125
+ - lib/haipa_rest/final_state_via.rb
126
+ - lib/haipa_rest/haipa_cli_error.rb
127
+ - lib/haipa_rest/haipa_operation_error.rb
128
+ - lib/haipa_rest/haipa_operation_response.rb
129
+ - lib/haipa_rest/haipa_service_client.rb
130
+ - lib/haipa_rest/polling_state.rb
131
+ - lib/haipa_rest/serialization.rb
132
+ - lib/haipa_rest/typed_error_info.rb
133
+ - lib/haipa_rest/version.rb
134
+ homepage: https://github.com/haipa/ruby-client
135
+ licenses:
136
+ - MIT
137
+ metadata:
138
+ bug_tracker_uri: https://github.com/haipa/haipa/issues
139
+ documentation_uri: https://github.com/haipa/ruby-client
140
+ homepage_uri: https://github.com/haipa/ruby-client
141
+ source_code_uri: https://github.com/haipa/ruby-client
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: 2.0.0
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.7.6
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Haipa Client Library for Ruby.
162
+ test_files: []