apisonator 2.100.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +317 -0
- data/Gemfile +11 -0
- data/Gemfile.base +65 -0
- data/Gemfile.lock +319 -0
- data/Gemfile.on_prem +1 -0
- data/Gemfile.on_prem.lock +297 -0
- data/LICENSE +202 -0
- data/NOTICE +15 -0
- data/README.md +230 -0
- data/Rakefile +287 -0
- data/apisonator.gemspec +47 -0
- data/app/api/api.rb +13 -0
- data/app/api/internal/alert_limits.rb +32 -0
- data/app/api/internal/application_keys.rb +49 -0
- data/app/api/internal/application_referrer_filters.rb +43 -0
- data/app/api/internal/applications.rb +77 -0
- data/app/api/internal/errors.rb +54 -0
- data/app/api/internal/events.rb +42 -0
- data/app/api/internal/internal.rb +104 -0
- data/app/api/internal/metrics.rb +40 -0
- data/app/api/internal/service_tokens.rb +46 -0
- data/app/api/internal/services.rb +58 -0
- data/app/api/internal/stats.rb +42 -0
- data/app/api/internal/usagelimits.rb +62 -0
- data/app/api/internal/utilization.rb +23 -0
- data/bin/3scale_backend +223 -0
- data/bin/3scale_backend_worker +26 -0
- data/config.ru +4 -0
- data/config/puma.rb +192 -0
- data/config/schedule.rb +9 -0
- data/ext/mkrf_conf.rb +64 -0
- data/lib/3scale/backend.rb +67 -0
- data/lib/3scale/backend/alert_limit.rb +56 -0
- data/lib/3scale/backend/alerts.rb +137 -0
- data/lib/3scale/backend/analytics/kinesis.rb +3 -0
- data/lib/3scale/backend/analytics/kinesis/adapter.rb +180 -0
- data/lib/3scale/backend/analytics/kinesis/exporter.rb +86 -0
- data/lib/3scale/backend/analytics/kinesis/job.rb +135 -0
- data/lib/3scale/backend/analytics/redshift.rb +3 -0
- data/lib/3scale/backend/analytics/redshift/adapter.rb +367 -0
- data/lib/3scale/backend/analytics/redshift/importer.rb +83 -0
- data/lib/3scale/backend/analytics/redshift/job.rb +33 -0
- data/lib/3scale/backend/application.rb +330 -0
- data/lib/3scale/backend/application_events.rb +76 -0
- data/lib/3scale/backend/background_job.rb +65 -0
- data/lib/3scale/backend/configurable.rb +20 -0
- data/lib/3scale/backend/configuration.rb +151 -0
- data/lib/3scale/backend/configuration/loader.rb +42 -0
- data/lib/3scale/backend/constants.rb +19 -0
- data/lib/3scale/backend/cors.rb +84 -0
- data/lib/3scale/backend/distributed_lock.rb +67 -0
- data/lib/3scale/backend/environment.rb +21 -0
- data/lib/3scale/backend/error_storage.rb +52 -0
- data/lib/3scale/backend/errors.rb +343 -0
- data/lib/3scale/backend/event_storage.rb +120 -0
- data/lib/3scale/backend/experiment.rb +84 -0
- data/lib/3scale/backend/extensions.rb +5 -0
- data/lib/3scale/backend/extensions/array.rb +19 -0
- data/lib/3scale/backend/extensions/hash.rb +26 -0
- data/lib/3scale/backend/extensions/nil_class.rb +13 -0
- data/lib/3scale/backend/extensions/redis.rb +44 -0
- data/lib/3scale/backend/extensions/string.rb +13 -0
- data/lib/3scale/backend/extensions/time.rb +110 -0
- data/lib/3scale/backend/failed_jobs_scheduler.rb +141 -0
- data/lib/3scale/backend/job_fetcher.rb +122 -0
- data/lib/3scale/backend/listener.rb +728 -0
- data/lib/3scale/backend/listener_metrics.rb +99 -0
- data/lib/3scale/backend/logging.rb +48 -0
- data/lib/3scale/backend/logging/external.rb +44 -0
- data/lib/3scale/backend/logging/external/impl.rb +93 -0
- data/lib/3scale/backend/logging/external/impl/airbrake.rb +66 -0
- data/lib/3scale/backend/logging/external/impl/bugsnag.rb +69 -0
- data/lib/3scale/backend/logging/external/impl/default.rb +18 -0
- data/lib/3scale/backend/logging/external/resque.rb +57 -0
- data/lib/3scale/backend/logging/logger.rb +18 -0
- data/lib/3scale/backend/logging/middleware.rb +62 -0
- data/lib/3scale/backend/logging/middleware/json_writer.rb +21 -0
- data/lib/3scale/backend/logging/middleware/text_writer.rb +60 -0
- data/lib/3scale/backend/logging/middleware/writer.rb +143 -0
- data/lib/3scale/backend/logging/worker.rb +107 -0
- data/lib/3scale/backend/manifest.rb +80 -0
- data/lib/3scale/backend/memoizer.rb +277 -0
- data/lib/3scale/backend/metric.rb +275 -0
- data/lib/3scale/backend/metric/collection.rb +91 -0
- data/lib/3scale/backend/oauth.rb +4 -0
- data/lib/3scale/backend/oauth/token.rb +26 -0
- data/lib/3scale/backend/oauth/token_key.rb +30 -0
- data/lib/3scale/backend/oauth/token_storage.rb +313 -0
- data/lib/3scale/backend/oauth/token_value.rb +25 -0
- data/lib/3scale/backend/period.rb +3 -0
- data/lib/3scale/backend/period/boundary.rb +107 -0
- data/lib/3scale/backend/period/cache.rb +28 -0
- data/lib/3scale/backend/period/period.rb +402 -0
- data/lib/3scale/backend/queue_storage.rb +16 -0
- data/lib/3scale/backend/rack.rb +49 -0
- data/lib/3scale/backend/rack/exception_catcher.rb +136 -0
- data/lib/3scale/backend/rack/internal_error_catcher.rb +23 -0
- data/lib/3scale/backend/rack/prometheus.rb +19 -0
- data/lib/3scale/backend/saas.rb +6 -0
- data/lib/3scale/backend/saas_analytics.rb +4 -0
- data/lib/3scale/backend/server.rb +30 -0
- data/lib/3scale/backend/server/falcon.rb +52 -0
- data/lib/3scale/backend/server/puma.rb +71 -0
- data/lib/3scale/backend/service.rb +317 -0
- data/lib/3scale/backend/service_token.rb +97 -0
- data/lib/3scale/backend/stats.rb +8 -0
- data/lib/3scale/backend/stats/aggregator.rb +170 -0
- data/lib/3scale/backend/stats/aggregators/base.rb +72 -0
- data/lib/3scale/backend/stats/aggregators/response_code.rb +58 -0
- data/lib/3scale/backend/stats/aggregators/usage.rb +34 -0
- data/lib/3scale/backend/stats/bucket_reader.rb +135 -0
- data/lib/3scale/backend/stats/bucket_storage.rb +108 -0
- data/lib/3scale/backend/stats/cleaner.rb +195 -0
- data/lib/3scale/backend/stats/codes_commons.rb +14 -0
- data/lib/3scale/backend/stats/delete_job_def.rb +60 -0
- data/lib/3scale/backend/stats/key_generator.rb +73 -0
- data/lib/3scale/backend/stats/keys.rb +104 -0
- data/lib/3scale/backend/stats/partition_eraser_job.rb +58 -0
- data/lib/3scale/backend/stats/partition_generator_job.rb +46 -0
- data/lib/3scale/backend/stats/period_commons.rb +34 -0
- data/lib/3scale/backend/stats/stats_parser.rb +141 -0
- data/lib/3scale/backend/stats/storage.rb +113 -0
- data/lib/3scale/backend/statsd.rb +14 -0
- data/lib/3scale/backend/storable.rb +35 -0
- data/lib/3scale/backend/storage.rb +40 -0
- data/lib/3scale/backend/storage_async.rb +4 -0
- data/lib/3scale/backend/storage_async/async_redis.rb +21 -0
- data/lib/3scale/backend/storage_async/client.rb +205 -0
- data/lib/3scale/backend/storage_async/pipeline.rb +79 -0
- data/lib/3scale/backend/storage_async/resque_extensions.rb +30 -0
- data/lib/3scale/backend/storage_helpers.rb +278 -0
- data/lib/3scale/backend/storage_key_helpers.rb +9 -0
- data/lib/3scale/backend/storage_sync.rb +43 -0
- data/lib/3scale/backend/transaction.rb +62 -0
- data/lib/3scale/backend/transactor.rb +177 -0
- data/lib/3scale/backend/transactor/limit_headers.rb +54 -0
- data/lib/3scale/backend/transactor/notify_batcher.rb +139 -0
- data/lib/3scale/backend/transactor/notify_job.rb +47 -0
- data/lib/3scale/backend/transactor/process_job.rb +33 -0
- data/lib/3scale/backend/transactor/report_job.rb +84 -0
- data/lib/3scale/backend/transactor/status.rb +236 -0
- data/lib/3scale/backend/transactor/usage_report.rb +182 -0
- data/lib/3scale/backend/usage.rb +63 -0
- data/lib/3scale/backend/usage_limit.rb +115 -0
- data/lib/3scale/backend/use_cases/provider_key_change_use_case.rb +60 -0
- data/lib/3scale/backend/util.rb +17 -0
- data/lib/3scale/backend/validators.rb +26 -0
- data/lib/3scale/backend/validators/base.rb +36 -0
- data/lib/3scale/backend/validators/key.rb +17 -0
- data/lib/3scale/backend/validators/limits.rb +57 -0
- data/lib/3scale/backend/validators/oauth_key.rb +15 -0
- data/lib/3scale/backend/validators/oauth_setting.rb +15 -0
- data/lib/3scale/backend/validators/redirect_uri.rb +33 -0
- data/lib/3scale/backend/validators/referrer.rb +60 -0
- data/lib/3scale/backend/validators/service_state.rb +15 -0
- data/lib/3scale/backend/validators/state.rb +15 -0
- data/lib/3scale/backend/version.rb +5 -0
- data/lib/3scale/backend/views/oauth_access_tokens.builder +14 -0
- data/lib/3scale/backend/views/oauth_app_id_by_token.builder +4 -0
- data/lib/3scale/backend/worker.rb +87 -0
- data/lib/3scale/backend/worker_async.rb +88 -0
- data/lib/3scale/backend/worker_metrics.rb +44 -0
- data/lib/3scale/backend/worker_sync.rb +32 -0
- data/lib/3scale/bundler_shim.rb +17 -0
- data/lib/3scale/prometheus_server.rb +10 -0
- data/lib/3scale/tasks/connectivity.rake +41 -0
- data/lib/3scale/tasks/helpers.rb +3 -0
- data/lib/3scale/tasks/helpers/environment.rb +23 -0
- data/lib/3scale/tasks/stats.rake +131 -0
- data/lib/3scale/tasks/swagger.rake +46 -0
- data/licenses.xml +1215 -0
- metadata +227 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module API
|
4
|
+
internal_api '/services/:service_id/metrics' do
|
5
|
+
get '/:id' do |service_id, id|
|
6
|
+
metric = Metric.load service_id, id
|
7
|
+
if metric
|
8
|
+
{ status: :found, metric: metric.to_hash }.to_json
|
9
|
+
else
|
10
|
+
[404, headers, { status: :not_found, error: 'metric not found' }.to_json]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
post '/:id' do |service_id, id|
|
15
|
+
metric_attrs = api_params Metric
|
16
|
+
metric_attrs[:service_id] = service_id
|
17
|
+
metric_attrs[:id] = id
|
18
|
+
metric = Metric.save metric_attrs
|
19
|
+
[201, headers, { status: :created, metric: metric.to_hash }.to_json]
|
20
|
+
end
|
21
|
+
|
22
|
+
put '/:id' do |service_id, id|
|
23
|
+
metric_attrs = api_params Metric
|
24
|
+
metric_attrs[:service_id] = service_id
|
25
|
+
metric_attrs[:id] = id
|
26
|
+
metric = Metric.save metric_attrs
|
27
|
+
{ status: :modified, metric: metric.to_hash }.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
delete '/:id' do |service_id, id|
|
31
|
+
if Metric.delete(service_id, id)
|
32
|
+
{ status: :deleted }.to_json
|
33
|
+
else
|
34
|
+
[404, headers, { status: :not_found, error: 'metric not found' }.to_json]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module API
|
4
|
+
internal_api '/service_tokens' do
|
5
|
+
|
6
|
+
head '/:token/:service_id/' do |token, service_id|
|
7
|
+
ServiceToken.exists?(token, service_id) ? 200 : 404
|
8
|
+
end
|
9
|
+
|
10
|
+
post '/' do
|
11
|
+
check_tokens_param!
|
12
|
+
|
13
|
+
token_pairs = @service_tokens.map do |token, token_info|
|
14
|
+
{ service_token: token, service_id: token_info[:service_id] }
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
ServiceToken.save_pairs(token_pairs)
|
19
|
+
[201, headers, { status: :created }.to_json]
|
20
|
+
rescue ServiceToken::ValidationError => e
|
21
|
+
halt(e.http_code, { status: :error, error: e.message }.to_json)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
delete '/' do
|
26
|
+
check_tokens_param!
|
27
|
+
|
28
|
+
deleted = @service_tokens.count do |token|
|
29
|
+
ServiceToken.delete(token[:service_token], token[:service_id]) == 1
|
30
|
+
end
|
31
|
+
|
32
|
+
{ status: :deleted, count: deleted }.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def check_tokens_param!
|
38
|
+
@service_tokens = params[:service_tokens]
|
39
|
+
unless @service_tokens
|
40
|
+
halt(400, { error: "missing parameter 'service_tokens'".freeze }.to_json)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require '3scale/backend/use_cases/provider_key_change_use_case'
|
2
|
+
|
3
|
+
module ThreeScale
|
4
|
+
module Backend
|
5
|
+
module API
|
6
|
+
internal_api '/services' do
|
7
|
+
get '/:id' do
|
8
|
+
service = Service.load_by_id(params[:id])
|
9
|
+
if service
|
10
|
+
{ status: :found, service: service.to_hash }.to_json
|
11
|
+
else
|
12
|
+
[404, headers, {error: :not_found}.to_json]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
post '/' do
|
17
|
+
svc_attrs = api_params Service
|
18
|
+
service = Service.save!(svc_attrs)
|
19
|
+
[201, headers, {service: service.to_hash, status: :created}.to_json]
|
20
|
+
end
|
21
|
+
|
22
|
+
put '/:id' do
|
23
|
+
svc_attrs = api_params Service
|
24
|
+
service = Service.load_by_id(params[:id])
|
25
|
+
if service
|
26
|
+
svc_attrs.each do |attr, value|
|
27
|
+
service.send "#{attr}=", value
|
28
|
+
end
|
29
|
+
service.save!
|
30
|
+
else
|
31
|
+
service = Service.save!(svc_attrs)
|
32
|
+
end
|
33
|
+
{service: service.to_hash, status: :ok}.to_json
|
34
|
+
end
|
35
|
+
|
36
|
+
put '/change_provider_key/:key' do
|
37
|
+
begin
|
38
|
+
ProviderKeyChangeUseCase.new(params[:key], params[:new_key]).process
|
39
|
+
{status: :ok}.to_json
|
40
|
+
rescue InvalidProviderKeys, ProviderKeyExists, ProviderKeyNotFound => e
|
41
|
+
respond_with_400 e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
delete '/:id' do
|
46
|
+
begin
|
47
|
+
Service.delete_by_id params[:id]
|
48
|
+
{status: :deleted}.to_json
|
49
|
+
rescue ServiceIsDefaultService => e
|
50
|
+
respond_with_400 e
|
51
|
+
rescue ServiceIdInvalid => e
|
52
|
+
respond_with_404 e
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module API
|
4
|
+
internal_api '/services/:service_id/stats' do
|
5
|
+
before do
|
6
|
+
respond_with_404('service not found') unless Service.exists?(params[:service_id])
|
7
|
+
end
|
8
|
+
|
9
|
+
# This is very slow and needs to be disabled until the performance
|
10
|
+
# issues are solved. In the meanwhile, the job will just return OK.
|
11
|
+
=begin
|
12
|
+
delete '' do |service_id|
|
13
|
+
delete_stats_job_attrs = api_params Stats::DeleteJobDef
|
14
|
+
delete_stats_job_attrs[:service_id] = service_id
|
15
|
+
delete_stats_job_attrs[:from] = delete_stats_job_attrs[:from].to_i
|
16
|
+
delete_stats_job_attrs[:to] = delete_stats_job_attrs[:to].to_i
|
17
|
+
begin
|
18
|
+
Stats::DeleteJobDef.new(delete_stats_job_attrs).run_async
|
19
|
+
rescue DeleteServiceStatsValidationError => e
|
20
|
+
[400, headers, { status: :error, error: e.message }.to_json]
|
21
|
+
else
|
22
|
+
{ status: :to_be_deleted }.to_json
|
23
|
+
end
|
24
|
+
=end
|
25
|
+
|
26
|
+
# This is an alternative to the above. It just adds the service to a
|
27
|
+
# Redis set to marked is as "to be deleted".
|
28
|
+
# Later a script can read that set and actually delete the keys.
|
29
|
+
# Read the docs of the Stats::Cleaner class for more details.
|
30
|
+
#
|
31
|
+
# Notice that this method ignores the "from" and "to" parameters. When
|
32
|
+
# system calls this method, they're always interested in deleting all
|
33
|
+
# the keys. They were just passing "from" and "to" to make the
|
34
|
+
# implementation of the option above easier.
|
35
|
+
delete '' do |service_id|
|
36
|
+
Stats::Cleaner.mark_service_to_be_deleted(service_id)
|
37
|
+
{ status: :to_be_deleted }.to_json
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module API
|
4
|
+
# Note: ideally this URL should NOT look like this.
|
5
|
+
#
|
6
|
+
# We have it this way because the entities don't fit a hierarchical
|
7
|
+
# scheme since their relations are complex:
|
8
|
+
#
|
9
|
+
# * We don't have UsageLimit ID's per se
|
10
|
+
# * Plan is a denormalized entity in backend
|
11
|
+
# * Metrics need to be loaded from a given Service
|
12
|
+
# * But neither Plan nor Metric are nested wrt each other
|
13
|
+
# * And Service has no other use than being able to load a Metric
|
14
|
+
#
|
15
|
+
# In the end no single URL shape is pleasing enough: specifying some
|
16
|
+
# needed IDs as parameters feels wrong because of the reasons above, but
|
17
|
+
# adding them to the URL makes for really long URLs with no clear
|
18
|
+
# hierarchy for nesting. We chose the latter, but could have chosen almost
|
19
|
+
# any workable form.
|
20
|
+
#
|
21
|
+
internal_api '/services/:service_id/plans/:plan_id/usagelimits' do
|
22
|
+
module UsageLimitsHelper
|
23
|
+
def self.to_hash(service_id, plan_id, metric_id, period, value)
|
24
|
+
{
|
25
|
+
:service_id => service_id,
|
26
|
+
:plan_id => plan_id,
|
27
|
+
:metric_id => metric_id,
|
28
|
+
period.to_sym => value
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
get '/:metric_id/:period' do |service_id, plan_id, metric_id, period|
|
34
|
+
value = UsageLimit.load_value(service_id, plan_id, metric_id, period)
|
35
|
+
if value
|
36
|
+
{ status: :found, usagelimit: UsageLimitsHelper.to_hash(service_id, plan_id,
|
37
|
+
metric_id, period,
|
38
|
+
value) }.to_json
|
39
|
+
else
|
40
|
+
[404, headers, { status: :not_found, error: 'usagelimit not found' }.to_json]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
put '/:metric_id/:period' do |service_id, plan_id, metric_id, period|
|
45
|
+
attributes = params[:usagelimit]
|
46
|
+
halt 400, { status: :error, error: 'missing parameter \'usagelimit\'' }.to_json unless attributes
|
47
|
+
value = attributes[period.to_sym]
|
48
|
+
halt 400, { status: :error, error: "missing parameter '#{period}'" }.to_json unless value
|
49
|
+
ul_hash = UsageLimitsHelper.to_hash(service_id, plan_id, metric_id, period, value)
|
50
|
+
UsageLimit.save(ul_hash)
|
51
|
+
{ status: :modified, usagelimit: ul_hash }.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
delete '/:metric_id/:period' do |service_id, plan_id, metric_id, period|
|
55
|
+
UsageLimit.delete(service_id, plan_id, metric_id, period)
|
56
|
+
{ status: :deleted }.to_json
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module API
|
4
|
+
internal_api '/services/:service_id/applications/:app_id/utilization' do
|
5
|
+
before do
|
6
|
+
unless Service.exists?(params[:service_id])
|
7
|
+
respond_with_404('service not found')
|
8
|
+
end
|
9
|
+
|
10
|
+
unless Application.exists?(params[:service_id], params[:app_id])
|
11
|
+
respond_with_404('application not found')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
get '/' do |service_id, app_id|
|
16
|
+
utilization = Transactor.utilization(service_id, app_id)
|
17
|
+
usage_reports = utilization.map(&:to_h)
|
18
|
+
{ status: :found, utilization: usage_reports }.to_json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/bin/3scale_backend
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
require '3scale/backend/version'
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
class << self
|
7
|
+
def do_exit(code, global, msg='Unknown error')
|
8
|
+
Dir.chdir global[:original_dir]
|
9
|
+
exit_now! msg, code
|
10
|
+
end
|
11
|
+
|
12
|
+
def verbose(global_options, out=STDOUT)
|
13
|
+
out.puts(yield) if global_options[:verbose] || global_options[:'dry-run']
|
14
|
+
end
|
15
|
+
|
16
|
+
def exec(global_options)
|
17
|
+
Process.exec(*yield) unless global_options[:'dry-run']
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def build_cmdline(cmd, global_options, options, args)
|
22
|
+
require '3scale/backend/server'
|
23
|
+
server = ThreeScale::Backend::Server.get global_options[:server]
|
24
|
+
server.send(cmd, global_options, options, args)
|
25
|
+
rescue => e
|
26
|
+
STDERR.puts "Error: #{e.message}#{"\n" + caller_locations(0).join("\n") if global_options[:verbose]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def do_command(cmd, global_options, options, args)
|
30
|
+
argv = build_cmdline cmd, global_options, options, args
|
31
|
+
do_exit 1, global_options, "can't build command line" unless argv
|
32
|
+
argv << global_options[:'extra-args'] if global_options[:'extra-args']
|
33
|
+
verbose(global_options) { "Executing: #{argv.join ' '}" }
|
34
|
+
exec(global_options) { argv }
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_instance_id_options(c)
|
38
|
+
c.desc 'TCP port number where backend listens for connections'
|
39
|
+
c.arg_name 'NUMBER'
|
40
|
+
c.default_value '3000'
|
41
|
+
c.flag :p, :port
|
42
|
+
c.desc 'Filename where backend writes its PID'
|
43
|
+
c.arg_name 'FILENAME'
|
44
|
+
c.flag :pidfile
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
extend GLI::App
|
49
|
+
|
50
|
+
program_desc '3scale_backend launcher'
|
51
|
+
|
52
|
+
version ThreeScale::Backend::VERSION
|
53
|
+
|
54
|
+
CONFIG_FILE = '.backend_launcher.rc.yml'
|
55
|
+
EXPANDED_ROOT_PATH = File.expand_path(File.join('..', '..'), __FILE__)
|
56
|
+
|
57
|
+
config_file File.join(ENV['HOME'] || File.join('', 'tmp'), CONFIG_FILE)
|
58
|
+
|
59
|
+
subcommand_option_handling :normal
|
60
|
+
arguments :strict
|
61
|
+
|
62
|
+
desc 'Load Bundler when running'
|
63
|
+
default_value true
|
64
|
+
switch :b, :bundler
|
65
|
+
|
66
|
+
desc 'Do not actually run anything, just print what would be done'
|
67
|
+
default_value false
|
68
|
+
switch :n, :'dry-run'
|
69
|
+
|
70
|
+
desc 'Verbose mode'
|
71
|
+
default_value false
|
72
|
+
switch :v, :verbose
|
73
|
+
|
74
|
+
desc 'Directory where the app server will expect the code to be at'
|
75
|
+
arg_name 'DIRNAME'
|
76
|
+
flag :z, :directory
|
77
|
+
|
78
|
+
desc "Application server to use with backend"
|
79
|
+
default_value 'puma'
|
80
|
+
arg_name 'SERVER'
|
81
|
+
flag :s, :server
|
82
|
+
|
83
|
+
desc 'Environment backend will use'
|
84
|
+
arg_name 'ENVIRONMENT'
|
85
|
+
default_value 'development'
|
86
|
+
flag :e, :environment
|
87
|
+
|
88
|
+
desc 'Extra command arguments'
|
89
|
+
arg_name 'ARGS'
|
90
|
+
flag :X, :'extra-args'
|
91
|
+
|
92
|
+
pre do |global, command, options, args|
|
93
|
+
# Pre logic here
|
94
|
+
# Return true to proceed; false to abort and not call the
|
95
|
+
# chosen command
|
96
|
+
# Use skips_pre before a command to skip this block
|
97
|
+
# on that command only
|
98
|
+
global[:original_dir] = Dir.pwd
|
99
|
+
if global[:directory]
|
100
|
+
Dir.chdir global[:directory]
|
101
|
+
end
|
102
|
+
if global[:bundler]
|
103
|
+
begin
|
104
|
+
require 'bundler/setup'
|
105
|
+
if !Bundler::SharedHelpers.in_bundle?
|
106
|
+
# Gemfile not found, try with relative Gemfile from us
|
107
|
+
ENV['BUNDLE_GEMFILE'] = File.join(EXPANDED_ROOT_PATH, 'Gemfile')
|
108
|
+
require 'bundler'
|
109
|
+
Bundler.setup
|
110
|
+
end
|
111
|
+
rescue LoadError, Bundler::BundlerError => e
|
112
|
+
do_exit 64, global, "Unable to meet requirements: #{e.message}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
# manifest loading is not strictly necessary, so make it optional
|
116
|
+
begin
|
117
|
+
require '3scale/backend/manifest'
|
118
|
+
global[:manifest] = ThreeScale::Backend::Manifest.report
|
119
|
+
rescue LoadError, NameError, NoMethodError
|
120
|
+
end
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
post do |global,command,options,args|
|
125
|
+
# Post logic here
|
126
|
+
# Use skips_post before a command to skip this
|
127
|
+
# block on that command only
|
128
|
+
Dir.chdir global[:original_dir]
|
129
|
+
end
|
130
|
+
|
131
|
+
on_error do |exception|
|
132
|
+
# Error logic here
|
133
|
+
# return false to skip default error handling
|
134
|
+
true
|
135
|
+
end
|
136
|
+
|
137
|
+
desc 'Shows the capabilities of backend in its manifest'
|
138
|
+
command :manifest do |c|
|
139
|
+
c.action do |global_options, options, arg|
|
140
|
+
manifest = global_options[:manifest]
|
141
|
+
do_exit 65, global_options, "Could not load manifest: #{e.message}" unless manifest
|
142
|
+
STDOUT.puts(manifest.map do |k, v|
|
143
|
+
"#{"#{k[0..19]}:".ljust(21)} #{v.inspect}"
|
144
|
+
end.join "\n")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
desc 'Starts the backend server'
|
149
|
+
command :start do |c|
|
150
|
+
c.desc 'Filename where backend will log requests to (default: stdout)'
|
151
|
+
c.arg_name 'FILENAME'
|
152
|
+
c.flag :l, :logfile
|
153
|
+
c.desc 'Filename where backend will log errors to, defaulting to --logfile value'
|
154
|
+
c.arg_name 'FILENAME'
|
155
|
+
c.flag :x, :errorfile
|
156
|
+
c.desc 'Daemonize the server'
|
157
|
+
c.default_value false
|
158
|
+
c.switch :d, :daemonize
|
159
|
+
add_instance_id_options c
|
160
|
+
|
161
|
+
c.action do |global_options, options, args|
|
162
|
+
options[:logfile] = nil if options[:logfile] == '-'
|
163
|
+
options[:errorfile] ||= options[:logfile]
|
164
|
+
options[:errorfile] = nil if options[:errorfile] == '-'
|
165
|
+
do_command :start, global_options, options, args
|
166
|
+
end
|
167
|
+
|
168
|
+
c.example '3scale_backend start -p 5001 -d --pidfile backend.pid -l /var/log/backend.log -x /var/log/backend.err.log',
|
169
|
+
desc: 'Listen on port 5001, daemonize with pidfile, write separate logs for requests and errors'
|
170
|
+
end
|
171
|
+
|
172
|
+
desc 'Stops the backend server'
|
173
|
+
command :stop do |c|
|
174
|
+
add_instance_id_options c
|
175
|
+
|
176
|
+
c.action do |global_options, options, args|
|
177
|
+
do_command :stop, global_options, options, args
|
178
|
+
end
|
179
|
+
|
180
|
+
c.example '3scale_backend stop --pidfile backend.pid', desc: 'Stop a daemon with a pidfile'
|
181
|
+
end
|
182
|
+
|
183
|
+
desc 'Restarts the backend server'
|
184
|
+
command :restart do |c|
|
185
|
+
add_instance_id_options c
|
186
|
+
|
187
|
+
c.desc 'Perform a phased-restart where available to avoid downtime'
|
188
|
+
c.default_value true
|
189
|
+
c.switch :"phased-restart"
|
190
|
+
|
191
|
+
c.action do |global_options, options, args|
|
192
|
+
do_command :restart, global_options, options, args
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
desc 'Prints the status of the backend server'
|
197
|
+
command :status do |c|
|
198
|
+
add_instance_id_options c
|
199
|
+
|
200
|
+
c.action do |global_options, options, args|
|
201
|
+
do_command :status, global_options, options, args
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
desc 'Prints statistics of the backend server'
|
206
|
+
command :stats do |c|
|
207
|
+
add_instance_id_options c
|
208
|
+
|
209
|
+
c.action do |global_options, options, args|
|
210
|
+
do_command :stats, global_options, options, args
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
desc 'Print extra help from the application server'
|
215
|
+
command :'help-server' do |c|
|
216
|
+
c.action do |global_options, options, args|
|
217
|
+
server = ThreeScale::Backend::Server.get global_options[:server]
|
218
|
+
server.help(global_options, options, args)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
exit Runner.run(ARGV)
|