apisonator 2.100.0
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/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)
|