canvas_sync 0.16.5 → 0.17.0.beta5
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 +4 -4
- data/README.md +49 -137
- data/app/models/canvas_sync/sync_batch.rb +5 -0
- data/db/migrate/20201018210836_create_canvas_sync_sync_batches.rb +11 -0
- data/lib/canvas_sync.rb +35 -97
- data/lib/canvas_sync/importers/bulk_importer.rb +4 -7
- data/lib/canvas_sync/job.rb +4 -10
- data/lib/canvas_sync/job_batches/batch.rb +403 -0
- data/lib/canvas_sync/job_batches/batch_aware_job.rb +62 -0
- data/lib/canvas_sync/job_batches/callback.rb +152 -0
- data/lib/canvas_sync/job_batches/chain_builder.rb +220 -0
- data/lib/canvas_sync/job_batches/context_hash.rb +147 -0
- data/lib/canvas_sync/job_batches/jobs/base_job.rb +7 -0
- data/lib/canvas_sync/job_batches/jobs/concurrent_batch_job.rb +19 -0
- data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +75 -0
- data/lib/canvas_sync/job_batches/sidekiq.rb +93 -0
- data/lib/canvas_sync/job_batches/status.rb +83 -0
- data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +35 -0
- data/lib/canvas_sync/jobs/report_checker.rb +3 -6
- data/lib/canvas_sync/jobs/report_processor_job.rb +2 -5
- data/lib/canvas_sync/jobs/report_starter.rb +28 -20
- data/lib/canvas_sync/jobs/sync_accounts_job.rb +3 -5
- data/lib/canvas_sync/jobs/sync_admins_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_assignments_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_context_module_items_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_context_modules_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +4 -34
- data/lib/canvas_sync/jobs/sync_roles_job.rb +2 -5
- data/lib/canvas_sync/jobs/sync_simple_table_job.rb +11 -32
- data/lib/canvas_sync/jobs/sync_submissions_job.rb +2 -4
- data/lib/canvas_sync/jobs/sync_terms_job.rb +25 -8
- data/lib/canvas_sync/processors/assignment_groups_processor.rb +2 -3
- data/lib/canvas_sync/processors/assignments_processor.rb +2 -3
- data/lib/canvas_sync/processors/context_module_items_processor.rb +2 -3
- data/lib/canvas_sync/processors/context_modules_processor.rb +2 -3
- data/lib/canvas_sync/processors/normal_processor.rb +1 -2
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +2 -10
- data/lib/canvas_sync/processors/submissions_processor.rb +2 -3
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/canvas_sync_spec.rb +136 -153
- data/spec/canvas_sync/jobs/job_spec.rb +9 -17
- data/spec/canvas_sync/jobs/report_checker_spec.rb +1 -3
- data/spec/canvas_sync/jobs/report_processor_job_spec.rb +0 -3
- data/spec/canvas_sync/jobs/report_starter_spec.rb +19 -28
- data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +1 -4
- data/spec/canvas_sync/jobs/sync_assignment_groups_job_spec.rb +2 -1
- data/spec/canvas_sync/jobs/sync_assignments_job_spec.rb +3 -2
- data/spec/canvas_sync/jobs/sync_context_module_items_job_spec.rb +3 -2
- data/spec/canvas_sync/jobs/sync_context_modules_job_spec.rb +3 -2
- data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +3 -35
- data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +1 -4
- data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +5 -12
- data/spec/canvas_sync/jobs/sync_submissions_job_spec.rb +2 -1
- data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +1 -4
- data/spec/dummy/config/environments/test.rb +2 -0
- data/spec/dummy/db/schema.rb +9 -1
- data/spec/job_batching/batch_aware_job_spec.rb +100 -0
- data/spec/job_batching/batch_spec.rb +372 -0
- data/spec/job_batching/callback_spec.rb +38 -0
- data/spec/job_batching/flow_spec.rb +88 -0
- data/spec/job_batching/integration/integration.rb +57 -0
- data/spec/job_batching/integration/nested.rb +88 -0
- data/spec/job_batching/integration/simple.rb +47 -0
- data/spec/job_batching/integration/workflow.rb +134 -0
- data/spec/job_batching/integration_helper.rb +48 -0
- data/spec/job_batching/sidekiq_spec.rb +124 -0
- data/spec/job_batching/status_spec.rb +92 -0
- data/spec/job_batching/support/base_job.rb +14 -0
- data/spec/job_batching/support/sample_callback.rb +2 -0
- data/spec/spec_helper.rb +17 -0
- metadata +85 -8
- data/lib/canvas_sync/job_chain.rb +0 -102
- data/lib/canvas_sync/jobs/fork_gather.rb +0 -74
- data/spec/canvas_sync/jobs/fork_gather_spec.rb +0 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eba7624a65721ad2183b188372b167c47bde879c37c595ef13398e4ec4b835b5
|
4
|
+
data.tar.gz: a69c72c000c782bff566016ca1cc7813c0c1d6829f2516291721672e3ee7d5ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00e85f161794e1526cf734aabaaf364b55b92b93a832248bd8f17b4eeb97081e20fc8ef7e84ae7029dbd654ad46410939d10ec4db5ba79394b9326de49948342
|
7
|
+
data.tar.gz: d30bb87abb822cd0f5ad10b60b6941326ac8a2e964241fa6e8403c5a5bf303e3d6945bd79ff500a181bd21a6805161281f4fe05fdd091f42b295ebf820772362
|
data/README.md
CHANGED
@@ -91,27 +91,45 @@ This gem also helps with syncing and processing other reports if needed. In orde
|
|
91
91
|
- Integrate your reports with the `ReportStarter`
|
92
92
|
- Tell the gem what jobs to run
|
93
93
|
|
94
|
+
### `updated_after`
|
95
|
+
An `updated_after` param may be passed when triggering a provision or making a chain:
|
96
|
+
```ruby
|
97
|
+
CanvasSync.default_provisioning_report_chain(
|
98
|
+
%i[list of models to sync], updated_after: false
|
99
|
+
)
|
100
|
+
```
|
101
|
+
It may be one of the following values:
|
102
|
+
* `false` - Will not apply any `updated_after` filtering to the requested reports
|
103
|
+
* An ISO-8601 Date - Will pass the supplied date ad the `updated_after` param for the requested reports
|
104
|
+
* `true` (Default) - Will use the start date of the last successful sync
|
105
|
+
|
94
106
|
### Extensible chain
|
95
107
|
It is sometimes desired to extend or customize the chain of jobs that are run with CanvasSync.
|
96
108
|
This can be achieved with the following pattern:
|
97
109
|
|
98
110
|
```ruby
|
99
|
-
|
111
|
+
chain = CanvasSync.default_provisioning_report_chain(
|
100
112
|
%i[list of models to sync]
|
101
113
|
)
|
102
114
|
|
103
|
-
#
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
# Jobs placed before SyncProvisioningReportJob or after ForkGather will run once per Sync
|
109
|
-
job_chain[:jobs] << { job: CanvasSync::Jobs::ForkGather, options: {} }
|
115
|
+
# Add a custom job to the end of the chain.
|
116
|
+
chain << { job: CanvasSyncCompleteWorker, parameters: [{ job_id: job.id }] }
|
117
|
+
chain << { job: CanvasSyncCompleteWorker, options: { job_id: job.id } } # If an options key is provided, it will be automatically appended to the end of the :parameters array
|
118
|
+
|
119
|
+
chain.process!
|
110
120
|
|
111
|
-
#
|
112
|
-
|
121
|
+
# The chain object provides a fairly extensive API:
|
122
|
+
chain.insert({ job: SomeOtherJob }) # Adds the job to the end of the chain
|
123
|
+
chain.insert_at(0, { job: SomeOtherJob }) # Adds the job to the beginning of the chain
|
124
|
+
chain.insert({ job: SomeOtherJob }, after: 'CanvasSync::Jobs::SyncTermsJob') # Adds the job right after the SyncTermsJob
|
125
|
+
chain.insert({ job: SomeOtherJob }, before: 'CanvasSync::Jobs::SyncTermsJob') # Adds the job right before the SyncTermsJob
|
126
|
+
chain.insert({ job: SomeOtherJob }, with: 'CanvasSync::Jobs::SyncTermsJob') # Adds the job to be performed concurrently with the SyncTermsJob
|
113
127
|
|
114
|
-
|
128
|
+
# Some Jobs (such as the SyncTermsJob) have a sub-chain for, eg, Courses.
|
129
|
+
# chain.insert is aware of these sub-chains and will recurse into them when looking for a before:/after:/with: reference
|
130
|
+
chain.insert({ job: SomeOtherJob }, after: 'CanvasSync::Jobs::SyncCoursesJob') # Adds the job to be performed after SyncCoursesJob (which is a sub-job of the terms job and is duplicated for each term in the term_scope:)
|
131
|
+
# You can also retrieve the sub-chain like so:
|
132
|
+
chain.get_sub_chain('CanvasSync::Jobs::SyncTermsJob')
|
115
133
|
```
|
116
134
|
|
117
135
|
### Processor
|
@@ -134,9 +152,8 @@ Let's say we have a custom Canvas report called "my_really_cool_report_csv". Fir
|
|
134
152
|
|
135
153
|
```ruby
|
136
154
|
class MyReallyCoolReportJob < CanvasSync::Jobs::ReportStarter
|
137
|
-
def perform(
|
155
|
+
def perform(options)
|
138
156
|
super(
|
139
|
-
job_chain,
|
140
157
|
'my_really_cool_report_csv', # Report name
|
141
158
|
{ "parameters[param1]" => true }, # Report parameters
|
142
159
|
MyCoolProcessor.to_s, # Your processor class as a string
|
@@ -148,57 +165,6 @@ end
|
|
148
165
|
|
149
166
|
You can also see examples in `lib/canvas_sync/jobs/sync_users_job.rb` and `lib/canvas_sync/jobs/sync_provisioning_report.rb`.
|
150
167
|
|
151
|
-
### Start the jobs
|
152
|
-
|
153
|
-
The `CanvasSync.process_jobs` method allows you to pass in a chain of jobs to run. The job chain must be formatted like:
|
154
|
-
|
155
|
-
```ruby
|
156
|
-
{
|
157
|
-
jobs: [
|
158
|
-
{ job: JobClass, options: {} },
|
159
|
-
{ job: JobClass2, options: {} }
|
160
|
-
],
|
161
|
-
global_options: {}
|
162
|
-
}
|
163
|
-
```
|
164
|
-
|
165
|
-
Here is an example that runs our new report job first followed by the builtin provisioning job:
|
166
|
-
|
167
|
-
```ruby
|
168
|
-
job_chain = {
|
169
|
-
jobs: [
|
170
|
-
{ job: MyReallyCoolReportJob, options: {} },
|
171
|
-
{ job: CanvasSync::Jobs::SyncProvisioningReportJob, options: { models: ['users', 'courses'] } }
|
172
|
-
],
|
173
|
-
global_options: {}
|
174
|
-
}
|
175
|
-
|
176
|
-
CanvasSync.process_jobs(job_chain)
|
177
|
-
```
|
178
|
-
|
179
|
-
What if you've got some other job that you want run that doesn't deal with a report? No problem! Just make sure you call `CanvasSync.invoke_next` at the end of your job. Example:
|
180
|
-
|
181
|
-
|
182
|
-
```ruby
|
183
|
-
class SomeRandomJob < CanvasSync::Job
|
184
|
-
def perform(job_chain, options)
|
185
|
-
i_dunno_do_something!
|
186
|
-
|
187
|
-
CanvasSync.invoke_next(job_chain)
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
job_chain = {
|
192
|
-
jobs: [
|
193
|
-
{ job: SomeRandomJob, options: {} },
|
194
|
-
{ job: CanvasSync::Jobs::SyncProvisioningReportJob, options: { models: ['users', 'courses'] } }
|
195
|
-
],
|
196
|
-
global_options: {}
|
197
|
-
}
|
198
|
-
|
199
|
-
CanvasSync.process_jobs(job_chain)
|
200
|
-
```
|
201
|
-
|
202
168
|
### Batching
|
203
169
|
|
204
170
|
The provisioning report uses the `CanvasSync::Importers::BulkImporter` class to bulk import rows with the activerecord-import gem. It inserts rows in batches of 10,000 by default. This can be customized by setting the `BULK_IMPORTER_BATCH_SIZE` environment variable.
|
@@ -257,6 +223,14 @@ class CanvasSyncModel < ApplicationRecord
|
|
257
223
|
end
|
258
224
|
```
|
259
225
|
|
226
|
+
### Job Batching
|
227
|
+
CanvasSync adds a `CanvasSync::JobBatches` module. It adds Sidekiq/sidekiq-batch like support for Job Batches.
|
228
|
+
It integrates automatically with both Sidekiq and ActiveJob. The API is highly similar to the Sidekiq-batch implementation,
|
229
|
+
documentation for which can be found at https://github.com/mperham/sidekiq/wiki/Batches
|
230
|
+
|
231
|
+
A batch can be created using `Sidekiq::Batch` or `CanvasSync::JobBatching::Batch`.
|
232
|
+
|
233
|
+
Also see `canvas_sync/jobs/begin_sync_chain_job`, `canvas_sync/Job_batches/jobs/serial_batch_job`, or `canvas_sync/Job_batches/jobs/concurrent_batch_job` for example usage.
|
260
234
|
|
261
235
|
## Legacy Support
|
262
236
|
|
@@ -308,80 +282,19 @@ end
|
|
308
282
|
## Syncronize different reports
|
309
283
|
CanvasSync provides the functionality to import data from other reports into an specific table.
|
310
284
|
|
311
|
-
This can be
|
312
|
-
|
313
|
-
```ruby
|
314
|
-
CanvasSync.provisioning_sync(<array of models to sync>, term_scope: <optional term scope>)
|
315
|
-
CanvasSync
|
316
|
-
.simple_report_sync(
|
317
|
-
[
|
318
|
-
{
|
319
|
-
report_name: <report name>,
|
320
|
-
model: <model to sync>,
|
321
|
-
params: <hash with the require parameters the report needs to sync>
|
322
|
-
},
|
323
|
-
{
|
324
|
-
report_name: <report name>,
|
325
|
-
model: <model to sync>,
|
326
|
-
params: <hash with the require parameters the report needs to sync>
|
327
|
-
},
|
328
|
-
...
|
329
|
-
],
|
330
|
-
term_scope: <optional term scope>
|
331
|
-
)
|
332
|
-
```
|
333
|
-
|
334
|
-
Example:
|
285
|
+
This can be achieved by using the following method
|
335
286
|
|
336
287
|
```ruby
|
337
|
-
CanvasSync
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
},
|
348
|
-
{
|
349
|
-
report_name: 'proservices_provisioning_csv',
|
350
|
-
model: 'accounts',
|
351
|
-
params: {
|
352
|
-
"parameters[include_deleted]" => true,
|
353
|
-
"parameters[accounts]" => true
|
354
|
-
}
|
355
|
-
}
|
356
|
-
]
|
357
|
-
)
|
358
|
-
```
|
359
|
-
|
360
|
-
Example with the term_scope active:
|
361
|
-
|
362
|
-
```ruby
|
363
|
-
CanvasSync
|
364
|
-
.simple_report_sync(
|
365
|
-
[
|
366
|
-
{
|
367
|
-
report_name: 'proservices_provisioning_csv',
|
368
|
-
model: 'sections',
|
369
|
-
params: {
|
370
|
-
"parameters[include_deleted]" => true,
|
371
|
-
"parameters[sections]" => true
|
372
|
-
}
|
373
|
-
},
|
374
|
-
{
|
375
|
-
report_name: 'proservices_provisioning_csv',
|
376
|
-
model: 'courses',
|
377
|
-
params: {
|
378
|
-
"parameters[include_deleted]" => true,
|
379
|
-
"parameters[courses]" => true
|
380
|
-
}
|
381
|
-
}
|
382
|
-
],
|
383
|
-
term_scope: 'active'
|
384
|
-
)
|
288
|
+
chain = CanvasSync.default_provisioning_report_chain
|
289
|
+
chain << {
|
290
|
+
job: CanvasSync::Jobs::SyncSimpleTableJob,
|
291
|
+
options: {
|
292
|
+
report_name: <report name>,
|
293
|
+
model: <model to sync>,
|
294
|
+
params: <hash with the require parameters the report needs to sync>
|
295
|
+
},
|
296
|
+
}
|
297
|
+
chain.process!
|
385
298
|
```
|
386
299
|
|
387
300
|
## Configuration
|
@@ -421,7 +334,6 @@ class CanvasSyncStarterWorker
|
|
421
334
|
}
|
422
335
|
}
|
423
336
|
)
|
424
|
-
CanvasSync.invoke_next(job_chain)
|
425
337
|
end
|
426
338
|
|
427
339
|
def self.handle_canvas_sync_error(error, **options)
|
data/lib/canvas_sync.rb
CHANGED
@@ -5,7 +5,6 @@ require "canvas_sync/engine"
|
|
5
5
|
require "canvas_sync/misc_helper"
|
6
6
|
require "canvas_sync/class_callback_executor"
|
7
7
|
require "canvas_sync/job"
|
8
|
-
require "canvas_sync/job_chain"
|
9
8
|
require "canvas_sync/sidekiq_job"
|
10
9
|
require "canvas_sync/api_syncable"
|
11
10
|
require "canvas_sync/record"
|
@@ -14,6 +13,8 @@ require "canvas_sync/jobs/report_checker"
|
|
14
13
|
require "canvas_sync/jobs/report_processor_job"
|
15
14
|
require "canvas_sync/config"
|
16
15
|
|
16
|
+
require "canvas_sync/job_batches/batch"
|
17
|
+
|
17
18
|
Dir[File.dirname(__FILE__) + "/canvas_sync/jobs/*.rb"].each { |file| require file }
|
18
19
|
Dir[File.dirname(__FILE__) + "/canvas_sync/processors/*.rb"].each { |file| require file }
|
19
20
|
Dir[File.dirname(__FILE__) + "/canvas_sync/importers/*.rb"].each { |file| require file }
|
@@ -58,6 +59,9 @@ module CanvasSync
|
|
58
59
|
graded_submissions
|
59
60
|
].freeze
|
60
61
|
|
62
|
+
JobBatches::ChainBuilder.register_chain_job(CanvasSync::Jobs::SyncTermsJob, :sub_jobs)
|
63
|
+
JobBatches::ChainBuilder.register_chain_job(CanvasSync::Jobs::BeginSyncChainJob, 0)
|
64
|
+
|
61
65
|
class << self
|
62
66
|
# Runs a standard provisioning sync job with no extra report types.
|
63
67
|
# Terms will be synced first using the API. If you are syncing users/roles/admins
|
@@ -73,51 +77,9 @@ module CanvasSync
|
|
73
77
|
# and inserts it into the database. If an array of model names is provided then only those models will use legacy support.
|
74
78
|
# @param account_id [Integer, nil] This optional parameter can be used if your Term creation and
|
75
79
|
# canvas_sync_client methods require an account ID.
|
76
|
-
def provisioning_sync(models,
|
80
|
+
def provisioning_sync(models, **kwargs)
|
77
81
|
validate_models!(models)
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
# Runs a report different from provisioning sync job with no extra report types.
|
82
|
-
#
|
83
|
-
# @param reports_mapping [Array<Hash>] An Array of hash that list the model and params with their report you
|
84
|
-
# want to import:
|
85
|
-
# [{model: 'submissions', report_name: 'my_report_name_csv', params: { "parameters[include_deleted]" => true } }, ...]
|
86
|
-
# @param term_scope [Symbol, nil] An optional symbol representing a scope that exists on the Term model.
|
87
|
-
# The provisioning report will be run for each of the terms contained in that scope.
|
88
|
-
# @param account_id [Integer, nil] This optional parameter can be used if your Term creation and
|
89
|
-
# canvas_sync_client methods require an account ID.
|
90
|
-
def simple_report_sync(reports_mapping, term_scope: nil, account_id: nil)
|
91
|
-
invoke_next(simple_report_chain(reports_mapping, term_scope, account_id))
|
92
|
-
end
|
93
|
-
|
94
|
-
# Runs a chain of ordered jobs
|
95
|
-
#
|
96
|
-
# See the README for usage and examples
|
97
|
-
#
|
98
|
-
# @param job_chain [Hash]
|
99
|
-
def process_jobs(job_chain)
|
100
|
-
invoke_next(job_chain)
|
101
|
-
end
|
102
|
-
|
103
|
-
# @deprecated
|
104
|
-
def duplicate_chain(job_chain)
|
105
|
-
Marshal.load(Marshal.dump(job_chain))
|
106
|
-
end
|
107
|
-
|
108
|
-
# Invokes the next job in a chain of jobs.
|
109
|
-
#
|
110
|
-
# This should typically be called automatically by the gem where necessary.
|
111
|
-
#
|
112
|
-
# @param job_chain [Hash] A chain of jobs to execute
|
113
|
-
def invoke_next(job_chain, extra_options: {})
|
114
|
-
job_chain = JobChain.new(job_chain) unless job_chain.is_a?(JobChain)
|
115
|
-
job_chain.perform_next(extra_options)
|
116
|
-
end
|
117
|
-
|
118
|
-
def fork(job_log, job_chain, keys: [], &blk)
|
119
|
-
job_chain = JobChain.new(job_chain) unless job_chain.is_a?(JobChain)
|
120
|
-
job_chain.fork(job_log, keys: keys, &blk)
|
82
|
+
default_provisioning_report_chain(models, **kwargs).process!
|
121
83
|
end
|
122
84
|
|
123
85
|
# Given a Model or Relation, scope it down to items that should be synced
|
@@ -134,33 +96,6 @@ module CanvasSync
|
|
134
96
|
scope
|
135
97
|
end
|
136
98
|
|
137
|
-
# Syn any report to an specific set of models
|
138
|
-
#
|
139
|
-
# @param reports_mapping [Array<Hash>] List of reports with their specific model and params
|
140
|
-
# @param term_scope [String]
|
141
|
-
# @param account_id [Integer, nil] This optional parameter can be used if your Term creation and
|
142
|
-
# canvas_sync_client methods require an account ID.
|
143
|
-
def simple_report_chain(reports_mapping, term_scope=nil, account_id=nil)
|
144
|
-
jobs = reports_mapping.map do |report|
|
145
|
-
{
|
146
|
-
job: CanvasSync::Jobs::SyncSimpleTableJob.to_s,
|
147
|
-
options: {
|
148
|
-
report_name: report[:report_name],
|
149
|
-
model: report[:model],
|
150
|
-
mapping: report[:model],
|
151
|
-
klass: report[:model].singularize.capitalize.to_s,
|
152
|
-
term_scope: term_scope,
|
153
|
-
params: report[:params]
|
154
|
-
}
|
155
|
-
}
|
156
|
-
end
|
157
|
-
|
158
|
-
global_options = {}
|
159
|
-
global_options[:account_id] = account_id if account_id.present?
|
160
|
-
|
161
|
-
JobChain.new(jobs: jobs, global_options: global_options)
|
162
|
-
end
|
163
|
-
|
164
99
|
# Syncs terms, users/roles/admins if necessary, then the rest of the specified models.
|
165
100
|
#
|
166
101
|
# @param models [Array<String>]
|
@@ -171,7 +106,7 @@ module CanvasSync
|
|
171
106
|
# @param account_id [Integer, nil] This optional parameter can be used if your Term creation and
|
172
107
|
# canvas_sync_client methods require an account ID.
|
173
108
|
# @return [Hash]
|
174
|
-
def default_provisioning_report_chain(models, term_scope
|
109
|
+
def default_provisioning_report_chain(models, term_scope: nil, legacy_support: false, account_id: nil, updated_after: nil, options: {}) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/LineLength
|
175
110
|
return unless models.present?
|
176
111
|
models.map! &:to_s
|
177
112
|
term_scope = term_scope.to_s if term_scope
|
@@ -190,64 +125,67 @@ module CanvasSync
|
|
190
125
|
context_module_items: CanvasSync::Jobs::SyncContextModuleItemsJob,
|
191
126
|
}.with_indifferent_access
|
192
127
|
|
193
|
-
|
128
|
+
root_chain = JobBatches::ChainBuilder.new(CanvasSync::Jobs::BeginSyncChainJob)
|
129
|
+
concurrent_root_chain = JobBatches::ChainBuilder.new(JobBatches::ConcurrentBatchJob)
|
130
|
+
root_chain << concurrent_root_chain
|
131
|
+
current_chain = concurrent_root_chain
|
132
|
+
|
194
133
|
try_add_model_job = ->(model) {
|
195
134
|
return unless models.include?(model)
|
196
|
-
|
135
|
+
current_chain << { job: model_job_map[model].to_s, options: options[model.to_sym] || {} }
|
197
136
|
models -= [model]
|
198
137
|
}
|
199
138
|
|
200
139
|
##############################
|
201
|
-
#
|
140
|
+
# General provisioning jobs (not term-scoped)
|
202
141
|
##############################
|
203
142
|
|
204
|
-
#
|
205
|
-
models
|
206
|
-
try_add_model_job.call('terms')
|
143
|
+
# Terms are always synced regardless of the models option
|
144
|
+
models -= ['terms']
|
207
145
|
|
208
|
-
# Accounts, users, roles, and admins
|
146
|
+
# Accounts, users, roles, and admins cannot be scoped to term
|
209
147
|
try_add_model_job.call('accounts')
|
210
148
|
|
211
149
|
# These Models use the provisioning report, but are not term-scoped,
|
212
|
-
# so we sync them
|
150
|
+
# so we sync them outside of the term scoping to ensure work is not duplicated
|
213
151
|
if term_scope.present?
|
214
152
|
models -= (first_provisioning_models = models & ['users', 'pseudonyms'])
|
215
|
-
|
216
|
-
generate_provisioning_jobs(first_provisioning_models, options)
|
217
|
-
)
|
153
|
+
current_chain.insert(generate_provisioning_jobs(first_provisioning_models, options))
|
218
154
|
end
|
219
155
|
|
220
156
|
try_add_model_job.call('roles')
|
221
157
|
try_add_model_job.call('admins')
|
222
|
-
pre_provisioning_jobs = jobs
|
223
158
|
|
224
159
|
###############################
|
225
|
-
#
|
160
|
+
# Per-term provisioning jobs
|
226
161
|
###############################
|
227
162
|
|
228
|
-
|
163
|
+
per_term_chain = JobBatches::ChainBuilder.new(model_job_map[:terms])
|
164
|
+
per_term_chain.params[:term_scope] = term_scope
|
165
|
+
current_chain << per_term_chain
|
166
|
+
current_chain = per_term_chain
|
167
|
+
|
229
168
|
try_add_model_job.call('assignments')
|
230
169
|
try_add_model_job.call('submissions')
|
231
170
|
try_add_model_job.call('assignment_groups')
|
232
171
|
try_add_model_job.call('context_modules')
|
233
172
|
try_add_model_job.call('context_module_items')
|
234
|
-
|
173
|
+
|
174
|
+
current_chain.insert(
|
175
|
+
generate_provisioning_jobs(models, options, only_split: ['users'])
|
176
|
+
)
|
235
177
|
|
236
178
|
###############################
|
237
|
-
#
|
179
|
+
# Wrap it all up
|
238
180
|
###############################
|
239
181
|
|
240
|
-
|
241
|
-
*pre_provisioning_jobs,
|
242
|
-
*generate_provisioning_jobs(models, options, job_options: { term_scope: term_scope }, only_split: ['users']),
|
243
|
-
*post_provisioning_jobs,
|
244
|
-
]
|
245
|
-
|
246
|
-
global_options = { legacy_support: legacy_support }
|
182
|
+
global_options = { legacy_support: legacy_support, updated_after: updated_after }
|
247
183
|
global_options[:account_id] = account_id if account_id.present?
|
248
184
|
global_options.merge!(options[:global]) if options[:global].present?
|
249
185
|
|
250
|
-
|
186
|
+
root_chain.params[1] = global_options
|
187
|
+
|
188
|
+
root_chain
|
251
189
|
end
|
252
190
|
|
253
191
|
def group_by_job_options(model_list, options_hash, only_split: nil, default_key: :provisioning)
|