apress-api 1.22.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/.drone.yml +30 -0
- data/.gitignore +15 -0
- data/.rspec +4 -0
- data/Appraisals +31 -0
- data/CHANGELOG.md +227 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/app/controllers/apress/api/deprecated_versions_controller.rb +15 -0
- data/app/controllers/apress/api/v1/callbacks_controller.rb +30 -0
- data/app/controllers/apress/api/v1/tokens_controller.rb +24 -0
- data/app/docs/schema/api/v1/types/apress/api/link.rb +29 -0
- data/app/docs/schema/api/v1/types/apress/api/links.rb +24 -0
- data/app/docs/swagger/v1/controllers/apress/api/tokens_controller.rb +64 -0
- data/app/docs/swagger/v1/default_responses/bad_request.rb +16 -0
- data/app/docs/swagger/v1/default_responses/not_found.rb +16 -0
- data/app/docs/swagger/v1/default_responses/unauthenticated.rb +16 -0
- data/app/docs/swagger/v1/default_responses/unauthorized.rb +16 -0
- data/app/docs/swagger/v1/default_responses/unprocessable.rb +16 -0
- data/app/docs/swagger/v1/default_responses/updates_locked.rb +13 -0
- data/app/docs/swagger/v1/models/apress/api/client.rb +53 -0
- data/app/docs/swagger/v1/models/apress/api/simple_error.rb +27 -0
- data/app/docs/swagger/v1/models/apress/api/unproccesable_error.rb +16 -0
- data/app/docs/swagger/v1/models/apress/api/unprocessable_error.rb +37 -0
- data/app/docs/swagger/v1/root.rb +28 -0
- data/app/interactors/apress/api/callbacks/base_callback.rb +42 -0
- data/app/interactors/apress/api/delayed_fire_callback.rb +25 -0
- data/app/jobs/apress/api/event_handler_enqueueing_job.rb +19 -0
- data/app/jobs/apress/api/fire_callback_job.rb +25 -0
- data/app/models/apress/api/client.rb +60 -0
- data/app/policies/apress/api/callback_policy.rb +15 -0
- data/app/services/apress/api/auth_service.rb +37 -0
- data/app/views/apress/api/shared/_exception.json.jbuilder +4 -0
- data/app/views/apress/api/shared/error.json.jbuilder +5 -0
- data/app/views/apress/api/shared/parameter_missing_errors.json.jbuilder +9 -0
- data/app/views/apress/api/shared/unprocessable_errors.json.jbuilder +9 -0
- data/app/views/apress/api/v1/clients/_client.json.jbuilder +2 -0
- data/app/views/apress/api/v1/tokens/create.json.jbuilder +4 -0
- data/apress-api.gemspec +46 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20150716000000_create_api_clients.rb +38 -0
- data/dip.yml +48 -0
- data/docker-compose.development.yml +18 -0
- data/docker-compose.drone.yml +7 -0
- data/docker-compose.yml +20 -0
- data/lib/apress-api.rb +1 -0
- data/lib/apress/api.rb +25 -0
- data/lib/apress/api/api_controller/authentification.rb +33 -0
- data/lib/apress/api/api_controller/base.rb +63 -0
- data/lib/apress/api/api_controller/compatibility.rb +26 -0
- data/lib/apress/api/api_controller/pagination.rb +60 -0
- data/lib/apress/api/api_controller/pagination_helper.rb +55 -0
- data/lib/apress/api/api_controller/rescue.rb +89 -0
- data/lib/apress/api/api_controller/responds.rb +25 -0
- data/lib/apress/api/callbacks/config.rb +56 -0
- data/lib/apress/api/callbacks/fire_callback_error.rb +12 -0
- data/lib/apress/api/callbacks/integration.rb +28 -0
- data/lib/apress/api/callbacks/repeat_callback_error.rb +12 -0
- data/lib/apress/api/engine.rb +33 -0
- data/lib/apress/api/extensions/jbuilder/jbuilder_template.rb +41 -0
- data/lib/apress/api/rspec.rb +48 -0
- data/lib/apress/api/rspec/utils.rb +17 -0
- data/lib/apress/api/testing/json_matcher.rb +9 -0
- data/lib/apress/api/version.rb +5 -0
- data/lib/tasks/docs.rake +12 -0
- data/spec/controllers/api_controller/authentification_spec.rb +79 -0
- data/spec/controllers/api_controller/pagination_spec.rb +199 -0
- data/spec/controllers/api_controller/rescue_spec.rb +167 -0
- data/spec/controllers/deprecated_versions_controller_spec.rb +10 -0
- data/spec/controllers/v1/callbacks_controller_spec.rb +50 -0
- data/spec/controllers/v1/tokens_controller_spec.rb +53 -0
- data/spec/factories/client_factory.rb +4 -0
- data/spec/helpers/paginating_cache_spec.rb +72 -0
- data/spec/interactors/apress/api/delayed_fire_callback_spec.rb +43 -0
- data/spec/internal/app/integrations/error_client/fire_callback.rb +14 -0
- data/spec/internal/app/integrations/service_client/fire_callback.rb +7 -0
- data/spec/internal/app/jobs/handler_job.rb +5 -0
- data/spec/internal/app/jobs/second_handler_job.rb +5 -0
- data/spec/internal/app/models/dummy_model.rb +15 -0
- data/spec/internal/config/database.yml +5 -0
- data/spec/internal/config/environments/test.rb +5 -0
- data/spec/internal/config/initializers/api.rb +10 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +5 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/jobs/apress/api/event_handler_equeueing_job_spec.rb +31 -0
- data/spec/jobs/apress/api/fire_callback_job_spec.rb +34 -0
- data/spec/lib/apress/api/callbacks/integration_spec.rb +24 -0
- data/spec/models/client_spec.rb +25 -0
- data/spec/services/auth_service_spec.rb +64 -0
- data/spec/spec_helper.rb +34 -0
- metadata +518 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module ApiController
|
|
4
|
+
module Authentification
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
attr_reader :current_api_client
|
|
9
|
+
|
|
10
|
+
if (Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR == 2) || Rails::VERSION::MAJOR > 4
|
|
11
|
+
before_action :find_session
|
|
12
|
+
before_action :authenticate
|
|
13
|
+
else
|
|
14
|
+
before_filter :find_session
|
|
15
|
+
before_filter :authenticate
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def find_session
|
|
22
|
+
auth_service = AuthService.new(request)
|
|
23
|
+
return unless auth_service.call
|
|
24
|
+
@current_api_client = auth_service.client
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def authenticate
|
|
28
|
+
forbidden unless @current_api_client
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module ApiController
|
|
4
|
+
class Base < ActionController::Metal
|
|
5
|
+
abstract!
|
|
6
|
+
|
|
7
|
+
if (Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR > 0) || Rails::VERSION::MAJOR > 4
|
|
8
|
+
include AbstractController::Rendering
|
|
9
|
+
include ActionView::Rendering
|
|
10
|
+
end
|
|
11
|
+
include ActionController::HideActions if Rails::VERSION::MAJOR < 5
|
|
12
|
+
include ActionController::UrlFor
|
|
13
|
+
include ActionController::Redirecting
|
|
14
|
+
include ActionController::Rendering
|
|
15
|
+
include ActionController::Renderers::All
|
|
16
|
+
include ActionController::ConditionalGet
|
|
17
|
+
include ActionController::RackDelegation if Rails::VERSION::MAJOR < 5
|
|
18
|
+
include ActionController::ForceSSL
|
|
19
|
+
include AbstractController::Callbacks
|
|
20
|
+
include ActionController::Rescue
|
|
21
|
+
include ActionController::Instrumentation
|
|
22
|
+
include ActionController::StrongParameters if Rails::VERSION::MAJOR >= 4
|
|
23
|
+
include ActionController::MimeResponds
|
|
24
|
+
include ActionController::ImplicitRender
|
|
25
|
+
include ActionController::Helpers
|
|
26
|
+
include ActionController::Caching
|
|
27
|
+
include AbstractController::AssetPaths
|
|
28
|
+
|
|
29
|
+
# https://github.com/rails/strong_parameters/pull/199
|
|
30
|
+
if Rails::VERSION::MAJOR == 3
|
|
31
|
+
require "strong_parameters"
|
|
32
|
+
require "strong_parameters/version"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if defined?(StrongParameters::VERSION) &&
|
|
36
|
+
Gem::Version.new(StrongParameters::VERSION) <= Gem::Version.new("0.2.3")
|
|
37
|
+
include ActionController::StrongParameters
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# :nocov:
|
|
41
|
+
if defined?(::NewRelic)
|
|
42
|
+
require "new_relic/agent/instrumentation/rails#{Rails::VERSION::MAJOR}/action_controller"
|
|
43
|
+
|
|
44
|
+
include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
|
45
|
+
|
|
46
|
+
if Rails::VERSION::MAJOR == 3
|
|
47
|
+
include ::NewRelic::Agent::Instrumentation::Rails3::ActionController
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
# :nocov:
|
|
51
|
+
|
|
52
|
+
extend Compatibility
|
|
53
|
+
include Rescue
|
|
54
|
+
include Responds
|
|
55
|
+
include Authentification
|
|
56
|
+
include Pagination
|
|
57
|
+
|
|
58
|
+
ActiveSupport.run_load_hooks(:action_controller, self)
|
|
59
|
+
ActiveSupport.run_load_hooks(:"apress/api/api_controller", self)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module ApiController
|
|
4
|
+
module Compatibility
|
|
5
|
+
def assets_dir=(*); end
|
|
6
|
+
|
|
7
|
+
def javascripts_dir=(*); end
|
|
8
|
+
|
|
9
|
+
def stylesheets_dir=(*); end
|
|
10
|
+
|
|
11
|
+
def page_cache_directory=(*); end
|
|
12
|
+
|
|
13
|
+
def relative_url_root=(*); end
|
|
14
|
+
|
|
15
|
+
def helpers_path=(*); end
|
|
16
|
+
|
|
17
|
+
def allow_forgery_protection=(*); end
|
|
18
|
+
|
|
19
|
+
def helper(*); end
|
|
20
|
+
|
|
21
|
+
def include_all_helpers=(*); end
|
|
22
|
+
# :nocov:
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'addressable/uri'
|
|
2
|
+
require 'apress/api/api_controller/pagination_helper'
|
|
3
|
+
module Apress
|
|
4
|
+
module Api
|
|
5
|
+
module ApiController
|
|
6
|
+
module Pagination
|
|
7
|
+
class InvalidPaginationError < StandardError; end
|
|
8
|
+
class LinkHeaderAppendNotImplemented < StandardError; end
|
|
9
|
+
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
attr_reader :per_page, :page
|
|
14
|
+
alias_method :current_page, :page
|
|
15
|
+
rescue_from InvalidPaginationError, with: :bad_request
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
DEFAULT_PER_PAGE = 30
|
|
19
|
+
MAX_PER_PAGE = 100
|
|
20
|
+
|
|
21
|
+
# Public: sets page and per_page variables
|
|
22
|
+
#
|
|
23
|
+
# options - Hash, configuration
|
|
24
|
+
# :per_page - Hash, per_page value configuration
|
|
25
|
+
# :max - Integer, max per_page value
|
|
26
|
+
# :defuault - Integer, default value for per_page
|
|
27
|
+
# Examples
|
|
28
|
+
# prepare_pagination(per_page: {max: 110, default: 40})
|
|
29
|
+
#
|
|
30
|
+
# or with defaults max - 100 and default - 30
|
|
31
|
+
#
|
|
32
|
+
# prepare_pagination
|
|
33
|
+
#
|
|
34
|
+
# Returns nothing
|
|
35
|
+
def prepare_pagination(options = {})
|
|
36
|
+
per_page = options.fetch(:per_page, {})
|
|
37
|
+
max_per_page = per_page.fetch(:max, MAX_PER_PAGE)
|
|
38
|
+
default_per_page = per_page.fetch(:default, DEFAULT_PER_PAGE)
|
|
39
|
+
|
|
40
|
+
@page = params.fetch(:page, 1).to_i
|
|
41
|
+
raise InvalidPaginationError if @page <= 0
|
|
42
|
+
|
|
43
|
+
@per_page = params.fetch(:per_page, default_per_page).to_i
|
|
44
|
+
raise InvalidPaginationError unless (1..max_per_page).include?(@per_page)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Public: sets pagination headers
|
|
48
|
+
#
|
|
49
|
+
# collection - WillPaginate::Collection
|
|
50
|
+
#
|
|
51
|
+
# Returns nothing
|
|
52
|
+
def pagination_headers(collection)
|
|
53
|
+
raise LinkHeaderAppendNotImplemented if headers['Link'].present?
|
|
54
|
+
|
|
55
|
+
headers.merge!(::Apress::Api::ApiController::PaginationHelper.headers(collection, request.url))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module ApiController
|
|
4
|
+
module PaginationHelper
|
|
5
|
+
def self.headers(collection, url)
|
|
6
|
+
result = {}
|
|
7
|
+
|
|
8
|
+
result['X-Total-Count'] = collection.total_entries.to_s
|
|
9
|
+
result['X-Total-Pages'] = collection.total_pages.to_s
|
|
10
|
+
result['X-Per-Page'] = collection.per_page.to_s
|
|
11
|
+
result['X-Page'] = collection.current_page.to_s
|
|
12
|
+
|
|
13
|
+
numbers = page_numbers(collection)
|
|
14
|
+
links = header_link_values(url, numbers)
|
|
15
|
+
|
|
16
|
+
result['Link'] = links.join(', ') if links.present?
|
|
17
|
+
|
|
18
|
+
result
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.header_link_values(url, page_numbers)
|
|
22
|
+
url = ::Addressable::URI.parse(url)
|
|
23
|
+
url.query_values ||= {}
|
|
24
|
+
|
|
25
|
+
page_numbers.map do |rel, number|
|
|
26
|
+
url.query_values = url.query_values.merge('page' => number)
|
|
27
|
+
|
|
28
|
+
%(<#{url}>; rel="#{rel}")
|
|
29
|
+
end
|
|
30
|
+
rescue ::Addressable::URI::InvalidURIError
|
|
31
|
+
[]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.page_numbers(collection)
|
|
35
|
+
result = {}
|
|
36
|
+
return result unless collection.total_pages > 1
|
|
37
|
+
|
|
38
|
+
if collection.current_page > 1
|
|
39
|
+
result[:first] = 1
|
|
40
|
+
result[:prev] = collection.current_page - 1
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if collection.current_page < collection.total_pages
|
|
44
|
+
result[:last] = collection.total_pages
|
|
45
|
+
result[:next] = collection.current_page + 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
result
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private_class_method :header_link_values, :page_numbers
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module ApiController
|
|
4
|
+
module Rescue
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
rescue_from "Exception", with: :server_error if Rails.env.production?
|
|
9
|
+
|
|
10
|
+
rescue_from "Pundit::NotAuthorizedError", with: :forbidden
|
|
11
|
+
|
|
12
|
+
rescue_from "ActiveRecord::RecordNotFound",
|
|
13
|
+
"ActionView::MissingTemplate",
|
|
14
|
+
"ActionController::UnknownFormat",
|
|
15
|
+
"ActiveRecord::SubclassNotFound",
|
|
16
|
+
with: :not_found unless Rails.env.development?
|
|
17
|
+
|
|
18
|
+
rescue_from 'ActiveRecord::RecordInvalid', with: :unprocessable
|
|
19
|
+
|
|
20
|
+
rescue_from 'ActionController::ParameterMissing',
|
|
21
|
+
with: :parameter_missing
|
|
22
|
+
|
|
23
|
+
helper_method :show_errors?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def server_error(exception)
|
|
29
|
+
render_error(500, exception)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def not_found(exception = nil)
|
|
33
|
+
render_error(404, exception)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def forbidden(exception = nil)
|
|
37
|
+
render_error(403, exception)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def bad_request(exception = nil)
|
|
41
|
+
render_error(400, exception)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def unprocessable(exception_or_errors)
|
|
45
|
+
@status = 422
|
|
46
|
+
|
|
47
|
+
@errors =
|
|
48
|
+
if exception_or_errors.respond_to?(:record)
|
|
49
|
+
exception_or_errors.record.errors
|
|
50
|
+
elsif exception_or_errors.is_a?(StandardError)
|
|
51
|
+
{message: exception_or_errors.message}
|
|
52
|
+
else
|
|
53
|
+
exception_or_errors
|
|
54
|
+
end
|
|
55
|
+
@errors = Array.wrap(@errors)
|
|
56
|
+
render 'apress/api/shared/unprocessable_errors', status: @status
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def parameter_missing(exception)
|
|
60
|
+
@status = 400
|
|
61
|
+
@errors = [{exception.param => 'missing'}]
|
|
62
|
+
render 'apress/api/shared/parameter_missing_errors', status: @status
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def render_error(status, exception = nil)
|
|
66
|
+
@status = status
|
|
67
|
+
@exception = exception
|
|
68
|
+
|
|
69
|
+
log_error(exception) if exception
|
|
70
|
+
|
|
71
|
+
render "apress/api/shared/error", status: status
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def log_error(exception)
|
|
75
|
+
Rails.logger.error(exception.message)
|
|
76
|
+
Rails.logger.error(exception.backtrace.join("/n")) if exception.backtrace.present?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def show_errors?
|
|
80
|
+
soft_environment?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def soft_environment?
|
|
84
|
+
Rails.env.staging? || !Rails.env.production?
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module ApiController
|
|
4
|
+
module Responds
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
if (Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR == 2) || Rails::VERSION::MAJOR > 4
|
|
9
|
+
before_action :set_json_format
|
|
10
|
+
else
|
|
11
|
+
before_filter :set_json_format
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# :nocov:
|
|
18
|
+
def set_json_format
|
|
19
|
+
request.format = :json
|
|
20
|
+
end
|
|
21
|
+
# :nocov:
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
|
|
3
|
+
module Apress
|
|
4
|
+
module Api
|
|
5
|
+
module Callbacks
|
|
6
|
+
class Config
|
|
7
|
+
include Singleton
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
delegate :add_service, :services, to: :instance
|
|
11
|
+
delegate :allowed_client?, :add_client, to: :instance
|
|
12
|
+
delegate :add_handler, :handlers, to: :instance
|
|
13
|
+
delegate :valid_event?, to: :instance
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add_service(event:, service:)
|
|
17
|
+
events[event] << service
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add_handler(service:, event:, handler:)
|
|
21
|
+
(handlers_config[service][event] ||= []) << handler
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def add_client(access_id)
|
|
25
|
+
clients << access_id
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def allowed_client?(client)
|
|
29
|
+
clients.include?(client.access_id)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def services(event)
|
|
33
|
+
events[event]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def handlers(service:, event:)
|
|
37
|
+
handlers_config.fetch(service).fetch(event)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def handlers_config
|
|
43
|
+
@handlers_config ||= ::Hash.new { |hash, key| hash[key] = {} }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def events
|
|
47
|
+
@events ||= ::Hash.new { |hash, key| hash[key] = [] }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def clients
|
|
51
|
+
@clients ||= Set.new
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module Callbacks
|
|
4
|
+
module Integration
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
module ClassMethods
|
|
8
|
+
def notify_services(event:, params: {}, at:)
|
|
9
|
+
at = Array.wrap(at)
|
|
10
|
+
callback = at.shift
|
|
11
|
+
|
|
12
|
+
public_send(callback, *at) do
|
|
13
|
+
hash_params =
|
|
14
|
+
if params.respond_to?(:call)
|
|
15
|
+
params.call(self)
|
|
16
|
+
else
|
|
17
|
+
params.each_with_object({}) do |param, hash|
|
|
18
|
+
hash[param] = public_send(param)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
::Apress::Api::DelayedFireCallback.call!(event: event, params: hash_params)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|