croesus 0.1.3
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 +7 -0
- data/.gitignore +121 -0
- data/.ruby-version +1 -0
- data/API_operation.txt +197 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +0 -0
- data/README.md +146 -0
- data/Rakefile +26 -0
- data/bin/console_cmd.rb +133 -0
- data/croesus.gemspec +39 -0
- data/lib/croesus/associations.rb +46 -0
- data/lib/croesus/attribute.rb +41 -0
- data/lib/croesus/attributes.rb +93 -0
- data/lib/croesus/coerce.rb +110 -0
- data/lib/croesus/coercions/boolean_definitions.rb +32 -0
- data/lib/croesus/coercions/date_definitions.rb +30 -0
- data/lib/croesus/coercions/date_time_definitions.rb +30 -0
- data/lib/croesus/coercions/fixnum_definitions.rb +32 -0
- data/lib/croesus/coercions/float_definitions.rb +30 -0
- data/lib/croesus/coercions/hash_definitions.rb +27 -0
- data/lib/croesus/coercions/integer_definitions.rb +29 -0
- data/lib/croesus/coercions/string_definitions.rb +43 -0
- data/lib/croesus/coercions/time_definitions.rb +30 -0
- data/lib/croesus/core_ext/blank.rb +123 -0
- data/lib/croesus/core_ext/hash.rb +185 -0
- data/lib/croesus/dsl/dsl.rb +35 -0
- data/lib/croesus/dsl/helpers.rb +43 -0
- data/lib/croesus/dsl/mod_factory.rb +191 -0
- data/lib/croesus/dsl/resource_dsl.rb +59 -0
- data/lib/croesus/dsl/route_dsl.rb +42 -0
- data/lib/croesus/identity_map.rb +98 -0
- data/lib/croesus/platform.rb +47 -0
- data/lib/croesus/querying.rb +63 -0
- data/lib/croesus/resources/about.rb +15 -0
- data/lib/croesus/resources/basic_methods.rb +36 -0
- data/lib/croesus/resources/connectivity.rb +42 -0
- data/lib/croesus/resources/container.rb +135 -0
- data/lib/croesus/resources/fault.rb +38 -0
- data/lib/croesus/resources/fault_effect.rb +24 -0
- data/lib/croesus/resources/group.rb +37 -0
- data/lib/croesus/resources/host.rb +26 -0
- data/lib/croesus/resources/job.rb +27 -0
- data/lib/croesus/resources/namespace.rb +39 -0
- data/lib/croesus/resources/policy.rb +38 -0
- data/lib/croesus/resources/source.rb +86 -0
- data/lib/croesus/resources/source_config.rb +54 -0
- data/lib/croesus/resources/source_environment.rb +58 -0
- data/lib/croesus/resources/source_repository.rb +14 -0
- data/lib/croesus/resources/system_info.rb +21 -0
- data/lib/croesus/resources/timeflow.rb +40 -0
- data/lib/croesus/resources/timeflow_snapshot.rb +38 -0
- data/lib/croesus/utils.rb +262 -0
- data/lib/croesus/validations/many.rb +27 -0
- data/lib/croesus/validations/optional.rb +27 -0
- data/lib/croesus/validations.rb +91 -0
- data/lib/croesus/validators/base.rb +47 -0
- data/lib/croesus/validators/boolean_validator.rb +32 -0
- data/lib/croesus/validators/email_validator.rb +36 -0
- data/lib/croesus/validators/enumerable_validator.rb +40 -0
- data/lib/croesus/validators/hash_validator.rb +50 -0
- data/lib/croesus/validators/lambda_validator.rb +54 -0
- data/lib/croesus/validators/many_validator.rb +57 -0
- data/lib/croesus/validators/optional_validator.rb +41 -0
- data/lib/croesus/validators/presence_validator.rb +36 -0
- data/lib/croesus/validators/simple_type_validators.rb +38 -0
- data/lib/croesus/validators/simple_validator.rb +40 -0
- data/lib/croesus/version.rb +43 -0
- data/lib/croesus/web_client/web_client.rb +153 -0
- data/lib/croesus/web_client/web_request.rb +77 -0
- data/lib/croesus/web_client/web_response.rb +70 -0
- data/lib/croesus.rb +250 -0
- metadata +325 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
|
2
|
+
# Delphix Source API template
|
3
|
+
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :source do
|
6
|
+
description 'Sources represent external database instances outside the ' \
|
7
|
+
'Delphix system. These can be linked sources (which pull ' \
|
8
|
+
'data into Delphix from pre-existing databases) or virtual ' \
|
9
|
+
'sources which export data from Delphix to arbitrary targets.'
|
10
|
+
root '/resources/json/delphix/source'
|
11
|
+
|
12
|
+
get '/resources/json/delphix/source' do
|
13
|
+
description 'Lists sources on the system.'
|
14
|
+
returns Array
|
15
|
+
name :list
|
16
|
+
end
|
17
|
+
|
18
|
+
get '/resources/json/delphix/source/{ref}' do
|
19
|
+
description 'Retrieve the specified Source object.'
|
20
|
+
returns Array
|
21
|
+
name :read
|
22
|
+
end
|
23
|
+
|
24
|
+
post '/resources/json/delphix/source/{ref}' do
|
25
|
+
description 'Update the specified Source object.'
|
26
|
+
input Hash
|
27
|
+
name :update
|
28
|
+
end
|
29
|
+
|
30
|
+
post '/resources/json/delphix/source/{ref}/disable' do
|
31
|
+
description 'Disables the given source such that Delphix no longer ' \
|
32
|
+
'interacts with the source. A disabled source has no data ' \
|
33
|
+
'available on the target host, and therefore cannot be ' \
|
34
|
+
'running. No monitoring is done for disabled sources.'
|
35
|
+
input String
|
36
|
+
name :disable
|
37
|
+
end
|
38
|
+
|
39
|
+
post '/resources/json/delphix/source/{ref}/enable' do
|
40
|
+
description 'Enables the given source, exporting any necessary data and '\
|
41
|
+
'starting the source. Once enabled, the source will be ' \
|
42
|
+
'monitored by Delphix regardless of whether it is currently '\
|
43
|
+
'running, and the server will respond to changes in its ' \
|
44
|
+
'status appropriately.'
|
45
|
+
input Hash
|
46
|
+
name :enable
|
47
|
+
end
|
48
|
+
|
49
|
+
post '/resources/json/delphix/source/{ref}/start' do
|
50
|
+
description 'Starts the given source. Only virtual sources can be ' \
|
51
|
+
'started and stopped. A stopped source is equivalent to ' \
|
52
|
+
'stopping the source through application-specific means, ' \
|
53
|
+
'and a source can be started or stopped both through this ' \
|
54
|
+
'interface as well as via the external application. A ' \
|
55
|
+
'stopped source is still monitored for availability and ' \
|
56
|
+
'policies can still run against a stopped source, if ' \
|
57
|
+
'applicable. Linked sources cannot be stopped, only virtual '\
|
58
|
+
'sources managed by the server can be started via this ' \
|
59
|
+
'mechanism.'
|
60
|
+
input String
|
61
|
+
name :start
|
62
|
+
end
|
63
|
+
|
64
|
+
post '/resources/json/delphix/source/{ref}/stop' do
|
65
|
+
description 'Stops the given source. Only virtual sources can be ' \
|
66
|
+
'started and stopped. A stopped source is equivalent to ' \
|
67
|
+
'stopping the source through application-specific means, ' \
|
68
|
+
'and a source can be started or stopped both through this ' \
|
69
|
+
'interface as well as via the external application. A ' \
|
70
|
+
'stopped source is still monitored for availability and ' \
|
71
|
+
'policies can still run against a stopped source, if ' \
|
72
|
+
'applicable. Linked sources cannot be stopped, only virtual '\
|
73
|
+
'sources managed by the server can be stopped via this ' \
|
74
|
+
'mechanism.'
|
75
|
+
input String
|
76
|
+
name :stop
|
77
|
+
end
|
78
|
+
|
79
|
+
post '/resources/json/delphix/source/{ref}/upgrade' do
|
80
|
+
description 'Upgrades the given source. This upgrade operation changes ' \
|
81
|
+
'the repository of the source to a higher version repository.'
|
82
|
+
input String
|
83
|
+
name :upgrade
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
# Delphix Source API template
|
3
|
+
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :source_config do
|
6
|
+
description 'The source config represents the dynamically discovered ' \
|
7
|
+
'attributes of a source.'
|
8
|
+
root '/resources/json/delphix/sourceconfig'
|
9
|
+
|
10
|
+
get '/resources/json/delphix/sourceconfig' do
|
11
|
+
description 'Returns a list of source configs within the repository or ' \
|
12
|
+
'the environment.'
|
13
|
+
returns Array
|
14
|
+
name :list
|
15
|
+
end
|
16
|
+
|
17
|
+
get '/resources/json/delphix/sourceconfig/{ref}' do
|
18
|
+
description 'Retrieve the specified SourceConfig object.'
|
19
|
+
returns Object
|
20
|
+
name :read
|
21
|
+
end
|
22
|
+
|
23
|
+
post '/resources/json/delphix/sourceconfig' do
|
24
|
+
description 'Create a new SourceConfig object.'
|
25
|
+
returns String
|
26
|
+
name :create
|
27
|
+
end
|
28
|
+
|
29
|
+
post '/resources/json/delphix/sourceconfig/{ref}' do
|
30
|
+
description 'Update the specified SourceConfig object.'
|
31
|
+
input String
|
32
|
+
name :update
|
33
|
+
end
|
34
|
+
|
35
|
+
delete '/resources/json/delphix/sourceconfig/{ref}' do
|
36
|
+
description 'Delete the specified SourceConfig object.'
|
37
|
+
input String
|
38
|
+
name :delete
|
39
|
+
end
|
40
|
+
|
41
|
+
delete '/resources/json/delphix/sourceconfig/{ref}/defaultType' do
|
42
|
+
description 'None available'
|
43
|
+
input String
|
44
|
+
name :defaultType
|
45
|
+
end
|
46
|
+
|
47
|
+
delete '/resources/json/delphix/sourceconfig/{ref}/validateCredentials' do
|
48
|
+
description 'Tests the validity of the supplied database credentials, ' \
|
49
|
+
'returning an error if unable to connect to the database'
|
50
|
+
input String
|
51
|
+
name :defaultType
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
# Delphix Source Environment DSL
|
3
|
+
#
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :source_environment do
|
6
|
+
description 'The generic source environment schema.'
|
7
|
+
root '/resources/json/delphix/environment'
|
8
|
+
|
9
|
+
get '/resources/json/delphix/environment' do
|
10
|
+
description 'Returns the list of all source environments.'
|
11
|
+
returns Array
|
12
|
+
name :list
|
13
|
+
end
|
14
|
+
|
15
|
+
get '/resources/json/delphix/environment/{ref}' do
|
16
|
+
description 'Retrieve the specified SourceEnvironment object.'
|
17
|
+
returns Object
|
18
|
+
name :read
|
19
|
+
end
|
20
|
+
|
21
|
+
post '/resources/json/delphix/environment' do
|
22
|
+
description 'Create a new SourceEnvironment object.'
|
23
|
+
returns String
|
24
|
+
name :create
|
25
|
+
end
|
26
|
+
|
27
|
+
post '/resources/json/delphix/environment/{ref}' do
|
28
|
+
description 'Update the specified SourceEnvironment object.'
|
29
|
+
input String
|
30
|
+
name :update
|
31
|
+
end
|
32
|
+
|
33
|
+
delete '/resources/json/delphix/environment/{ref}' do
|
34
|
+
description 'Delete the specified SourceEnvironment object.'
|
35
|
+
input String
|
36
|
+
name :delete
|
37
|
+
end
|
38
|
+
|
39
|
+
post '/resources/json/delphix/environment/{ref}/disable' do
|
40
|
+
description 'Disables the given environment.'
|
41
|
+
input String
|
42
|
+
name :disable
|
43
|
+
end
|
44
|
+
|
45
|
+
post '/resources/json/delphix/environment/{ref}/enable' do
|
46
|
+
description 'Enables the given environment. This is only applicable for ' \
|
47
|
+
'disabled environments.'
|
48
|
+
input String
|
49
|
+
name :enable
|
50
|
+
end
|
51
|
+
|
52
|
+
post '/resources/json/delphix/environment/{ref}/refresh' do
|
53
|
+
description 'Refreshes the given environment.'
|
54
|
+
input String
|
55
|
+
name :refresh
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
# Delphix Source API template
|
3
|
+
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :source_repository do
|
6
|
+
description 'Source repositories are containers for SourceConfig objects. '\
|
7
|
+
'Each Environment can contain any number of repositories, and '\
|
8
|
+
'repositories can contain any number of source ' \
|
9
|
+
'configurations. A repository typically corresponds to a ' \
|
10
|
+
'database installation.'
|
11
|
+
root '/resources/json/delphix/repository'
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
# Delphix Source API template
|
3
|
+
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :system_info do
|
6
|
+
description 'Retrieve system-wide properties and manage the state of ' \
|
7
|
+
'the system.'
|
8
|
+
root '/resources/json/delphix/system'
|
9
|
+
|
10
|
+
get '/resources/json/delphix/system' do
|
11
|
+
description 'Retrieve the specified SystemInfo object.'
|
12
|
+
returns Array
|
13
|
+
name :list
|
14
|
+
end
|
15
|
+
|
16
|
+
post '/resources/json/delphix/system' do
|
17
|
+
description 'Update the specified SystemInfo object.'
|
18
|
+
name :update
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
# Delphix Source API template
|
3
|
+
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :timeflow do
|
6
|
+
description 'Timeflows represent a single provisionable timeline within a '\
|
7
|
+
'Database. The Delphix system currently only supports one ' \
|
8
|
+
'timeflow per database, though this may expand in the future. '\
|
9
|
+
'Each database has the notion of the `current` timeflow, ' \
|
10
|
+
'either the timeflow being synced from an external source ' \
|
11
|
+
'(for dSources) or the actively provisioned timeflow (for ' \
|
12
|
+
'VDBs). With only one timeflow supported per database, the ' \
|
13
|
+
'current timeflow is always the one and only timeflow for ' \
|
14
|
+
'the database.'
|
15
|
+
root '/resources/json/delphix/timeflow'
|
16
|
+
|
17
|
+
get '/resources/json/delphix/timeflow' do
|
18
|
+
description 'List Timeflow objects on the system.'
|
19
|
+
returns Array
|
20
|
+
name :list
|
21
|
+
end
|
22
|
+
|
23
|
+
get '/resources/json/delphix/timeflow/{ref}' do
|
24
|
+
description 'Retrieve the specified Timeflow object.'
|
25
|
+
returns Array
|
26
|
+
name :read
|
27
|
+
end
|
28
|
+
|
29
|
+
post '/resources/json/delphix/timeflow/{ref}/repair' do
|
30
|
+
description 'Manually fetch log files to repair a portion of a timeflow.'
|
31
|
+
name :repair
|
32
|
+
end
|
33
|
+
|
34
|
+
post '/resources/json/delphix/timeflow/{ref}/timeflowRanges' do
|
35
|
+
description 'Fetches timeflow ranges in between the specified start and ' \
|
36
|
+
'end locations.'
|
37
|
+
name :timeflowRanges
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
# Delphix Source API template
|
3
|
+
|
4
|
+
Croesus::DSL.evaluate do
|
5
|
+
resource :timeflow do
|
6
|
+
description 'Timeflow snapshots represent a point in time within a ' \
|
7
|
+
'Timeflow that is used as the base point for provisioning. A ' \
|
8
|
+
'provisioning operation begins at a timeflow snapshot and ' \
|
9
|
+
'performs additional operations to bring the database to the ' \
|
10
|
+
'requested state. Snapshots themselves may or may not be ' \
|
11
|
+
'provisionable, and can be associated with dSources or VDBs.'
|
12
|
+
root '/resources/json/delphix/snapshot'
|
13
|
+
|
14
|
+
get '/resources/json/delphix/snapshot' do
|
15
|
+
description 'Returns a list of snapshots on the system or within a ' \
|
16
|
+
'particular object. By default, all snapshots within the ' \
|
17
|
+
'domain are listed.'
|
18
|
+
returns Array
|
19
|
+
name :list
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/resources/json/delphix/snapshot/{ref}' do
|
23
|
+
description 'Retrieve the specified TimeflowSnapshot object.'
|
24
|
+
returns Array
|
25
|
+
name :read
|
26
|
+
end
|
27
|
+
|
28
|
+
post '/resources/json/delphix/snapshot/{ref}' do
|
29
|
+
description 'Update the specified TimeflowSnapshot object.'
|
30
|
+
name :update
|
31
|
+
end
|
32
|
+
|
33
|
+
delete '/resources/json/delphix/snapshot/{ref}' do
|
34
|
+
description 'Delete the specified TimeflowSnapshot object.'
|
35
|
+
name :delete
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
#
|
5
|
+
# Copyright (C) 2014 Stefano Harding
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied. See the License for the specific language governing
|
17
|
+
# permissions and limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'securerandom'
|
21
|
+
require 'time'
|
22
|
+
|
23
|
+
module Croesus::Utils
|
24
|
+
def self.included(base)
|
25
|
+
base.extend(ClassMethods)
|
26
|
+
end
|
27
|
+
private_class_method :included
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
def callable(call_her)
|
31
|
+
call_her.respond_to?(:call) ? call_her : lambda { call_her }
|
32
|
+
end
|
33
|
+
|
34
|
+
def camelize(underscored_word)
|
35
|
+
underscored_word.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
|
36
|
+
end
|
37
|
+
|
38
|
+
def classify(table_name)
|
39
|
+
camelize singularize(table_name.to_s.sub(/.*\./, ''))
|
40
|
+
end
|
41
|
+
|
42
|
+
def class_name
|
43
|
+
demodulize(self.class)
|
44
|
+
end
|
45
|
+
|
46
|
+
def caller_name
|
47
|
+
caller_locations(2, 1).first.label
|
48
|
+
end
|
49
|
+
|
50
|
+
def demodulize(class_name_in_module)
|
51
|
+
class_name_in_module.to_s.sub(/^.*::/, '')
|
52
|
+
end
|
53
|
+
|
54
|
+
def pluralize(word)
|
55
|
+
word.to_s.sub(/([^s])$/, '\1s')
|
56
|
+
end
|
57
|
+
|
58
|
+
def singularize(word)
|
59
|
+
word.to_s.sub(/s$/, '').sub(/ie$/, 'y')
|
60
|
+
end
|
61
|
+
|
62
|
+
def underscore(camel_cased_word)
|
63
|
+
word = camel_cased_word.to_s.dup
|
64
|
+
word.gsub!(/::/, '/')
|
65
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
66
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
67
|
+
word.tr! '-', '_'
|
68
|
+
word.downcase!
|
69
|
+
word
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return the date and time in "HTTP-date" format as defined by RFC 7231.
|
73
|
+
#
|
74
|
+
# @return [Date,Time] in "HTTP-date" format
|
75
|
+
def utc_httpdate
|
76
|
+
Time.now.utc.httpdate
|
77
|
+
end
|
78
|
+
|
79
|
+
def request_id
|
80
|
+
SecureRandom.uuid
|
81
|
+
end
|
82
|
+
|
83
|
+
def twenty_four_hours_ago
|
84
|
+
Time.now - ( 60 * 60 * 24)
|
85
|
+
end
|
86
|
+
|
87
|
+
def verify_options(accepted, actual) # @private
|
88
|
+
return unless debug || $DEBUG
|
89
|
+
unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
|
90
|
+
raise Croesus::Errors::UnknownOption,
|
91
|
+
"\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" <<
|
92
|
+
"Accepted options are: #{accepted.inspect}"
|
93
|
+
end
|
94
|
+
yield if block_given?
|
95
|
+
end
|
96
|
+
end # module ClassMethods
|
97
|
+
|
98
|
+
def callable(call_her)
|
99
|
+
call_her.respond_to?(:call) ? call_her : lambda { call_her }
|
100
|
+
end
|
101
|
+
|
102
|
+
def camelize(underscored_word)
|
103
|
+
underscored_word.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
|
104
|
+
end
|
105
|
+
|
106
|
+
def classify(table_name)
|
107
|
+
camelize singularize(table_name.to_s.sub(/.*\./, ''))
|
108
|
+
end
|
109
|
+
|
110
|
+
def class_name
|
111
|
+
demodulize(self.class)
|
112
|
+
end
|
113
|
+
|
114
|
+
def caller_name
|
115
|
+
caller_locations(2, 1).first.label
|
116
|
+
end
|
117
|
+
|
118
|
+
def demodulize(class_name_in_module)
|
119
|
+
class_name_in_module.to_s.sub(/^.*::/, '')
|
120
|
+
end
|
121
|
+
|
122
|
+
def pluralize(word)
|
123
|
+
word.to_s.sub(/([^s])$/, '\1s')
|
124
|
+
end
|
125
|
+
|
126
|
+
def singularize(word)
|
127
|
+
word.to_s.sub(/s$/, '').sub(/ie$/, 'y')
|
128
|
+
end
|
129
|
+
|
130
|
+
def underscore(camel_cased_word)
|
131
|
+
word = camel_cased_word.to_s.dup
|
132
|
+
word.gsub!(/::/, '/')
|
133
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
134
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
135
|
+
word.tr! '-', '_'
|
136
|
+
word.downcase!
|
137
|
+
word
|
138
|
+
end
|
139
|
+
|
140
|
+
# Return the date and time in "HTTP-date" format as defined by RFC 7231.
|
141
|
+
#
|
142
|
+
# @return [Date,Time] in "HTTP-date" format
|
143
|
+
def utc_httpdate
|
144
|
+
Time.now.utc.httpdate
|
145
|
+
end
|
146
|
+
|
147
|
+
def request_id
|
148
|
+
SecureRandom.uuid
|
149
|
+
end
|
150
|
+
|
151
|
+
def twenty_four_hours_ago
|
152
|
+
Time.now - ( 60 * 60 * 24)
|
153
|
+
end
|
154
|
+
|
155
|
+
def verify_options(accepted, actual) # @private
|
156
|
+
return unless debug || $DEBUG
|
157
|
+
unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
|
158
|
+
raise Croesus::Errors::UnknownOption,
|
159
|
+
"\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" <<
|
160
|
+
"Accepted options are: #{accepted.inspect}"
|
161
|
+
end
|
162
|
+
yield if block_given?
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns the columns and lines of the current tty.
|
166
|
+
#
|
167
|
+
# @return [Integer]
|
168
|
+
# number of columns and lines of tty, returns [0, 0] if no tty is present.
|
169
|
+
#
|
170
|
+
# @api public
|
171
|
+
def terminal_dimensions
|
172
|
+
[0, 0] unless STDOUT.tty?
|
173
|
+
[80, 40] if OS.windows?
|
174
|
+
|
175
|
+
if ENV['COLUMNS'] && ENV['LINES']
|
176
|
+
[ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
|
177
|
+
elsif ENV['TERM'] && command_in_path?('tput')
|
178
|
+
[`tput cols`.to_i, `tput lines`.to_i]
|
179
|
+
elsif command_in_path?('stty')
|
180
|
+
`stty size`.scan(/\d+/).map {|s| s.to_i }
|
181
|
+
else
|
182
|
+
[0, 0]
|
183
|
+
end
|
184
|
+
rescue
|
185
|
+
[0, 0]
|
186
|
+
end
|
187
|
+
|
188
|
+
# Checks in PATH returns true if the command is found
|
189
|
+
def command_in_path?(command)
|
190
|
+
found = ENV['PATH'].split(File::PATH_SEPARATOR).map do |p|
|
191
|
+
File.exist?(File.join(p, command))
|
192
|
+
end
|
193
|
+
found.include?(true)
|
194
|
+
end
|
195
|
+
|
196
|
+
# Runs a code block, and retries it when an exception occurs. Should the
|
197
|
+
# number of retries be reached without success, the last exception will be
|
198
|
+
# raised.
|
199
|
+
#
|
200
|
+
# @param opts [Hash{Symbol => Value}]
|
201
|
+
# @option opts [Fixnum] :tries
|
202
|
+
# number of attempts to retry before raising the last exception
|
203
|
+
# @option opts [Fixnum] :sleep
|
204
|
+
# number of seconds to wait between retries, use lambda to exponentially
|
205
|
+
# increasing delay between retries
|
206
|
+
# @option opts [Array(Exception)] :on
|
207
|
+
# the type of exception(s) to catch and retry on
|
208
|
+
# @option opts [Regex] :matching
|
209
|
+
# match based on the exception message
|
210
|
+
# @option opts [Block] :ensure
|
211
|
+
# ensure a block of code is executed, regardless of whether an exception
|
212
|
+
# is raised
|
213
|
+
#
|
214
|
+
# @return [Block]
|
215
|
+
#
|
216
|
+
def retrier(opts = {}, &block)
|
217
|
+
defaults = {
|
218
|
+
tries: 2,
|
219
|
+
sleep: 1,
|
220
|
+
on: StandardError,
|
221
|
+
matching: /.*/,
|
222
|
+
:ensure => Proc.new {}
|
223
|
+
}
|
224
|
+
|
225
|
+
check_for_invalid_options(opts, defaults)
|
226
|
+
defaults.merge!(opts)
|
227
|
+
|
228
|
+
return if defaults[:tries] == 0
|
229
|
+
|
230
|
+
on_exception, tries = [defaults[:on]].flatten, defaults[:tries]
|
231
|
+
retries = 0
|
232
|
+
retry_exception = nil
|
233
|
+
|
234
|
+
begin
|
235
|
+
yield retries, retry_exception
|
236
|
+
rescue *on_exception => exception
|
237
|
+
raise unless exception.message =~ defaults[:matching]
|
238
|
+
raise if retries+1 >= defaults[:tries]
|
239
|
+
|
240
|
+
# Interrupt Exception could be raised while sleeping
|
241
|
+
begin
|
242
|
+
sleep defaults[:sleep].respond_to?(:call) ?
|
243
|
+
defaults[:sleep].call(retries) : defaults[:sleep]
|
244
|
+
rescue *on_exception
|
245
|
+
end
|
246
|
+
|
247
|
+
retries += 1
|
248
|
+
retry_exception = exception
|
249
|
+
retry
|
250
|
+
ensure
|
251
|
+
defaults[:ensure].call(retries)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
private # P R O P R I E T À P R I V A T A Vietato L'accesso
|
256
|
+
|
257
|
+
def check_for_invalid_options(custom_options, defaults)
|
258
|
+
invalid_options = defaults.merge(custom_options).keys - defaults.keys
|
259
|
+
raise ArgumentError.new('[Retrier] Invalid options: ' \
|
260
|
+
"#{invalid_options.join(", ")}") unless invalid_options.empty?
|
261
|
+
end
|
262
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
#
|
5
|
+
# Copyright (C) 2014 Stefano Harding
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied. See the License for the specific language governing
|
17
|
+
# permissions and limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
module Croesus::Validations
|
21
|
+
class Many
|
22
|
+
attr_reader :validation
|
23
|
+
def initialize(validation)
|
24
|
+
@validation = validation
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
#
|
5
|
+
# Copyright (C) 2014 Stefano Harding
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied. See the License for the specific language governing
|
17
|
+
# permissions and limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
module Croesus::Validations
|
21
|
+
class Optional
|
22
|
+
attr_reader :validation
|
23
|
+
def initialize(validation)
|
24
|
+
@validation = validation
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|