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,29 @@
|
|
|
1
|
+
module Schema
|
|
2
|
+
module Api
|
|
3
|
+
module V1
|
|
4
|
+
module Types
|
|
5
|
+
module Apress
|
|
6
|
+
module Api
|
|
7
|
+
class Link < ::Apress::Api::Swagger::Schema
|
|
8
|
+
swagger_schema name.to_sym do
|
|
9
|
+
key :required, [:href]
|
|
10
|
+
key :description, 'A representation of a link object'
|
|
11
|
+
|
|
12
|
+
property :href do
|
|
13
|
+
key :type, :string
|
|
14
|
+
key :description, 'A string containing the link’s URL'
|
|
15
|
+
key :example, 'https://www.example.com/api/v1/review_comments'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
property :meta do
|
|
19
|
+
key :type, :object
|
|
20
|
+
key :description, 'A meta object containing non-standard meta-information about the link'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Schema
|
|
2
|
+
module Api
|
|
3
|
+
module V1
|
|
4
|
+
module Types
|
|
5
|
+
module Apress
|
|
6
|
+
module Api
|
|
7
|
+
class Links < ::Apress::Api::Swagger::Schema
|
|
8
|
+
swagger_schema name.to_sym do
|
|
9
|
+
key :description, 'A representation of a links object (http://jsonapi.org/format/#document-links)'
|
|
10
|
+
key :type, :object
|
|
11
|
+
key :additionalProperties, {
|
|
12
|
+
oneOf: [
|
|
13
|
+
{'type': 'string'},
|
|
14
|
+
{'$ref' => '#/definitions/Schema::Api::V1::Types::Apress::Api::Link'}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module Controllers
|
|
4
|
+
module Apress
|
|
5
|
+
module Api
|
|
6
|
+
class TokensController < ::Apress::Api::Swagger::Schema
|
|
7
|
+
swagger_path '/clients/{access_id}/tokens' do
|
|
8
|
+
operation :post do
|
|
9
|
+
key :produces, ['application/json']
|
|
10
|
+
|
|
11
|
+
key :description, 'Refreshes token for client with given access_id'
|
|
12
|
+
key :operationId, 'refreshToken'
|
|
13
|
+
key :tags, ['clients']
|
|
14
|
+
|
|
15
|
+
parameter do
|
|
16
|
+
key :name, :access_id
|
|
17
|
+
key :in, :path
|
|
18
|
+
key :description, "client's access_id"
|
|
19
|
+
key :required, true
|
|
20
|
+
key :type, :string
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
parameter do
|
|
24
|
+
key :name, 'refresh_token'
|
|
25
|
+
key :in, :body
|
|
26
|
+
key :description, "Client's refresh token"
|
|
27
|
+
key :required, true
|
|
28
|
+
schema type: :object do
|
|
29
|
+
property :refresh_token do
|
|
30
|
+
key :type, :string
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
response 200 do
|
|
36
|
+
key :description, 'Success response'
|
|
37
|
+
schema type: 'object' do
|
|
38
|
+
property :client do
|
|
39
|
+
key :'$ref', :'Swagger::V1::Models::Apress::Api::Client'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
response 400 do
|
|
45
|
+
key :description, 'refresh token not valid for current access_id'
|
|
46
|
+
schema do
|
|
47
|
+
key :'$ref', :'Swagger::V1::Models::Apress::Api::SimpleError'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
response 403 do
|
|
52
|
+
key :description, 'refresh token is expired'
|
|
53
|
+
schema do
|
|
54
|
+
key :'$ref', :'Swagger::V1::Models::Apress::Api::SimpleError'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module DefaultResponses
|
|
4
|
+
module BadRequest
|
|
5
|
+
def self.extended(base)
|
|
6
|
+
base.response 400 do
|
|
7
|
+
key :description, "Переданные параметры не могут быть обработаны"
|
|
8
|
+
schema do
|
|
9
|
+
key :'$ref', :'Swagger::V1::::Models::Apress::Api::UnprocessableError'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module DefaultResponses
|
|
4
|
+
module NotFound
|
|
5
|
+
def self.extended(base)
|
|
6
|
+
base.response 404 do
|
|
7
|
+
key :description, "Запрашиваемый ресурс не найден"
|
|
8
|
+
schema do
|
|
9
|
+
key :'$ref', :'Swagger::V1::::Models::Apress::Api::SimpleError'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module DefaultResponses
|
|
4
|
+
module Unauthenticated
|
|
5
|
+
def self.extended(base)
|
|
6
|
+
base.response 401 do
|
|
7
|
+
key :description, "Запрос не прошел аутентификацию (проблема с подписью запроса)"
|
|
8
|
+
schema do
|
|
9
|
+
key :'$ref', :'Swagger::V1::::Models::Apress::Api::SimpleError'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module DefaultResponses
|
|
4
|
+
module Unauthorized
|
|
5
|
+
def self.extended(base)
|
|
6
|
+
base.response 403 do
|
|
7
|
+
key :description, "Нет доступа к ресурсу"
|
|
8
|
+
schema do
|
|
9
|
+
key :'$ref', :'Swagger::V1::::Models::Apress::Api::SimpleError'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module DefaultResponses
|
|
4
|
+
module Unprocessable
|
|
5
|
+
def self.extended(base)
|
|
6
|
+
base.response 422 do
|
|
7
|
+
key :description, "Переданные параметры не валидны"
|
|
8
|
+
schema do
|
|
9
|
+
key :'$ref', :'Swagger::V1::::Models::Apress::Api::UnprocessableError'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module Models
|
|
4
|
+
module Apress
|
|
5
|
+
module Api
|
|
6
|
+
class Client < ::Apress::Documentation::Swagger::Schema
|
|
7
|
+
swagger_schema name.to_sym do
|
|
8
|
+
key :required, [
|
|
9
|
+
:id,
|
|
10
|
+
:access_id,
|
|
11
|
+
:secret_token_expire_at,
|
|
12
|
+
:secret_token,
|
|
13
|
+
:refresh_token_expire_at,
|
|
14
|
+
:refresh_token,
|
|
15
|
+
:user_agent,
|
|
16
|
+
:updated_at,
|
|
17
|
+
:created_at
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
property :id do
|
|
21
|
+
key :type, :integer
|
|
22
|
+
key :format, :int64
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
{
|
|
26
|
+
access_id: '6760dc04-db3e-4c18-b7a3-5cd68718e869',
|
|
27
|
+
secret_token: 'fflnVd5JyQAlH4EICLEV/c49RQRj0MaINNKFAVsuxngfcQHzLw7L9uF7fnOm/mbn4SBs3ssCUjvjcTjb4nQ==',
|
|
28
|
+
refresh_token: 'kmwCUAQxg2YOCZg2ENLQ4t4hfH8DYKPb6e+6ZkSl1K/zOyAXflUeL9Ef/jL7rEMTfuu0QqbrMm8SNsEnww==',
|
|
29
|
+
secret_token_expire_at: Time.current,
|
|
30
|
+
refresh_token_expire_at: Time.current,
|
|
31
|
+
user_agent: nil
|
|
32
|
+
}.each do |k, v|
|
|
33
|
+
property k do
|
|
34
|
+
key :type, :string
|
|
35
|
+
key :example, v if v
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
[:created_at, :updated_at].each do |k|
|
|
40
|
+
property k do
|
|
41
|
+
key :type, :string
|
|
42
|
+
key :format, :date
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
ActiveSupport.run_load_hooks(:'swagger/models/v1/apress/api/client', self)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module Models
|
|
4
|
+
module Apress
|
|
5
|
+
module Api
|
|
6
|
+
class SimpleError < ::Apress::Documentation::Swagger::Schema
|
|
7
|
+
swagger_schema name.to_sym do
|
|
8
|
+
keys = [
|
|
9
|
+
:status,
|
|
10
|
+
:message,
|
|
11
|
+
:backtrace
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
key :required, keys
|
|
15
|
+
|
|
16
|
+
keys.each do |k|
|
|
17
|
+
property k do
|
|
18
|
+
key :type, :string
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative 'unprocessable_error'
|
|
2
|
+
|
|
3
|
+
module Swagger
|
|
4
|
+
module V1
|
|
5
|
+
module Models
|
|
6
|
+
module Apress
|
|
7
|
+
module Api
|
|
8
|
+
# Deprecated: Please use `UnprocessableError` instead
|
|
9
|
+
class UnproccesableError < ::Apress::Documentation::Swagger::Schema
|
|
10
|
+
include UnprocessableError::Schema
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
module Models
|
|
4
|
+
module Apress
|
|
5
|
+
module Api
|
|
6
|
+
class UnprocessableError < ::Apress::Documentation::Swagger::Schema
|
|
7
|
+
module Schema
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
swagger_schema name.to_sym do
|
|
12
|
+
key :required, [:errors, :status]
|
|
13
|
+
|
|
14
|
+
property :status do
|
|
15
|
+
key :type, :string
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
property :errors do
|
|
19
|
+
key :type, :array
|
|
20
|
+
items do
|
|
21
|
+
key :type, :object
|
|
22
|
+
property :error do
|
|
23
|
+
key :type, :object
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
include Schema
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Swagger
|
|
2
|
+
module V1
|
|
3
|
+
class Root < ::Apress::Documentation::Swagger::Schema
|
|
4
|
+
swagger_root do
|
|
5
|
+
key :swagger, '2.0'
|
|
6
|
+
info do
|
|
7
|
+
key :version, '1.0.0'
|
|
8
|
+
key :title, 'Apress API'
|
|
9
|
+
key :description, 'Apress API'
|
|
10
|
+
key :termsOfService, 'None'
|
|
11
|
+
contact do
|
|
12
|
+
key :name, 'Abak-Press Team'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
key :basePath, '/api/v1'
|
|
17
|
+
key :produces, ['application/json']
|
|
18
|
+
|
|
19
|
+
security_definition :APIAuth do
|
|
20
|
+
key :type, :apiKey
|
|
21
|
+
key :in, :header
|
|
22
|
+
key :name, 'Authorization'
|
|
23
|
+
key :description, 'Authentication by access_id token based on HMAC'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
module Callbacks
|
|
4
|
+
class BaseCallback
|
|
5
|
+
include Interactor
|
|
6
|
+
|
|
7
|
+
def self.retry_exceptions
|
|
8
|
+
@retry_exceptions ||= Set.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.repeat_exceptions
|
|
12
|
+
@repeat_exceptions ||= Set.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.add_retry_exceptions(*errors)
|
|
16
|
+
retry_exceptions.merge(errors)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.add_repeat_exceptions(*errors)
|
|
20
|
+
repeat_exceptions.merge(errors)
|
|
21
|
+
retry_exceptions.merge(errors)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.inherited(other)
|
|
25
|
+
other.around do |interactor|
|
|
26
|
+
begin
|
|
27
|
+
interactor.call
|
|
28
|
+
rescue Exception => error
|
|
29
|
+
if self.class.repeat_exceptions.any? { |ex| ex === error }
|
|
30
|
+
raise Apress::Api::Callbacks::RepeatCallbackError.new(error.message, error.backtrace)
|
|
31
|
+
elsif self.class.retry_exceptions.any? { |ex| error.is_a?(Class) && ex >= error || ex === error }
|
|
32
|
+
raise Apress::Api::Callbacks::FireCallbackError.new(error.message, error.backtrace)
|
|
33
|
+
else
|
|
34
|
+
raise error
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Apress
|
|
2
|
+
module Api
|
|
3
|
+
class DelayedFireCallback
|
|
4
|
+
include Interactor
|
|
5
|
+
|
|
6
|
+
delegate :event, :params, to: :context
|
|
7
|
+
def call
|
|
8
|
+
services = Apress::Api::Callbacks::Config.services(event)
|
|
9
|
+
|
|
10
|
+
return if services.blank?
|
|
11
|
+
|
|
12
|
+
::Resque.redis.multi do
|
|
13
|
+
services.each do |service|
|
|
14
|
+
::Resque.enqueue(
|
|
15
|
+
::Apress::Api::FireCallbackJob,
|
|
16
|
+
service,
|
|
17
|
+
event,
|
|
18
|
+
params
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|