gooddata 1.0.0-java

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.
Files changed (517) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.editorconfig +12 -0
  4. data/.flayignore +6 -0
  5. data/.gitignore +38 -0
  6. data/.pronto.yml +3 -0
  7. data/.rspec +5 -0
  8. data/.rubocop.yml +101 -0
  9. data/.travis.yml +9 -0
  10. data/.yardopts +22 -0
  11. data/CHANGELOG.md +272 -0
  12. data/CLI.md +435 -0
  13. data/CONTRIBUTING.md +38 -0
  14. data/DEPENDENCIES.md +880 -0
  15. data/Dockerfile.jruby +17 -0
  16. data/Dockerfile.ruby +19 -0
  17. data/Gemfile +4 -0
  18. data/Guardfile +5 -0
  19. data/LICENSE +22 -0
  20. data/LICENSE.rb +5 -0
  21. data/README.md +78 -0
  22. data/Rakefile +204 -0
  23. data/TODO.md +32 -0
  24. data/authors.sh +4 -0
  25. data/bin/gooddata +7 -0
  26. data/ci.rake +47 -0
  27. data/dependency_decisions.yml +104 -0
  28. data/docker-compose.yml +34 -0
  29. data/gooddata +9 -0
  30. data/gooddata.gemspec +72 -0
  31. data/lib/gooddata.rb +34 -0
  32. data/lib/gooddata/app/app.rb +16 -0
  33. data/lib/gooddata/bricks/base_downloader.rb +86 -0
  34. data/lib/gooddata/bricks/brick.rb +37 -0
  35. data/lib/gooddata/bricks/bricks.rb +17 -0
  36. data/lib/gooddata/bricks/middleware/aws_middleware.rb +41 -0
  37. data/lib/gooddata/bricks/middleware/base_middleware.rb +57 -0
  38. data/lib/gooddata/bricks/middleware/bench_middleware.rb +25 -0
  39. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +37 -0
  40. data/lib/gooddata/bricks/middleware/decode_params_middleware.rb +21 -0
  41. data/lib/gooddata/bricks/middleware/dwh_middleware.rb +41 -0
  42. data/lib/gooddata/bricks/middleware/fs_download_middleware.rb +48 -0
  43. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +36 -0
  44. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +112 -0
  45. data/lib/gooddata/bricks/middleware/logger_middleware.rb +33 -0
  46. data/lib/gooddata/bricks/middleware/middleware.rb +12 -0
  47. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +58 -0
  48. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +23 -0
  49. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +29 -0
  50. data/lib/gooddata/bricks/middleware/undot_params_middleware.rb +37 -0
  51. data/lib/gooddata/bricks/pipeline.rb +25 -0
  52. data/lib/gooddata/bricks/utils.rb +18 -0
  53. data/lib/gooddata/cli/cli.rb +27 -0
  54. data/lib/gooddata/cli/commands/auth_cmd.rb +29 -0
  55. data/lib/gooddata/cli/commands/domain_cmd.rb +28 -0
  56. data/lib/gooddata/cli/commands/project_cmd.rb +28 -0
  57. data/lib/gooddata/cli/hooks.rb +56 -0
  58. data/lib/gooddata/cli/shared.rb +66 -0
  59. data/lib/gooddata/cli/terminal.rb +20 -0
  60. data/lib/gooddata/client.rb +67 -0
  61. data/lib/gooddata/commands/api.rb +64 -0
  62. data/lib/gooddata/commands/auth.rb +107 -0
  63. data/lib/gooddata/commands/base.rb +12 -0
  64. data/lib/gooddata/commands/commands.rb +12 -0
  65. data/lib/gooddata/commands/datasets.rb +148 -0
  66. data/lib/gooddata/commands/datawarehouse.rb +20 -0
  67. data/lib/gooddata/commands/domain.rb +40 -0
  68. data/lib/gooddata/commands/process.rb +67 -0
  69. data/lib/gooddata/commands/project.rb +144 -0
  70. data/lib/gooddata/commands/projects.rb +20 -0
  71. data/lib/gooddata/commands/role.rb +36 -0
  72. data/lib/gooddata/commands/runners.rb +47 -0
  73. data/lib/gooddata/commands/scaffold.rb +69 -0
  74. data/lib/gooddata/commands/user.rb +39 -0
  75. data/lib/gooddata/connection.rb +127 -0
  76. data/lib/gooddata/core/core.rb +12 -0
  77. data/lib/gooddata/core/logging.rb +105 -0
  78. data/lib/gooddata/core/nil_logger.rb +32 -0
  79. data/lib/gooddata/core/project.rb +74 -0
  80. data/lib/gooddata/core/rest.rb +149 -0
  81. data/lib/gooddata/core/user.rb +20 -0
  82. data/lib/gooddata/data/data.rb +12 -0
  83. data/lib/gooddata/data/guesser.rb +122 -0
  84. data/lib/gooddata/exceptions/attr_element_not_found.rb +16 -0
  85. data/lib/gooddata/exceptions/command_failed.rb +11 -0
  86. data/lib/gooddata/exceptions/exceptions.rb +12 -0
  87. data/lib/gooddata/exceptions/execution_limit_exceeded.rb +13 -0
  88. data/lib/gooddata/exceptions/export_clone.rb +4 -0
  89. data/lib/gooddata/exceptions/filter_maqlization.rb +16 -0
  90. data/lib/gooddata/exceptions/import_clone.rb +4 -0
  91. data/lib/gooddata/exceptions/malformed_user.rb +15 -0
  92. data/lib/gooddata/exceptions/maql_execution.rb +16 -0
  93. data/lib/gooddata/exceptions/no_project_error.rb +19 -0
  94. data/lib/gooddata/exceptions/object_migration.rb +32 -0
  95. data/lib/gooddata/exceptions/project_not_found.rb +13 -0
  96. data/lib/gooddata/exceptions/segment_not_empty.rb +18 -0
  97. data/lib/gooddata/exceptions/uncomputable_report.rb +13 -0
  98. data/lib/gooddata/exceptions/user_in_different_domain.rb +15 -0
  99. data/lib/gooddata/exceptions/validation_error.rb +16 -0
  100. data/lib/gooddata/extensions/big_decimal.rb +17 -0
  101. data/lib/gooddata/extensions/class.rb +11 -0
  102. data/lib/gooddata/extensions/enumerable.rb +39 -0
  103. data/lib/gooddata/extensions/extensions.rb +10 -0
  104. data/lib/gooddata/extensions/false.rb +23 -0
  105. data/lib/gooddata/extensions/hash.rb +49 -0
  106. data/lib/gooddata/extensions/integer.rb +5 -0
  107. data/lib/gooddata/extensions/nil.rb +19 -0
  108. data/lib/gooddata/extensions/numeric.rb +15 -0
  109. data/lib/gooddata/extensions/object.rb +31 -0
  110. data/lib/gooddata/extensions/string.rb +7 -0
  111. data/lib/gooddata/extensions/symbol.rb +15 -0
  112. data/lib/gooddata/extensions/true.rb +23 -0
  113. data/lib/gooddata/extract.rb +21 -0
  114. data/lib/gooddata/goodzilla/goodzilla.rb +160 -0
  115. data/lib/gooddata/helpers/auth_helpers.rb +75 -0
  116. data/lib/gooddata/helpers/csv_helper.rb +61 -0
  117. data/lib/gooddata/helpers/data_helper.rb +129 -0
  118. data/lib/gooddata/helpers/erb_helper.rb +23 -0
  119. data/lib/gooddata/helpers/global_helpers.rb +266 -0
  120. data/lib/gooddata/helpers/global_helpers_params.rb +292 -0
  121. data/lib/gooddata/helpers/helpers.rb +10 -0
  122. data/lib/gooddata/lcm/actions/actions.rb +12 -0
  123. data/lib/gooddata/lcm/actions/apply_custom_maql.rb +80 -0
  124. data/lib/gooddata/lcm/actions/associate_clients.rb +87 -0
  125. data/lib/gooddata/lcm/actions/base_action.rb +23 -0
  126. data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +53 -0
  127. data/lib/gooddata/lcm/actions/collect_client_projects.rb +78 -0
  128. data/lib/gooddata/lcm/actions/collect_clients.rb +128 -0
  129. data/lib/gooddata/lcm/actions/collect_data_product.rb +57 -0
  130. data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +62 -0
  131. data/lib/gooddata/lcm/actions/collect_ldm_objects.rb +56 -0
  132. data/lib/gooddata/lcm/actions/collect_meta.rb +88 -0
  133. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +113 -0
  134. data/lib/gooddata/lcm/actions/collect_segments.rb +72 -0
  135. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +80 -0
  136. data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +46 -0
  137. data/lib/gooddata/lcm/actions/create_segment_masters.rb +160 -0
  138. data/lib/gooddata/lcm/actions/ensure_data_product.rb +53 -0
  139. data/lib/gooddata/lcm/actions/ensure_release_table.rb +53 -0
  140. data/lib/gooddata/lcm/actions/ensure_segments.rb +32 -0
  141. data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +70 -0
  142. data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +83 -0
  143. data/lib/gooddata/lcm/actions/execute_schedules.rb +128 -0
  144. data/lib/gooddata/lcm/actions/hello_world.rb +41 -0
  145. data/lib/gooddata/lcm/actions/import_object_collections.rb +60 -0
  146. data/lib/gooddata/lcm/actions/print_actions.rb +58 -0
  147. data/lib/gooddata/lcm/actions/print_modes.rb +69 -0
  148. data/lib/gooddata/lcm/actions/print_types.rb +52 -0
  149. data/lib/gooddata/lcm/actions/provision_clients.rb +89 -0
  150. data/lib/gooddata/lcm/actions/purge_clients.rb +58 -0
  151. data/lib/gooddata/lcm/actions/rename_existing_client_projects.rb +70 -0
  152. data/lib/gooddata/lcm/actions/segments_filter.rb +50 -0
  153. data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +64 -0
  154. data/lib/gooddata/lcm/actions/synchronize_cas.rb +72 -0
  155. data/lib/gooddata/lcm/actions/synchronize_clients.rb +94 -0
  156. data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +67 -0
  157. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +155 -0
  158. data/lib/gooddata/lcm/actions/synchronize_label_types.rb +64 -0
  159. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +82 -0
  160. data/lib/gooddata/lcm/actions/synchronize_meta.rb +52 -0
  161. data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +61 -0
  162. data/lib/gooddata/lcm/actions/synchronize_processes.rb +66 -0
  163. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +91 -0
  164. data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +64 -0
  165. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +210 -0
  166. data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +53 -0
  167. data/lib/gooddata/lcm/actions/synchronize_users.rb +336 -0
  168. data/lib/gooddata/lcm/actions/update_release_table.rb +77 -0
  169. data/lib/gooddata/lcm/data/create_lcm_release.sql.erb +6 -0
  170. data/lib/gooddata/lcm/data/insert_into_lcm_release.sql.erb +11 -0
  171. data/lib/gooddata/lcm/data/select_from_lcm_release.sql.erb +8 -0
  172. data/lib/gooddata/lcm/data/update_lcm_release.sql.erb +7 -0
  173. data/lib/gooddata/lcm/dsl/dsl.rb +50 -0
  174. data/lib/gooddata/lcm/dsl/params_dsl.rb +61 -0
  175. data/lib/gooddata/lcm/dsl/type_dsl.rb +62 -0
  176. data/lib/gooddata/lcm/helpers/check_helper.rb +41 -0
  177. data/lib/gooddata/lcm/helpers/helpers.rb +12 -0
  178. data/lib/gooddata/lcm/helpers/tags_helper.rb +36 -0
  179. data/lib/gooddata/lcm/lcm.rb +325 -0
  180. data/lib/gooddata/lcm/lcm2.rb +400 -0
  181. data/lib/gooddata/lcm/types/base_type.rb +29 -0
  182. data/lib/gooddata/lcm/types/class/ads_client.rb +35 -0
  183. data/lib/gooddata/lcm/types/class/class.rb +21 -0
  184. data/lib/gooddata/lcm/types/class/gd_client.rb +35 -0
  185. data/lib/gooddata/lcm/types/class/types.rb +12 -0
  186. data/lib/gooddata/lcm/types/complex/complex.rb +33 -0
  187. data/lib/gooddata/lcm/types/complex/release_query.rb +35 -0
  188. data/lib/gooddata/lcm/types/complex/segment.rb +40 -0
  189. data/lib/gooddata/lcm/types/complex/synchronization_info.rb +35 -0
  190. data/lib/gooddata/lcm/types/complex/tokens.rb +31 -0
  191. data/lib/gooddata/lcm/types/complex/types.rb +12 -0
  192. data/lib/gooddata/lcm/types/complex/update_preference.rb +38 -0
  193. data/lib/gooddata/lcm/types/complex/users_brick_config.rb +32 -0
  194. data/lib/gooddata/lcm/types/param.rb +16 -0
  195. data/lib/gooddata/lcm/types/scalar/bool.rb +22 -0
  196. data/lib/gooddata/lcm/types/scalar/hash.rb +22 -0
  197. data/lib/gooddata/lcm/types/scalar/integer.rb +22 -0
  198. data/lib/gooddata/lcm/types/scalar/object.rb +22 -0
  199. data/lib/gooddata/lcm/types/scalar/string.rb +22 -0
  200. data/lib/gooddata/lcm/types/scalar/types.rb +12 -0
  201. data/lib/gooddata/lcm/types/special/array.rb +33 -0
  202. data/lib/gooddata/lcm/types/special/enum.rb +15 -0
  203. data/lib/gooddata/lcm/types/special/types.rb +12 -0
  204. data/lib/gooddata/lcm/types/types.rb +12 -0
  205. data/lib/gooddata/lcm/user_bricks_helper.rb +32 -0
  206. data/lib/gooddata/mixins/author.rb +26 -0
  207. data/lib/gooddata/mixins/content_getter.rb +15 -0
  208. data/lib/gooddata/mixins/content_property_reader.rb +17 -0
  209. data/lib/gooddata/mixins/content_property_writer.rb +17 -0
  210. data/lib/gooddata/mixins/contributor.rb +20 -0
  211. data/lib/gooddata/mixins/data_getter.rb +15 -0
  212. data/lib/gooddata/mixins/data_property_reader.rb +19 -0
  213. data/lib/gooddata/mixins/data_property_writer.rb +19 -0
  214. data/lib/gooddata/mixins/inspector.rb +53 -0
  215. data/lib/gooddata/mixins/is_attribute.rb +17 -0
  216. data/lib/gooddata/mixins/is_dimension.rb +17 -0
  217. data/lib/gooddata/mixins/is_fact.rb +17 -0
  218. data/lib/gooddata/mixins/is_folder.rb +11 -0
  219. data/lib/gooddata/mixins/is_label.rb +19 -0
  220. data/lib/gooddata/mixins/links.rb +15 -0
  221. data/lib/gooddata/mixins/md_finders.rb +79 -0
  222. data/lib/gooddata/mixins/md_grantees.rb +42 -0
  223. data/lib/gooddata/mixins/md_id_to_uri.rb +39 -0
  224. data/lib/gooddata/mixins/md_json.rb +15 -0
  225. data/lib/gooddata/mixins/md_lock.rb +87 -0
  226. data/lib/gooddata/mixins/md_object_id.rb +15 -0
  227. data/lib/gooddata/mixins/md_object_indexer.rb +74 -0
  228. data/lib/gooddata/mixins/md_object_query.rb +134 -0
  229. data/lib/gooddata/mixins/md_relations.rb +43 -0
  230. data/lib/gooddata/mixins/meta_getter.rb +17 -0
  231. data/lib/gooddata/mixins/meta_property_reader.rb +19 -0
  232. data/lib/gooddata/mixins/meta_property_writer.rb +19 -0
  233. data/lib/gooddata/mixins/mixins.rb +19 -0
  234. data/lib/gooddata/mixins/not_attribute.rb +17 -0
  235. data/lib/gooddata/mixins/not_exportable.rb +15 -0
  236. data/lib/gooddata/mixins/not_fact.rb +17 -0
  237. data/lib/gooddata/mixins/not_group.rb +17 -0
  238. data/lib/gooddata/mixins/not_label.rb +19 -0
  239. data/lib/gooddata/mixins/not_metric.rb +19 -0
  240. data/lib/gooddata/mixins/obj_id.rb +15 -0
  241. data/lib/gooddata/mixins/rest_getters.rb +17 -0
  242. data/lib/gooddata/mixins/rest_resource.rb +47 -0
  243. data/lib/gooddata/mixins/root_key_getter.rb +15 -0
  244. data/lib/gooddata/mixins/root_key_setter.rb +15 -0
  245. data/lib/gooddata/mixins/timestamps.rb +19 -0
  246. data/lib/gooddata/mixins/to_json.rb +11 -0
  247. data/lib/gooddata/mixins/uri_getter.rb +9 -0
  248. data/lib/gooddata/models/ads_output_stage.rb +85 -0
  249. data/lib/gooddata/models/automated_data_distribution.rb +36 -0
  250. data/lib/gooddata/models/blueprint/anchor_field.rb +65 -0
  251. data/lib/gooddata/models/blueprint/attribute_field.rb +45 -0
  252. data/lib/gooddata/models/blueprint/blueprint.rb +11 -0
  253. data/lib/gooddata/models/blueprint/blueprint_field.rb +70 -0
  254. data/lib/gooddata/models/blueprint/dashboard_builder.rb +30 -0
  255. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +455 -0
  256. data/lib/gooddata/models/blueprint/date_dimension.rb +20 -0
  257. data/lib/gooddata/models/blueprint/fact_field.rb +20 -0
  258. data/lib/gooddata/models/blueprint/label_field.rb +47 -0
  259. data/lib/gooddata/models/blueprint/project_blueprint.rb +791 -0
  260. data/lib/gooddata/models/blueprint/project_builder.rb +103 -0
  261. data/lib/gooddata/models/blueprint/reference_field.rb +43 -0
  262. data/lib/gooddata/models/blueprint/schema_blueprint.rb +160 -0
  263. data/lib/gooddata/models/blueprint/schema_builder.rb +89 -0
  264. data/lib/gooddata/models/blueprint/to_manifest.rb +185 -0
  265. data/lib/gooddata/models/blueprint/to_wire.rb +173 -0
  266. data/lib/gooddata/models/channel_configuration.rb +112 -0
  267. data/lib/gooddata/models/client.rb +236 -0
  268. data/lib/gooddata/models/client_synchronization_result.rb +31 -0
  269. data/lib/gooddata/models/client_synchronization_result_details.rb +41 -0
  270. data/lib/gooddata/models/data_product.rb +149 -0
  271. data/lib/gooddata/models/datawarehouse.rb +114 -0
  272. data/lib/gooddata/models/domain.rb +505 -0
  273. data/lib/gooddata/models/execution.rb +115 -0
  274. data/lib/gooddata/models/execution_detail.rb +81 -0
  275. data/lib/gooddata/models/from_wire.rb +173 -0
  276. data/lib/gooddata/models/invitation.rb +75 -0
  277. data/lib/gooddata/models/links.rb +50 -0
  278. data/lib/gooddata/models/membership.rb +441 -0
  279. data/lib/gooddata/models/metadata.rb +324 -0
  280. data/lib/gooddata/models/metadata/attribute.rb +155 -0
  281. data/lib/gooddata/models/metadata/dashboard.rb +120 -0
  282. data/lib/gooddata/models/metadata/dashboard/dashboard_item.rb +76 -0
  283. data/lib/gooddata/models/metadata/dashboard/filter_apply_item.rb +37 -0
  284. data/lib/gooddata/models/metadata/dashboard/filter_item.rb +64 -0
  285. data/lib/gooddata/models/metadata/dashboard/geo_chart_item.rb +56 -0
  286. data/lib/gooddata/models/metadata/dashboard/headline_item.rb +56 -0
  287. data/lib/gooddata/models/metadata/dashboard/iframe_item.rb +46 -0
  288. data/lib/gooddata/models/metadata/dashboard/report_item.rb +92 -0
  289. data/lib/gooddata/models/metadata/dashboard/text_item.rb +55 -0
  290. data/lib/gooddata/models/metadata/dashboard_tab.rb +141 -0
  291. data/lib/gooddata/models/metadata/dataset.rb +67 -0
  292. data/lib/gooddata/models/metadata/dimension.rb +57 -0
  293. data/lib/gooddata/models/metadata/fact.rb +51 -0
  294. data/lib/gooddata/models/metadata/folder.rb +49 -0
  295. data/lib/gooddata/models/metadata/label.rb +128 -0
  296. data/lib/gooddata/models/metadata/metadata.rb +12 -0
  297. data/lib/gooddata/models/metadata/metric.rb +206 -0
  298. data/lib/gooddata/models/metadata/report.rb +268 -0
  299. data/lib/gooddata/models/metadata/report_definition.rb +272 -0
  300. data/lib/gooddata/models/metadata/scheduled_mail.rb +277 -0
  301. data/lib/gooddata/models/metadata/scheduled_mail/dashboard_attachment.rb +62 -0
  302. data/lib/gooddata/models/metadata/scheduled_mail/report_attachment.rb +64 -0
  303. data/lib/gooddata/models/metadata/variable.rb +96 -0
  304. data/lib/gooddata/models/model.rb +293 -0
  305. data/lib/gooddata/models/models.rb +12 -0
  306. data/lib/gooddata/models/module_constants.rb +31 -0
  307. data/lib/gooddata/models/notification_rule.rb +113 -0
  308. data/lib/gooddata/models/process.rb +371 -0
  309. data/lib/gooddata/models/profile.rb +451 -0
  310. data/lib/gooddata/models/project.rb +2030 -0
  311. data/lib/gooddata/models/project_creator.rb +209 -0
  312. data/lib/gooddata/models/project_log_formatter.rb +204 -0
  313. data/lib/gooddata/models/project_metadata.rb +67 -0
  314. data/lib/gooddata/models/project_role.rb +79 -0
  315. data/lib/gooddata/models/report_data_result.rb +270 -0
  316. data/lib/gooddata/models/schedule.rb +538 -0
  317. data/lib/gooddata/models/segment.rb +274 -0
  318. data/lib/gooddata/models/style_setting.rb +62 -0
  319. data/lib/gooddata/models/subscription.rb +188 -0
  320. data/lib/gooddata/models/tab_builder.rb +27 -0
  321. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +76 -0
  322. data/lib/gooddata/models/user_filters/user_filter.rb +101 -0
  323. data/lib/gooddata/models/user_filters/user_filter_builder.rb +553 -0
  324. data/lib/gooddata/models/user_filters/user_filters.rb +13 -0
  325. data/lib/gooddata/models/user_filters/variable_user_filter.rb +33 -0
  326. data/lib/gooddata/models/user_group.rb +250 -0
  327. data/lib/gooddata/rest/README.md +37 -0
  328. data/lib/gooddata/rest/client.rb +396 -0
  329. data/lib/gooddata/rest/connection.rb +776 -0
  330. data/lib/gooddata/rest/object.rb +69 -0
  331. data/lib/gooddata/rest/object_factory.rb +51 -0
  332. data/lib/gooddata/rest/resource.rb +27 -0
  333. data/lib/gooddata/rest/rest.rb +24 -0
  334. data/lib/gooddata/version.rb +23 -0
  335. data/lib/templates/bricks/brick.rb.erb +7 -0
  336. data/lib/templates/bricks/main.rb.erb +5 -0
  337. data/lib/templates/project/Goodfile.erb +4 -0
  338. data/lib/templates/project/data/commits.csv +4 -0
  339. data/lib/templates/project/data/devs.csv +4 -0
  340. data/lib/templates/project/data/repos.csv +3 -0
  341. data/lib/templates/project/model/model.rb.erb +20 -0
  342. data/spec/.rubocop.yml +16 -0
  343. data/spec/bricks/bricks_spec.rb +110 -0
  344. data/spec/bricks/default-config.json +8 -0
  345. data/spec/data/.gooddata +4 -0
  346. data/spec/data/blueprints/additional_dataset_module.json +32 -0
  347. data/spec/data/blueprints/attribute_sort_order_blueprint.json +72 -0
  348. data/spec/data/blueprints/big_blueprint_not_pruned.json +2079 -0
  349. data/spec/data/blueprints/invalid_blueprint.json +103 -0
  350. data/spec/data/blueprints/m_n_model.json +104 -0
  351. data/spec/data/blueprints/model_module.json +25 -0
  352. data/spec/data/blueprints/test_blueprint.json +39 -0
  353. data/spec/data/blueprints/test_project_model_spec.json +106 -0
  354. data/spec/data/cc/data/source/commits.csv +4 -0
  355. data/spec/data/cc/data/source/devs.csv +4 -0
  356. data/spec/data/cc/data/source/repos.csv +3 -0
  357. data/spec/data/cc/devel.prm +0 -0
  358. data/spec/data/cc/graph/graph.grf +11 -0
  359. data/spec/data/cc/workspace.prm +19 -0
  360. data/spec/data/column_based_permissions.csv +7 -0
  361. data/spec/data/column_based_permissions2.csv +6 -0
  362. data/spec/data/dynamic_schedule_params_table.csv +7 -0
  363. data/spec/data/gd_gse_data_blueprint.json +1371 -0
  364. data/spec/data/gd_gse_data_manifest.json +1424 -0
  365. data/spec/data/gd_gse_data_model.json +1772 -0
  366. data/spec/data/gooddata_version_process/gooddata_version.rb +9 -0
  367. data/spec/data/gooddata_version_process/gooddata_version.zip +0 -0
  368. data/spec/data/hello_world_process/hello_world.rb +9 -0
  369. data/spec/data/hello_world_process/hello_world.zip +0 -0
  370. data/spec/data/line_based_permissions.csv +3 -0
  371. data/spec/data/manifests/test_blueprint.json +32 -0
  372. data/spec/data/manifests/test_project.json +107 -0
  373. data/spec/data/reports/left_attr_report.json +108 -0
  374. data/spec/data/reports/metric_only_one_line.json +83 -0
  375. data/spec/data/reports/report_1.json +197 -0
  376. data/spec/data/reports/top_attr_report.json +108 -0
  377. data/spec/data/ruby_params_process/ruby_params.rb +9 -0
  378. data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
  379. data/spec/data/ruby_process/process.rb +8 -0
  380. data/spec/data/ruby_process/stuff.txt +1 -0
  381. data/spec/data/superfluous_titles_view.json +81 -0
  382. data/spec/data/test-ci-data.csv +2 -0
  383. data/spec/data/users.csv +12 -0
  384. data/spec/data/wire_models/attribute_sort_by_model.json +73 -0
  385. data/spec/data/wire_models/model_view.json +1775 -0
  386. data/spec/data/wire_models/nu_model.json +3046 -0
  387. data/spec/data/wire_models/test_blueprint.json +66 -0
  388. data/spec/data/wire_test_project.json +150 -0
  389. data/spec/data/workspace_table.csv +3 -0
  390. data/spec/environment/default.rb +43 -0
  391. data/spec/environment/development.rb +32 -0
  392. data/spec/environment/environment.rb +38 -0
  393. data/spec/environment/production.rb +27 -0
  394. data/spec/environment/staging.rb +33 -0
  395. data/spec/environment/testing.rb +32 -0
  396. data/spec/helpers/blueprint_helper.rb +27 -0
  397. data/spec/helpers/cli_helper.rb +38 -0
  398. data/spec/helpers/connection_helper.rb +43 -0
  399. data/spec/helpers/crypto_helper.rb +19 -0
  400. data/spec/helpers/csv_helper.rb +20 -0
  401. data/spec/helpers/process_helper.rb +35 -0
  402. data/spec/helpers/project_helper.rb +74 -0
  403. data/spec/helpers/schedule_helper.rb +33 -0
  404. data/spec/helpers/spec_helper.rb +17 -0
  405. data/spec/integration/ads_output_stage_spec.rb +45 -0
  406. data/spec/integration/blueprint_updates_spec.rb +107 -0
  407. data/spec/integration/blueprint_with_ca_spec.rb +56 -0
  408. data/spec/integration/blueprint_with_grain_spec.rb +74 -0
  409. data/spec/integration/channel_configuration_spec.rb +67 -0
  410. data/spec/integration/clients_spec.rb +164 -0
  411. data/spec/integration/command_datawarehouse_spec.rb +45 -0
  412. data/spec/integration/command_projects_spec.rb +32 -0
  413. data/spec/integration/commands/command_projects_spec.rb +22 -0
  414. data/spec/integration/core/connection_spec.rb +56 -0
  415. data/spec/integration/core/logging_spec.rb +130 -0
  416. data/spec/integration/core/project_spec.rb +54 -0
  417. data/spec/integration/create_from_template_spec.rb +29 -0
  418. data/spec/integration/create_project_spec.rb +27 -0
  419. data/spec/integration/date_dim_switch_spec.rb +150 -0
  420. data/spec/integration/deprecated_load_spec.rb +60 -0
  421. data/spec/integration/full_process_schedule_spec.rb +367 -0
  422. data/spec/integration/full_project_spec.rb +592 -0
  423. data/spec/integration/helpers_spec.rb +16 -0
  424. data/spec/integration/lcm_spec.rb +54 -0
  425. data/spec/integration/mixins/id_to_uri_spec.rb +44 -0
  426. data/spec/integration/models/data_product_spec.rb +71 -0
  427. data/spec/integration/models/domain_spec.rb +162 -0
  428. data/spec/integration/models/invitation_spec.rb +17 -0
  429. data/spec/integration/models/membership_spec.rb +127 -0
  430. data/spec/integration/models/metadata/report_spec.rb +54 -0
  431. data/spec/integration/models/params_spec.rb +118 -0
  432. data/spec/integration/models/profile_spec.rb +210 -0
  433. data/spec/integration/models/project_role_spec.rb +94 -0
  434. data/spec/integration/models/project_spec.rb +225 -0
  435. data/spec/integration/models/schedule_spec.rb +485 -0
  436. data/spec/integration/models/unit_project_spec.rb +130 -0
  437. data/spec/integration/over_to_user_filters_spec.rb +98 -0
  438. data/spec/integration/partial_md_export_import_spec.rb +41 -0
  439. data/spec/integration/project_spec.rb +381 -0
  440. data/spec/integration/rest_spec.rb +214 -0
  441. data/spec/integration/schedule_spec.rb +613 -0
  442. data/spec/integration/segments_spec.rb +100 -0
  443. data/spec/integration/subscription_spec.rb +88 -0
  444. data/spec/integration/urn_date_dim_spec.rb +53 -0
  445. data/spec/integration/user_filters_spec.rb +306 -0
  446. data/spec/integration/user_group_spec.rb +147 -0
  447. data/spec/integration/variables_spec.rb +189 -0
  448. data/spec/logging_in_logging_out_spec.rb +91 -0
  449. data/spec/spec_helper.rb +66 -0
  450. data/spec/unit/actions/associate_clients_spec.rb +47 -0
  451. data/spec/unit/actions/collect_client_projects_spec.rb +47 -0
  452. data/spec/unit/actions/collect_clients_spec.rb +65 -0
  453. data/spec/unit/actions/collect_data_product_spec.rb +56 -0
  454. data/spec/unit/actions/collect_dynamic_schedule_params_spec.rb +56 -0
  455. data/spec/unit/actions/collect_meta_spec.rb +88 -0
  456. data/spec/unit/actions/collect_segment_clients_spec.rb +81 -0
  457. data/spec/unit/actions/collect_tagged_objects_spec.rb +126 -0
  458. data/spec/unit/actions/collect_users_brick_users_spec.rb +36 -0
  459. data/spec/unit/actions/create_segment_masters_spec.rb +64 -0
  460. data/spec/unit/actions/ensure_data_product_spec.rb +38 -0
  461. data/spec/unit/actions/ensure_technical_users_domain_spec.rb +51 -0
  462. data/spec/unit/actions/ensure_technical_users_project_spec.rb +72 -0
  463. data/spec/unit/actions/execute_schedules_spec.rb +94 -0
  464. data/spec/unit/actions/provision_clients_spec.rb +45 -0
  465. data/spec/unit/actions/purge_clients_spec.rb +47 -0
  466. data/spec/unit/actions/rename_existing_client_projects_spec.rb +54 -0
  467. data/spec/unit/actions/segments_filter_spec.rb +46 -0
  468. data/spec/unit/actions/shared_examples_for_user_actions.rb +26 -0
  469. data/spec/unit/actions/synchronize_cas_spec.rb +58 -0
  470. data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +212 -0
  471. data/spec/unit/actions/synchronize_ldm_spec.rb +57 -0
  472. data/spec/unit/actions/synchronize_user_filters_spec.rb +146 -0
  473. data/spec/unit/actions/synchronize_user_groups_spec.rb +49 -0
  474. data/spec/unit/actions/synchronize_users_spec.rb +134 -0
  475. data/spec/unit/bricks/bricks_spec.rb +34 -0
  476. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +98 -0
  477. data/spec/unit/bricks/middleware/bench_middleware_spec.rb +15 -0
  478. data/spec/unit/bricks/middleware/bulk_salesforce_middleware_spec.rb +15 -0
  479. data/spec/unit/bricks/middleware/gooddata_middleware_spec.rb +15 -0
  480. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +30 -0
  481. data/spec/unit/bricks/middleware/restforce_middleware_spec.rb +15 -0
  482. data/spec/unit/bricks/middleware/stdout_middleware_spec.rb +15 -0
  483. data/spec/unit/bricks/middleware/twitter_middleware_spec.rb +15 -0
  484. data/spec/unit/cli/cli_spec.rb +17 -0
  485. data/spec/unit/cli/commands/cmd_auth_spec.rb +17 -0
  486. data/spec/unit/core/nil_logger_spec.rb +13 -0
  487. data/spec/unit/extensions/hash_spec.rb +22 -0
  488. data/spec/unit/godzilla/goodzilla_spec.rb +74 -0
  489. data/spec/unit/helpers/csv_helper_spec.rb +22 -0
  490. data/spec/unit/helpers/data_helper_spec.rb +67 -0
  491. data/spec/unit/helpers/global_helpers_spec.rb +264 -0
  492. data/spec/unit/helpers_spec.rb +254 -0
  493. data/spec/unit/lcm/user_bricks_helper_spec.rb +58 -0
  494. data/spec/unit/models/blueprint/attribute_sort_by_spec.rb +20 -0
  495. data/spec/unit/models/blueprint/attributes_spec.rb +28 -0
  496. data/spec/unit/models/blueprint/dataset_spec.rb +120 -0
  497. data/spec/unit/models/blueprint/labels_spec.rb +43 -0
  498. data/spec/unit/models/blueprint/project_blueprint_spec.rb +642 -0
  499. data/spec/unit/models/blueprint/reference_spec.rb +28 -0
  500. data/spec/unit/models/blueprint/schema_builder_spec.rb +36 -0
  501. data/spec/unit/models/blueprint/to_wire_spec.rb +195 -0
  502. data/spec/unit/models/execution_spec.rb +109 -0
  503. data/spec/unit/models/from_wire_spec.rb +301 -0
  504. data/spec/unit/models/metadata_spec.rb +140 -0
  505. data/spec/unit/models/metric_spec.rb +129 -0
  506. data/spec/unit/models/model_spec.rb +77 -0
  507. data/spec/unit/models/project_creator_spec.rb +90 -0
  508. data/spec/unit/models/project_spec.rb +94 -0
  509. data/spec/unit/models/report_result_data_spec.rb +194 -0
  510. data/spec/unit/models/to_manifest_spec.rb +136 -0
  511. data/spec/unit/models/user_filters/user_filter_builder_spec.rb +110 -0
  512. data/spec/unit/models/user_filters_spec.rb +95 -0
  513. data/spec/unit/models/variable_spec.rb +280 -0
  514. data/spec/unit/rest/polling_spec.rb +101 -0
  515. data/spec/unit/rest/resource_spec.rb +10 -0
  516. data/yard-server.sh +3 -0
  517. metadata +1207 -0
@@ -0,0 +1,371 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'zip'
8
+ require 'uri'
9
+
10
+ require_relative '../helpers/global_helpers'
11
+ require_relative '../rest/resource'
12
+
13
+ require_relative 'execution_detail'
14
+ require_relative 'schedule'
15
+
16
+ APP_STORE_URL ||= 'https://github.com/gooddata/app_store'
17
+
18
+ module GoodData
19
+ class Process < Rest::Resource
20
+ attr_reader :data
21
+
22
+ alias_method :raw_data, :data
23
+ alias_method :json, :data
24
+ alias_method :to_hash, :data
25
+
26
+ class << self
27
+ def [](id, options = {})
28
+ project = options[:project]
29
+ c = options[:client] || (project && project.client)
30
+
31
+ if id == :all && project
32
+ uri = "/gdc/projects/#{project.pid}/dataload/processes"
33
+ data = c.get(uri)
34
+ data['processes']['items'].map do |process_data|
35
+ c.create(Process, process_data, project: project)
36
+ end
37
+ elsif id == :all
38
+ uri = "/gdc/account/profile/#{c.user.obj_id}/dataload/processes"
39
+ data = c.get(uri)
40
+ pids = data['processes']['items'].map { |process_data| process_data['process']['links']['self'].match(%r{/gdc/projects/(\w*)/})[1] }.uniq
41
+ projects_lookup = pids.pmap { |pid| c.projects(pid) }.reduce({}) do |a, e|
42
+ a[e.pid] = e
43
+ a
44
+ end
45
+
46
+ data['processes']['items'].map do |process_data|
47
+ pid = process_data['process']['links']['self'].match(%r{/gdc/projects/(\w*)/})[1]
48
+ c.create(Process, process_data, project: projects_lookup[pid])
49
+ end
50
+ else
51
+ uri = "/gdc/projects/#{project.pid}/dataload/processes/#{id}"
52
+ c.create(Process, c.get(uri), project: project)
53
+ end
54
+ end
55
+
56
+ def all
57
+ Process[:all]
58
+ end
59
+
60
+ def with_deploy(dir, options = {}, &block)
61
+ _client, project = GoodData.get_client_and_project(options)
62
+
63
+ GoodData.with_project(project) do
64
+ params = options[:params].nil? ? [] : [options[:params]]
65
+ if block
66
+ begin
67
+ res = GoodData::Process.deploy(dir, options.merge(:files_to_exclude => params))
68
+ block.call(res)
69
+ rescue => e
70
+ puts e.inspect
71
+ ensure
72
+ res.delete if res
73
+ end
74
+ else
75
+ GoodData::Process.deploy(dir, options.merge(:files_to_exclude => params))
76
+ end
77
+ end
78
+ end
79
+
80
+ def upload_package(path, files_to_exclude, opts = { :client => GoodData.connection })
81
+ GoodData.get_client_and_project(opts)
82
+ zip_and_upload(path, files_to_exclude, opts)
83
+ end
84
+
85
+ # Deploy a new process or redeploy existing one.
86
+ #
87
+ # @param path [String] Path to ZIP archive or to a directory containing files that should be ZIPed
88
+ # @option options [String] :files_to_exclude
89
+ # @option options [String] :type ('GRAPH') Type of process - GRAPH or RUBY
90
+ # @option options [String] :name Readable name of the process
91
+ # @option options [String] :process_id ID of a process to be redeployed (do not set if you want to create a new process)
92
+ # @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
93
+ def deploy(path, options = { :client => GoodData.client, :project => GoodData.project })
94
+ return deploy_brick(path, options) if path.to_s.start_with?(APP_STORE_URL)
95
+
96
+ return deploy_from_appstore(path.to_s, options) if (path.to_s =~ %r{\${.*}:(.*)\/(.*):\/}) == 0 # rubocop:disable Style/NumericPredicate
97
+
98
+ client, project = GoodData.get_client_and_project(options)
99
+
100
+ path = Pathname(path) || fail('Path is not specified')
101
+ files_to_exclude = options[:files_to_exclude].nil? ? [] : options[:files_to_exclude].map { |pname| Pathname(pname) }
102
+ process_id = options[:process_id]
103
+
104
+ type = options[:type] || 'GRAPH'
105
+ deploy_name = options[:name]
106
+ fail ArgumentError, 'options[:name] can not be nil or empty!' if deploy_name.nil? || deploy_name.empty?
107
+
108
+ verbose = options[:verbose] || false
109
+ puts HighLine.color("Deploying #{path}", HighLine::BOLD) if verbose
110
+
111
+ deployed_path = Process.upload_package(path, files_to_exclude, client: client, project: project)
112
+ data = {
113
+ :process => {
114
+ :name => deploy_name,
115
+ :path => "/uploads/#{File.basename(deployed_path)}",
116
+ :type => type
117
+ }
118
+ }
119
+
120
+ res = if process_id.nil?
121
+ client.post("/gdc/projects/#{project.pid}/dataload/processes", data)
122
+ else
123
+ client.put("/gdc/projects/#{project.pid}/dataload/processes/#{process_id}", data)
124
+ end
125
+
126
+ File.delete(deployed_path) if File.exist?(deployed_path)
127
+
128
+ if res['asyncTask']
129
+ res = client.poll_on_response(res['asyncTask']['links']['poll']) { |body| body['asyncTask'] }
130
+ end
131
+
132
+ process = client.create(Process, res, project: project)
133
+ puts HighLine.color("Deploy DONE #{path}", HighLine::GREEN) if verbose
134
+ process
135
+ end
136
+
137
+ def deploy_brick(path, options = { :client => GoodData.client, :project => GoodData.project })
138
+ client, project = GoodData.get_client_and_project(options)
139
+
140
+ brick_uri_parts = URI(path).path.split('/')
141
+ ref = brick_uri_parts[4]
142
+ brick_name = brick_uri_parts.last
143
+ brick_path = brick_uri_parts[5..-1].join('/')
144
+
145
+ Dir.mktmpdir do |dir|
146
+ Dir.chdir(dir) do
147
+ `git clone #{APP_STORE_URL}`
148
+ end
149
+
150
+ Dir.chdir(File.join(dir, 'app_store')) do
151
+ if ref
152
+ `git checkout #{ref}`
153
+
154
+ fail 'Wrong branch or tag specified!' if $CHILD_STATUS.to_i.nonzero?
155
+ end
156
+
157
+ opts = {
158
+ :client => client,
159
+ :project => project,
160
+ :name => brick_name,
161
+ :type => 'RUBY'
162
+ }
163
+
164
+ full_brick_path = File.join(dir, 'app_store', brick_path)
165
+
166
+ unless File.exist?(full_brick_path)
167
+ fail "Invalid brick name specified - '#{brick_name}'"
168
+ end
169
+
170
+ return deploy(full_brick_path, opts)
171
+ end
172
+ end
173
+ end
174
+
175
+ def deploy_from_appstore(path, options = { :client => GoodData.client, :project => GoodData.project })
176
+ client, project = GoodData.get_client_and_project(options)
177
+
178
+ deploy_name = options[:name]
179
+ fail ArgumentError, 'options[:name] can not be nil or empty!' if deploy_name.nil? || deploy_name.empty?
180
+
181
+ verbose = options[:verbose] || false
182
+ puts HighLine.color("Deploying #{path}", HighLine::BOLD) if verbose
183
+
184
+ process_id = options[:process_id]
185
+
186
+ data = {
187
+ process: {
188
+ name: deploy_name,
189
+ path: path,
190
+ type: 'RUBY'
191
+ }
192
+ }
193
+
194
+ res =
195
+ if process_id.nil?
196
+ client.post("/gdc/projects/#{project.pid}/dataload/processes", data)
197
+
198
+ else
199
+ client.put("/gdc/projects/#{project.pid}/dataload/processes/#{process_id}", data)
200
+
201
+ end
202
+
203
+ if res.keys.first == 'asyncTask'
204
+ res = JSON.parse(client.poll_on_code(res['asyncTask']['links']['poll'], options.merge(process: false)))
205
+ end
206
+
207
+ process = client.create(Process, res, project: project)
208
+ puts HighLine.color("Deploy DONE #{path}", HighLine::GREEN) if verbose
209
+ process
210
+ end
211
+
212
+ private
213
+
214
+ def with_zip(opts = {})
215
+ client = opts[:client]
216
+ temp = Tempfile.new(['deploy-graph-archive', '.zip'])
217
+ zip_filename = temp.path
218
+
219
+ temp.close!
220
+ Zip::File.open(zip_filename, Zip::File::CREATE) do |zipfile|
221
+ yield zipfile
222
+ end
223
+ client.upload_to_user_webdav(zip_filename, opts)
224
+ zip_filename
225
+ end
226
+
227
+ def zip_and_upload(path, files_to_exclude, opts = {})
228
+ client = opts[:client]
229
+ puts 'Creating package for upload'
230
+ if !path.directory? && (path.extname == '.grf' || path.extname == '.rb')
231
+ with_zip(opts) do |zipfile|
232
+ zipfile.add(File.basename(path), path)
233
+ end
234
+ elsif !path.directory?
235
+ # this branch expects a zipped file. Since the filename on webdav is by default
236
+ # equal to the filename of a local file. I happened often that the name clashed
237
+ # if ran in parallel. Create a randomized name to mitigate that
238
+ randomized_filename = (0...16).map { (65 + rand(26)).chr }.join
239
+ client.upload_to_user_webdav(path, { filename: randomized_filename }.merge(opts))
240
+ randomized_filename
241
+ else
242
+ with_zip(opts) do |zipfile|
243
+ files_to_upload = Dir[File.join(path, '**', '**')].reject { |f| files_to_exclude.include?(Pathname(path) + f) }
244
+ puts "Uploading #{files_to_upload.count} files."
245
+ files_to_upload.each do |file|
246
+ file_pathname = Pathname.new(file)
247
+ file_relative_pathname = file_pathname.relative_path_from(Pathname.new(path))
248
+ zipfile.add(file_relative_pathname, file)
249
+ end
250
+ end
251
+ end
252
+ end
253
+ # -----------------------------
254
+ end
255
+
256
+ def initialize(data)
257
+ @data = data
258
+ end
259
+
260
+ def delete
261
+ client.delete(uri)
262
+ end
263
+
264
+ # Redeploy existing process.
265
+ #
266
+ # @param path [String] Path to ZIP archive or to a directory containing files that should be ZIPed
267
+ # @option options [String] :files_to_exclude
268
+ # @option options [String] :process_id ('nobody') From address
269
+ # @option options [String] :type ('GRAPH') Type of process - GRAPH or RUBY
270
+ # @option options [String] :name Readable name of the process
271
+ # @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
272
+ def deploy(path, options = {})
273
+ Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type }.merge(options))
274
+ end
275
+
276
+ # Downloads the process from S3 in a zipped form.
277
+ #
278
+ # @return [IO] The stream of data that represents a zipped deployed process.
279
+ def download
280
+ link = links['source']
281
+ client.connection.refresh_token
282
+ client.get(link, process: false) { |_, _, result| RestClient.get(result.to_hash['location'].first) }
283
+ end
284
+
285
+ def process
286
+ data['process']
287
+ end
288
+
289
+ def name
290
+ process['name']
291
+ end
292
+
293
+ def type
294
+ process['type'].downcase.to_sym
295
+ end
296
+
297
+ def links
298
+ process['links']
299
+ end
300
+
301
+ def link
302
+ links['self']
303
+ end
304
+
305
+ alias_method :uri, :link
306
+
307
+ def obj_id
308
+ uri.split('/').last
309
+ end
310
+
311
+ alias_method :process_id, :obj_id
312
+
313
+ def executions_link
314
+ links['executions']
315
+ end
316
+
317
+ def graphs
318
+ process['graphs']
319
+ end
320
+
321
+ def executables
322
+ process['executables']
323
+ end
324
+
325
+ def path
326
+ process['path']
327
+ end
328
+
329
+ def schedules
330
+ project.schedules.select { |schedule| schedule.process_id == obj_id }
331
+ end
332
+
333
+ def create_schedule(cron, executable, options = {})
334
+ project.create_schedule(process_id, cron, executable, options.merge(client: client, project: project))
335
+ end
336
+
337
+ def execute(executable, options = {})
338
+ result = start_execution(executable, options)
339
+ begin
340
+ client.poll_on_code(result['executionTask']['links']['poll'], options)
341
+ rescue RestClient::RequestFailed => e
342
+ raise(e)
343
+ ensure
344
+ result = client.get(result['executionTask']['links']['detail'])
345
+ if result['executionDetail']['status'] == 'ERROR'
346
+ fail "Runing process failed. You can look at a log here #{result['executionDetail']['logFileName']}"
347
+ end
348
+ end
349
+ client.create(GoodData::ExecutionDetail, result, client: client, project: project)
350
+ end
351
+
352
+ def start_execution(executable, options = {})
353
+ params = options[:params] || {}
354
+ hidden_params = options[:hidden_params] || {}
355
+ client.post(executions_link,
356
+ :execution => {
357
+ :graph => executable.to_s,
358
+ :params => GoodData::Helpers.encode_public_params(params),
359
+ :hiddenParams => GoodData::Helpers.encode_hidden_params(hidden_params)
360
+ })
361
+ end
362
+
363
+ def notification_rules
364
+ NotificationRule.all(project: project, process: self, client: client)
365
+ end
366
+
367
+ def create_notification_rule(opts = {})
368
+ NotificationRule.create(opts.merge(project: project, process: self, client: client))
369
+ end
370
+ end
371
+ end
@@ -0,0 +1,451 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'pmap'
8
+
9
+ require_relative '../rest/object'
10
+
11
+ require_relative 'project'
12
+
13
+ module GoodData
14
+ class Profile < Rest::Resource
15
+ attr_reader :user, :json
16
+
17
+ EMPTY_OBJECT = {
18
+ 'accountSetting' => {
19
+ 'companyName' => nil,
20
+ 'country' => nil,
21
+ 'created' => nil,
22
+ 'firstName' => nil,
23
+ 'lastName' => nil,
24
+ 'login' => nil,
25
+ 'phoneNumber' => nil,
26
+ 'position' => nil,
27
+ 'timezone' => nil,
28
+ 'updated' => nil,
29
+ 'language' => nil,
30
+ 'links' => {
31
+ 'projects' => nil,
32
+ 'self' => nil
33
+ },
34
+ 'email' => nil,
35
+ 'authenticationModes' => []
36
+ }
37
+ }
38
+
39
+ ASSIGNABLE_MEMBERS = [
40
+ :company,
41
+ :country,
42
+ :email,
43
+ :login,
44
+ :first_name,
45
+ :last_name,
46
+ :phone,
47
+ :position,
48
+ :timezone,
49
+ :language
50
+ ]
51
+
52
+ PROFILE_PATH = '/gdc/account/profile/%s'
53
+
54
+ class << self
55
+ # Get profile by ID or URI
56
+ #
57
+ # @param id ID or URI of user to be found
58
+ # @param [Hash] opts Additional optional options
59
+ # @option opts [GoodData::Rest::Client] :client Client used for communication with server
60
+ # @return GoodData::Profile User Profile
61
+ def [](id, opts = { client: GoodData.connection })
62
+ return id if id.instance_of?(GoodData::Profile) || id.respond_to?(:profile?) && id.profile?
63
+
64
+ if id.to_s !~ %r{^(\/gdc\/account\/profile\/)?[a-zA-Z\d]+$}
65
+ fail(ArgumentError, 'wrong type of argument. Should be either profile ID or path')
66
+ end
67
+
68
+ id = id.match(/[a-zA-Z\d]+$/)[0] if id =~ %r{/}
69
+
70
+ c = client(opts)
71
+ fail ArgumentError, 'No :client specified' if c.nil?
72
+
73
+ response = c.get(PROFILE_PATH % id)
74
+ c.factory.create(Profile, response)
75
+ end
76
+
77
+ # Creates new instance from hash with attributes
78
+ #
79
+ # @param attributes [Hash] Hash with initial attributes
80
+ # @return [GoodData::Profile] New profile instance
81
+ def create(attributes)
82
+ res = create_object(attributes)
83
+ res.save!
84
+ res
85
+ end
86
+
87
+ def create_object(attributes)
88
+ json = GoodData::Helpers.deep_dup(EMPTY_OBJECT)
89
+ json['accountSetting']['links']['self'] = attributes[:uri] if attributes[:uri]
90
+ res = client.create(GoodData::Profile, json)
91
+
92
+ attributes.each do |k, v|
93
+ res.send("#{k}=", v) if ASSIGNABLE_MEMBERS.include? k
94
+ end
95
+ res
96
+ end
97
+
98
+ def diff(item1, item2)
99
+ x = diff_list([item1], [item2])
100
+ return {} if x[:changed].empty?
101
+ x[:changed].first[:diff]
102
+ end
103
+
104
+ def diff_list(list1, list2)
105
+ GoodData::Helpers.diff(list1, list2, key: :login)
106
+ end
107
+
108
+ # Gets user currently logged in
109
+ # @return [GoodData::Profile] User currently logged-in
110
+ def current
111
+ client.user
112
+ end
113
+ end
114
+
115
+ # Creates new instance
116
+ #
117
+ # @return [Profile] New Profile instance
118
+ def initialize(json)
119
+ @json = json
120
+ @dirty = false
121
+ end
122
+
123
+ # Checks objects for equality
124
+ #
125
+ # @param right [GoodData::Profile] Project to compare with
126
+ # @return [Boolean] True if same else false
127
+ def ==(other)
128
+ return false unless other.respond_to?(:to_hash)
129
+ to_hash == other.to_hash
130
+ end
131
+
132
+ # Checks objects for non-equality
133
+ #
134
+ # @param right [GoodData::Profile] Project to compare with
135
+ # @return [Boolean] True if different else false
136
+ def !=(other)
137
+ !(self == other)
138
+ end
139
+
140
+ # Apply changes to object.
141
+ #
142
+ # @param changes [Hash] Hash with modifications
143
+ # @return [GoodData::Profile] Modified object
144
+ # def apply(changes)
145
+ # GoodData::Profile.apply(self, changes)
146
+ # end
147
+
148
+ # Gets the company name
149
+ #
150
+ # @return [String] Company name
151
+ def company
152
+ @json['accountSetting']['companyName'] || ''
153
+ end
154
+
155
+ # Set the company name
156
+ #
157
+ # @param val [String] Company name to be set
158
+ def company=(val)
159
+ @dirty ||= company != val
160
+ @json['accountSetting']['companyName'] = val
161
+ end
162
+
163
+ # Gets the language
164
+ #
165
+ # @return [String] Language
166
+ def language
167
+ @json['accountSetting']['language'] || 'en-US'
168
+ end
169
+
170
+ # Set the language
171
+ #
172
+ # @param val [String] Language to be set
173
+ def language=(val)
174
+ @dirty ||= language != val
175
+ @json['accountSetting']['language'] = val
176
+ end
177
+
178
+ # Gets the country
179
+ #
180
+ # @return [String] Country
181
+ def country
182
+ @json['accountSetting']['country'] || ''
183
+ end
184
+
185
+ # Set the country
186
+ #
187
+ # @param val [String] Country to be set
188
+ def country=(val)
189
+ @dirty ||= country != val
190
+ @json['accountSetting']['country'] = val
191
+ end
192
+
193
+ # Gets date when created
194
+ #
195
+ # @return [DateTime] Created date
196
+ def created
197
+ DateTime.parse(@json['accountSetting']['created'])
198
+ end
199
+
200
+ # Deletes this account settings
201
+ def delete
202
+ client.delete uri
203
+ end
204
+
205
+ # Gets hash representing diff of profiles
206
+ #
207
+ # @param user [GoodData::Profile] Another profile to compare with
208
+ # @return [Hash] Hash representing diff
209
+ def diff(user)
210
+ GoodData::Profile.diff(self, user)
211
+ end
212
+
213
+ # Gets the email
214
+ #
215
+ # @return [String] Email address
216
+ def email
217
+ @json['accountSetting']['email'] || ''
218
+ end
219
+
220
+ # Set the email
221
+ #
222
+ # @param val [String] Email to be set
223
+ def email=(val)
224
+ @dirty ||= email != val
225
+ @json['accountSetting']['email'] = val
226
+ end
227
+
228
+ # Gets the first name
229
+ #
230
+ # @return [String] First name
231
+ def first_name
232
+ @json['accountSetting']['firstName'] || ''
233
+ end
234
+
235
+ # Set the first name
236
+ #
237
+ # @param val [String] First name to be set
238
+ def first_name=(val)
239
+ @dirty ||= first_name != val
240
+ @json['accountSetting']['firstName'] = val
241
+ end
242
+
243
+ # Get full name
244
+ #
245
+ # @return String Full Name
246
+ # NOTE: This can be tricky to implement correctly for i18n
247
+ def full_name
248
+ "#{first_name} #{last_name}"
249
+ end
250
+
251
+ alias_method :title, :full_name
252
+
253
+ # Gets the last name
254
+ #
255
+ # @return [String] Last name
256
+ def last_name
257
+ @json['accountSetting']['lastName'] || ''
258
+ end
259
+
260
+ # Set the last name
261
+ #
262
+ # @param val [String] Last name to be set
263
+ def last_name=(val)
264
+ @dirty ||= last_name != val
265
+ @json['accountSetting']['lastName'] = val
266
+ end
267
+
268
+ # Gets the login
269
+ #
270
+ # @return [String] Login
271
+ def login
272
+ @json['accountSetting']['login'] || ''
273
+ end
274
+
275
+ # Set the login
276
+ #
277
+ # @param val [String] Login to be set
278
+ def login=(val)
279
+ @dirty ||= login != val
280
+ @json['accountSetting']['login'] = val
281
+ end
282
+
283
+ # Gets the resource identifier
284
+ #
285
+ # @return [String] Resource identifier
286
+ def obj_id
287
+ uri.split('/').last
288
+ end
289
+
290
+ alias_method :account_setting_id, :obj_id
291
+
292
+ # Gets the phone
293
+ #
294
+ # @return [String] Phone
295
+ def phone
296
+ @json['accountSetting']['phoneNumber'] || ''
297
+ end
298
+
299
+ alias_method :phone_number, :phone
300
+
301
+ # Set the phone
302
+ #
303
+ # @param val [String] Phone to be set
304
+ def phone=(val)
305
+ @dirty ||= phone != val
306
+ @json['accountSetting']['phoneNumber'] = val
307
+ end
308
+
309
+ alias_method :phone_number=, :phone=
310
+
311
+ # Gets the position in company
312
+ #
313
+ # @return [String] Position in company
314
+ def position
315
+ @json['accountSetting']['position'] || ''
316
+ end
317
+
318
+ # Set the position
319
+ #
320
+ # @param val [String] Position to be set
321
+ def position=(val)
322
+ @dirty ||= position != val
323
+ @json['accountSetting']['position'] = val
324
+ end
325
+
326
+ # Gets the array of projects
327
+ #
328
+ # @return [Array<GoodData::Project>] Array of project where account settings belongs to
329
+ def projects
330
+ projects = client.get @json['accountSetting']['links']['projects']
331
+ projects['projects'].map do |project|
332
+ client.create(GoodData::Project, project)
333
+ end
334
+ end
335
+
336
+ # Saves object if dirty, clears dirty flag
337
+ def save!
338
+ if @dirty
339
+ raw = @json.dup
340
+ raw['accountSetting'].delete('login')
341
+
342
+ if uri && !uri.empty?
343
+ url = "/gdc/account/profile/#{obj_id}"
344
+ @json = client.put url, raw
345
+ @dirty = false
346
+ end
347
+ end
348
+ self
349
+ end
350
+
351
+ # Gets the preferred timezone
352
+ #
353
+ # @return [String] Preferred timezone
354
+ def timezone
355
+ @json['accountSetting']['timezone'] || ''
356
+ end
357
+
358
+ # Set the timezone
359
+ #
360
+ # @param val [String] Timezone to be set
361
+ def timezone=(val)
362
+ @dirty ||= timezone != val
363
+ @json['accountSetting']['timezone'] = val
364
+ end
365
+
366
+ # Gets the date when updated
367
+ #
368
+ # @return [DateTime] Updated date
369
+ def updated
370
+ DateTime.parse(@json['accountSetting']['updated'])
371
+ end
372
+
373
+ # Gets the resource REST URI
374
+ #
375
+ # @return [String] Resource URI
376
+ def uri
377
+ GoodData::Helpers.get_path(@json, %w(accountSetting links self))
378
+ end
379
+
380
+ def data
381
+ data = @json || {}
382
+ data['accountSetting'] || {}
383
+ end
384
+
385
+ def links
386
+ data['links'] || {}
387
+ end
388
+
389
+ def content
390
+ keys = (data.keys - ['links'])
391
+ data.slice(*keys)
392
+ end
393
+
394
+ def name
395
+ (first_name || '') + (last_name || '')
396
+ end
397
+
398
+ def password
399
+ @json['accountSetting']['password']
400
+ end
401
+
402
+ def password=(a_password)
403
+ @dirty = true
404
+ @json['accountSetting']['password'] = a_password
405
+ end
406
+
407
+ def sso_provider
408
+ @json['accountSetting']['ssoProvider']
409
+ end
410
+
411
+ def sso_provider=(an_sso_provider)
412
+ @dirty = true
413
+ @json['accountSetting']['ssoProvider'] = an_sso_provider
414
+ end
415
+
416
+ def authentication_modes
417
+ @json['accountSetting']['authenticationModes'].map { |x| x.downcase.to_sym }
418
+ end
419
+
420
+ def authentication_modes=(modes)
421
+ modes = Array(modes)
422
+ @dirty = true
423
+ @json['accountSetting']['authenticationModes'] = modes.map { |x| x.to_s.upcase }
424
+ end
425
+
426
+ def to_hash
427
+ tmp = GoodData::Helpers.symbolize_keys(content.merge(uri: uri))
428
+ [
429
+ [:companyName, :company],
430
+ [:phoneNumber, :phone],
431
+ [:firstName, :first_name],
432
+ [:lastName, :last_name],
433
+ [:authenticationModes, :authentication_modes],
434
+ [:ssoProvider, :sso_provider]
435
+ ].each do |vals|
436
+ wire, rb = vals
437
+ tmp[rb] = tmp[wire]
438
+ tmp.delete(wire)
439
+ end
440
+ tmp
441
+ end
442
+
443
+ def create_channel
444
+ GoodData::ChannelConfiguration.create(to: email, title: email, client: client)
445
+ end
446
+
447
+ def channels
448
+ GoodData::ChannelConfiguration.all(client: client)
449
+ end
450
+ end
451
+ end