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,13 @@
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 'pathname'
8
+
9
+ base = Pathname(__FILE__).dirname.expand_path
10
+
11
+ Dir.glob(base + '*.rb').each do |file|
12
+ require_relative file
13
+ end
@@ -0,0 +1,33 @@
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_relative 'user_filter'
8
+
9
+ module GoodData
10
+ class VariableUserFilter < UserFilter
11
+ # Creates or updates the variable user filter on the server
12
+ #
13
+ # @return [String]
14
+ def save
15
+ res = client.post(uri, :variable => @json)
16
+ @json[:uri] = res['uri']
17
+ self
18
+ end
19
+
20
+ # Method used for replacing values in their state according to mapping.
21
+ # Can be used to replace any values but it is typically used to replace
22
+ # the URIs. Returns a new object of the same type.
23
+ #
24
+ # @param [Array<Array>]Mapping specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.
25
+ # @return [GoodData::VariableUserFilter]
26
+ def replace(mapping)
27
+ x = GoodData::MdObject.replace_quoted(self, mapping)
28
+ x = GoodData::MdObject.replace_bracketed(x, mapping)
29
+ vals = GoodData::MdObject.find_replaceable_values(x, mapping)
30
+ GoodData::MdObject.replace_bracketed(x, vals)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,250 @@
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_relative '../rest/rest'
8
+ require_relative '../rest/resource'
9
+ require_relative '../mixins/author'
10
+ require_relative '../mixins/contributor'
11
+ require_relative '../mixins/links'
12
+ require_relative '../mixins/rest_resource'
13
+ require_relative '../mixins/uri_getter'
14
+
15
+ module GoodData
16
+ # Representation of User Group
17
+ #
18
+ # Use user groups to manage user access to dashboards on the GoodData Portal.
19
+ # Create groups to more quickly manage permissions for users with
20
+ # the the same role or who need similar access to dashboards.
21
+ # Groups can be part of groups.
22
+ class UserGroup < Rest::Resource
23
+ include Mixin::Author
24
+ include Mixin::Contributor
25
+ include Mixin::Links
26
+ include Mixin::UriGetter
27
+
28
+ EMPTY_OBJECT = {
29
+ 'userGroup' => {
30
+ 'content' => {
31
+ 'name' => nil,
32
+ 'description' => nil,
33
+ 'project' => nil
34
+ }
35
+ }
36
+ }
37
+
38
+ class << self
39
+ # Returns list of all clients or a particular client
40
+ #
41
+ # @param id [String|Symbol] Uri of the segment required or :all for all segments.
42
+ # @return [Array<GoodData::Segment>] List of segments for a particular domain
43
+ def [](id, opts = {})
44
+ # TODO: Replace with GoodData.get_client_and_project(opts)
45
+ project = opts[:project]
46
+ fail 'Project has to be passed in options' unless project
47
+ fail 'Project has to be of type GoodData::Project' unless project.is_a?(GoodData::Project)
48
+ client = project.client
49
+
50
+ results = client.get('/gdc/userGroups', params: { :project => project.pid, :user => opts[:user] }.compact)
51
+ groups = GoodData::Helpers.get_path(results, %w(userGroups items)).map { |i| client.create(GoodData::UserGroup, i, :project => project) }
52
+ id == :all ? groups : groups.find { |g| g.obj_id == id || g.name == id }
53
+ end
54
+
55
+ # Create new user group
56
+ #
57
+ # Should not be called directly. Use GoodData::Project.add_user_group.
58
+ # @param data [Hash] Initial data
59
+ # @option data name [String]
60
+ # @option data description [String]
61
+ # @option data project [GoodData::Project]
62
+ # @return [UserGroup] Newly created user group
63
+ def create(data)
64
+ new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
65
+ d['userGroup']['content']['name'] = data[:name]
66
+ d['userGroup']['content']['description'] = data[:description]
67
+ d['userGroup']['content']['project'] = data[:project].uri
68
+ end
69
+
70
+ client = data[:project].client
71
+
72
+ group = client.create(GoodData::UserGroup, GoodData::Helpers.stringify_keys(new_data))
73
+ group.project = data[:project]
74
+ group
75
+ end
76
+
77
+ # Constructs payload for user management/manipulation
78
+ #
79
+ # @return [Hash] Created payload
80
+ def construct_payload(users, operation)
81
+ users = users.is_a?(Array) ? users : [users]
82
+
83
+ {
84
+ modifyMembers: {
85
+ operation: operation,
86
+ items: users.map do |user|
87
+ uri = user.respond_to?(:uri) ? user.uri : user
88
+ fail 'You cannot add group as member of another group as of now.' if uri =~ %r{^\/gdc\/userGroups\/}
89
+ uri
90
+ end
91
+ }
92
+ }
93
+ end
94
+
95
+ # URI used for membership manipulation/managementv
96
+ #
97
+ # @param client [Client] Client used for communication with platform
98
+ # @param users [User | String | Array<User> | Array<String>] User(s) to be modified
99
+ # @param operation [String] Operation to be performed - ADD, SET, REMOVE
100
+ # @param uri [String] URI to be used for operation
101
+ # @return [String] URI used for membership manipulation/management
102
+ def modify_users(client, users, operation, uri)
103
+ payload = construct_payload(users, operation)
104
+ client.post(uri, payload)
105
+ end
106
+ end
107
+
108
+ # Initialize object with json
109
+ #
110
+ # @return [UserGroup] User Group object initialized with json
111
+ def initialize(json)
112
+ @json = json
113
+ self
114
+ end
115
+
116
+ # Add member(s) to user group
117
+ #
118
+ # @param [String | User | Array<User>] Users to add to user group
119
+ # @return [nil] Nothing is returned
120
+ def add_members(user)
121
+ UserGroup.modify_users(client, user, 'ADD', uri_modify_members)
122
+ end
123
+
124
+ alias_method :add_member, :add_members
125
+
126
+ # Gets user group name
127
+ #
128
+ # @return [String] User group name
129
+ def name
130
+ content['name']
131
+ end
132
+
133
+ # Sets user group name
134
+ #
135
+ # @param name [String] New user group name
136
+ # @return [String] New user group name
137
+ def name=(name)
138
+ content['name'] = name
139
+ name
140
+ end
141
+
142
+ # Gets user group description
143
+ #
144
+ # @return [String] User group description
145
+ def description
146
+ content['description']
147
+ end
148
+
149
+ # Sets user group description
150
+ #
151
+ # @param name [String] New user group description
152
+ # @return [String] New user group description
153
+ def description=(name)
154
+ content['description'] = name
155
+ end
156
+
157
+ # Gets Users with this Role
158
+ #
159
+ # @return [Array<GoodData::Profile>] List of users
160
+ def members
161
+ url = GoodData::Helpers.get_path(data, %w(links members))
162
+ return [] unless url
163
+ Enumerator.new do |y|
164
+ loop do
165
+ res = client.get url
166
+ res['userGroupMembers']['paging']['next']
167
+ res['userGroupMembers']['items'].each do |member|
168
+ case member.keys.first
169
+ when 'user'
170
+ y << client.create(GoodData::Profile, client.get(GoodData::Helpers.get_path(member, %w(user links self))), :project => project)
171
+ when 'userGroup'
172
+ y << client.create(UserGroup, client.get(GoodData::Helpers.get_path(member, %w(userGroup links self))), :project => project)
173
+ end
174
+ end
175
+ url = res['userGroupMembers']['paging']['next']
176
+ break unless url
177
+ end
178
+ end
179
+ end
180
+
181
+ # Verifies if user is in a group or any nested group and returns true if it does
182
+ #
183
+ # @return [Boolean] Retruns true if member is member of the group or any of its members
184
+ def member?(a_member)
185
+ # could be better on API directly?
186
+ uri = a_member.respond_to?(:uri) ? a_member.uri : a_member
187
+ members.map(&:uri).include?(uri)
188
+ end
189
+
190
+ # Save user group
191
+ # New group is created if needed else existing one is updated
192
+ #
193
+ # @return [UserGroup] Created or updated user group
194
+ def save
195
+ if uri
196
+ # get rid of unsupported keys
197
+ data = json['userGroup']
198
+ client.put(uri, 'userGroup' => data.except('meta', 'links'))
199
+ @json = client.get(uri)
200
+ else
201
+ response = client.post('/gdc/userGroups', @json)
202
+ @json = client.get(response['uri'])
203
+ end
204
+ self
205
+ end
206
+
207
+ # Remove member(s) from user group
208
+ #
209
+ # @param [String | User | Array<User>] Users to remove from user group
210
+ # @return [nil] Nothing is returned
211
+ def remove_members(user)
212
+ UserGroup.modify_users(client, user, 'REMOVE', uri_modify_members)
213
+ end
214
+
215
+ alias_method :remove_member, :remove_members
216
+
217
+ # Set member(s) to user group.
218
+ # Only users passed to this call will be new members of user group.
219
+ # Old members not passed to this method will be removed!
220
+ #
221
+ # @param [String | User | Array<User>] Users to set as members of user group
222
+ # @return [nil] Nothing is returned
223
+ def set_members(user) # rubocop:disable Style/AccessorMethodName
224
+ UserGroup.modify_users(client, user, 'SET', uri_modify_members)
225
+ end
226
+
227
+ alias_method :set_member, :set_members
228
+
229
+ # URI used for membership manipulation/management
230
+ #
231
+ # @return [String] URI used for membership manipulation/management
232
+ def uri_modify_members
233
+ links['modifyMembers']
234
+ end
235
+
236
+ # Is it a user group?
237
+ #
238
+ # @return [Boolean] Return true if it is a user group
239
+ def user_group?
240
+ true
241
+ end
242
+
243
+ # Checks if two user groups are same
244
+ #
245
+ # @return [Boolean] Return true if the two groups are same
246
+ def ==(other)
247
+ uri == other.uri
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,37 @@
1
+ # Rest
2
+
3
+ Proof of Concept of GoodWay of dealing with non-perfect REST Endpoints
4
+
5
+ ## Terminology
6
+
7
+ Terms like 'MUST', 'MUST NOT', 'SHALL', 'SHALL NOT' are used as defined in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)
8
+
9
+ ## Architecture
10
+
11
+ There are few basic classes.
12
+
13
+ - Connection
14
+ - Client
15
+ - Factory
16
+ - Object
17
+ - Resource
18
+
19
+ ## Connection
20
+
21
+ Low-level network connection
22
+
23
+ ## Client
24
+
25
+ User's interface to GoodData Platform.
26
+
27
+ ## Factory
28
+
29
+ Authority responsible for creating Object bounded to some Connection.
30
+
31
+ ## Object
32
+
33
+ Remote REST-like accessible content.
34
+
35
+ ## Resource
36
+
37
+ Objects which are (at least mimicking to be) first class citizen REST Resource with full CRUD
@@ -0,0 +1,396 @@
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 'rest-client'
8
+
9
+ require_relative '../helpers/auth_helpers'
10
+ require_relative '../helpers/global_helpers'
11
+
12
+ require_relative 'connection'
13
+ require_relative 'object_factory'
14
+
15
+ require_relative '../mixins/inspector'
16
+
17
+ module GoodData
18
+ module Rest
19
+ # User's interface to GoodData Platform.
20
+ #
21
+ # MUST provide way to use - DELETE, GET, POST, PUT
22
+ # SHOULD provide way to use - HEAD, Bulk GET ...
23
+ class Client
24
+ #################################
25
+ # Constants
26
+ #################################
27
+ DEFAULT_CONNECTION_IMPLEMENTATION = GoodData::Rest::Connection
28
+ DEFAULT_SLEEP_INTERVAL = 10
29
+ DEFAULT_POLL_TIME_LIMIT = 5 * 60 * 60 # 5 hours
30
+
31
+ #################################
32
+ # Class variables
33
+ #################################
34
+ @@instance = nil # rubocop:disable ClassVars
35
+
36
+ #################################
37
+ # Getters/Setters
38
+ #################################
39
+
40
+ # Decide if we need provide direct access to connection
41
+ attr_reader :connection
42
+
43
+ # TODO: Decide if we need provide direct access to factory
44
+ attr_reader :factory
45
+ attr_reader :opts
46
+
47
+ include Mixin::Inspector
48
+ inspector :object_id
49
+
50
+ #################################
51
+ # Class methods
52
+ #################################
53
+ class << self
54
+ # Globally available way to connect (and create client and set global instance)
55
+ #
56
+ # ## HACK
57
+ # To make transition from old implementation to new one following HACK IS TEMPORARILY ENGAGED!
58
+ #
59
+ # 1. First call of #connect sets the GoodData::Rest::Client.instance (static, singleton instance)
60
+ # 2. There are METHOD functions with same signature as their CLASS counterparts using singleton instance
61
+ #
62
+ # ## Example
63
+ #
64
+ # client = GoodData.connect('jon.smith@goodddata.com', 's3cr3tp4sw0rd')
65
+ #
66
+ # @param username [String] Username to be used for authentication
67
+ # @param password [String] Password to be used for authentication
68
+ # @return [GoodData::Rest::Client] Client
69
+ def connect(username, password = 'aaaa', opts = {})
70
+ if username.nil? && password.nil?
71
+ username = ENV['GD_GEM_USER']
72
+ password = ENV['GD_GEM_PASSWORD']
73
+ end
74
+
75
+ username = GoodData::Helpers.symbolize_keys(username) if username.is_a?(Hash)
76
+
77
+ new_opts = opts.dup
78
+ if username.is_a?(Hash) && username.key?(:sst_token)
79
+ new_opts = new_opts.merge(username)
80
+ elsif username.is_a? Hash
81
+ new_opts = new_opts.merge(username)
82
+ new_opts[:username] = username[:login] || username[:user] || username[:username]
83
+ new_opts[:password] = username[:password]
84
+ elsif username.nil? && password.nil? && opts.blank?
85
+ new_opts = Helpers::AuthHelper.read_credentials
86
+ else
87
+ new_opts[:username] = username
88
+ new_opts[:password] = password
89
+ end
90
+
91
+ new_opts = { verify_ssl: true }.merge(new_opts)
92
+ if username.is_a?(Hash) && username[:cookies]
93
+ new_opts[:sst_token] = username[:cookies]['GDCAuthSST']
94
+ new_opts[:cookies] = username[:cookies]
95
+ end
96
+
97
+ unless new_opts[:sst_token]
98
+ fail ArgumentError, 'No username specified' if new_opts[:username].nil?
99
+ fail ArgumentError, 'No password specified' if new_opts[:password].nil?
100
+ end
101
+
102
+ if username.is_a?(Hash) && username.key?(:server)
103
+ new_opts[:server] = username[:server]
104
+ end
105
+
106
+ client = Client.new(new_opts)
107
+ GoodData.logger.info("Connected to server with webdav path #{client.user_webdav_path}")
108
+
109
+ # HACK: This line assigns class instance # if not done yet
110
+ @@instance = client # rubocop:disable ClassVars
111
+ end
112
+
113
+ def connect_sso(sso)
114
+ client = Client.new(sso)
115
+ client
116
+ end
117
+
118
+ def disconnect
119
+ if @@instance # rubocop:disable Style/GuardClause
120
+ @@instance.disconnect
121
+ @@instance = nil # rubocop:disable ClassVars
122
+ end
123
+ end
124
+
125
+ def connection
126
+ @@instance
127
+ end
128
+
129
+ # Retry block if exception thrown
130
+ def retryable(options = {}, &block)
131
+ GoodData::Rest::Connection.retryable(options, &block)
132
+ end
133
+
134
+ alias_method :client, :connection
135
+ end
136
+
137
+ # Constructor of client
138
+ # @param opts [Hash] Client options
139
+ # @option opts [String] :username Username used for authentication
140
+ # @option opts [String] :password Password used for authentication
141
+ # @option opts :connection_factory Object able to create new instances of GoodData::Rest::Connection
142
+ # @option opts [GoodData::Rest::Connection] :connection Existing GoodData::Rest::Connection
143
+ def initialize(opts)
144
+ # TODO: Decide if we want to pass the options directly or not
145
+ @opts = opts
146
+
147
+ @connection_factory = @opts[:connection_factory] || DEFAULT_CONNECTION_IMPLEMENTATION
148
+
149
+ # TODO: See previous TODO
150
+ # Create connection
151
+ @connection = opts[:connection] || @connection_factory.new(opts)
152
+
153
+ # Connect
154
+ connect
155
+
156
+ # Create factory bound to previously created connection
157
+ @factory = ObjectFactory.new(self)
158
+ end
159
+
160
+ def create_project(options = { title: 'Project' })
161
+ GoodData::Project.create({ client: self }.merge(options))
162
+ end
163
+
164
+ def create_project_from_blueprint(blueprint, options = {})
165
+ GoodData::Model::ProjectCreator.migrate(options.merge(spec: blueprint, client: self))
166
+ end
167
+
168
+ def domain(domain_name)
169
+ GoodData::Domain[domain_name, :client => self]
170
+ end
171
+
172
+ def project_is_accessible?(id)
173
+ projects(id) && true
174
+ rescue
175
+ true
176
+ end
177
+
178
+ def projects(id = :all)
179
+ GoodData::Project[id, client: self]
180
+ end
181
+
182
+ def processes(id = :all)
183
+ GoodData::Process[id, client: self]
184
+ end
185
+
186
+ def connect
187
+ username = @opts[:username]
188
+ password = @opts[:password]
189
+
190
+ @connection.connect(username, password, @opts)
191
+ end
192
+
193
+ def disconnect
194
+ if stats_on?
195
+ puts "API call statistics to server #{@connection.server}"
196
+ puts @connection.stats_table
197
+ end
198
+ @connection.disconnect
199
+ end
200
+
201
+ def warehouses(id = :all)
202
+ GoodData::DataWarehouse[id, client: self]
203
+ end
204
+
205
+ def create_datawarehouse(opts = {})
206
+ GoodData::DataWarehouse.create({ client: self }.merge(opts))
207
+ end
208
+
209
+ #######################
210
+ # Factory stuff
211
+ ######################
212
+ def create(klass, data = {}, opts = {})
213
+ @factory.create(klass, data, opts)
214
+ end
215
+
216
+ def find(klass, opts = {})
217
+ @factory.find(klass, opts)
218
+ end
219
+
220
+ # Gets resource by name
221
+ def resource(res_name)
222
+ puts "Getting resource '#{res_name}'"
223
+ nil
224
+ end
225
+
226
+ def user(id = nil)
227
+ if id
228
+ create(GoodData::Profile, get(id))
229
+ else
230
+ create(GoodData::Profile, @connection.user)
231
+ end
232
+ end
233
+
234
+ def stats_off
235
+ @stats = false
236
+ end
237
+
238
+ def stats_on
239
+ @stats = true
240
+ end
241
+
242
+ def stats_on?
243
+ @stats
244
+ end
245
+
246
+ def generate_request_id
247
+ @connection.generate_request_id
248
+ end
249
+
250
+ #######################
251
+ # Rest
252
+ #######################
253
+ # HTTP DELETE
254
+ #
255
+ # @param uri [String] Target URI
256
+ def delete(uri, opts = {})
257
+ @connection.delete uri, opts
258
+ end
259
+
260
+ # HTTP GET
261
+ #
262
+ # @param uri [String] Target URI
263
+ def get(uri, opts = {}, & block)
264
+ @connection.get uri, opts, & block
265
+ end
266
+
267
+ def project_webdav_path(opts = { project: GoodData.project })
268
+ p = opts[:project]
269
+ fail ArgumentError, 'No :project specified' if p.nil?
270
+
271
+ project = GoodData::Project[p, opts]
272
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
273
+
274
+ url = project.links['uploads']
275
+ fail 'Project WebDAV not supported in this Data Center' unless url
276
+
277
+ GoodData.logger.warn 'Beware! Project webdav is deprecated and should not be used.'
278
+ url
279
+ end
280
+
281
+ def user_webdav_path
282
+ uri = if opts[:webdav_server]
283
+ opts[:webdav_server]
284
+ else
285
+ links.find { |i| i['category'] == 'uploads' }['link']
286
+ end
287
+ res = uri.chomp('/') + '/'
288
+ res[0] == '/' ? "#{connection.server}#{res}" : res
289
+ end
290
+
291
+ # Generalizaton of poller. Since we have quite a variation of how async proceses are handled
292
+ # this is a helper that should help you with resources where the information about "Are we done"
293
+ # is the http code of response. By default we repeat as long as the code == 202. You can
294
+ # change the code if necessary. It expects the URI as an input where it can poll. It returns the
295
+ # value of last poll. In majority of cases these are the data that you need.
296
+ #
297
+ # @param link [String] Link for polling
298
+ # @param options [Hash] Options
299
+ # @return [Hash] Result of polling
300
+ def poll_on_code(link, options = {})
301
+ code = options[:code] || 202
302
+ process = options[:process]
303
+
304
+ response = poll_on_response(link, options.merge(:process => false)) do |resp|
305
+ resp.code == code
306
+ end
307
+
308
+ if process == false
309
+ response
310
+ else
311
+ get(link)
312
+ end
313
+ end
314
+
315
+ # Generalizaton of poller. Since we have quite a variation of how async proceses are handled
316
+ # this is a helper that should help you with resources where the information about "Are we done"
317
+ # is inside the response. It expects the URI as an input where it can poll and a block that should
318
+ # return either true -> 'meaning we are done' or false -> meaning sleep and repeat. It returns the
319
+ # value of last poll. In majority of cases these are the data that you need
320
+ #
321
+ # @param link [String] Link for polling
322
+ # @param options [Hash] Options
323
+ # @return [Hash] Result of polling
324
+ def poll_on_response(link, options = {}, &bl)
325
+ sleep_interval = options[:sleep_interval] || DEFAULT_SLEEP_INTERVAL
326
+ time_limit = options[:time_limit] || DEFAULT_POLL_TIME_LIMIT
327
+ process = options[:process] == false ? false : true
328
+
329
+ # get the first status and start the timer
330
+ response = get(link, process: process)
331
+ poll_start = Time.now
332
+
333
+ while bl.call(response)
334
+ limit_breached = time_limit && (Time.now - poll_start > time_limit)
335
+ if limit_breached
336
+ fail ExecutionLimitExceeded, "The time limit #{time_limit} secs for polling on #{link} is over"
337
+ end
338
+ sleep sleep_interval
339
+ GoodData::Rest::Client.retryable(:tries => Helpers::GD_MAX_RETRY, :refresh_token => proc { connection.refresh_token }) do
340
+ response = get(link, process: process)
341
+ end
342
+ end
343
+ response
344
+ end
345
+
346
+ # HTTP PUT
347
+ #
348
+ # @param uri [String] Target URI
349
+ def put(uri, data, opts = {})
350
+ @connection.put uri, data, opts
351
+ end
352
+
353
+ # HTTP POST
354
+ #
355
+ # @param uri [String] Target URI
356
+ def post(uri, data, opts = {})
357
+ @connection.post uri, data, opts
358
+ end
359
+
360
+ # Uploads file to staging
361
+ #
362
+ # @param file [String] file to be uploaded
363
+ # @param options [Hash] must contain :staging_url key (file will be uploaded to :staging_url + File.basename(file))
364
+ def upload(file, options = {})
365
+ @connection.upload file, options
366
+ end
367
+
368
+ # Downloads file from staging
369
+ #
370
+ # @param source_relative_path [String] path relative to @param options[:staging_url]
371
+ # @param target_file_path [String] path to be downloaded to
372
+ # @param options [Hash] must contain :staging_url key (file will be downloaded from :staging_url + source_relative_path)
373
+ def download(source_relative_path, target_file_path, options = {})
374
+ @connection.download source_relative_path, target_file_path, options
375
+ end
376
+
377
+ def download_from_user_webdav(source_relative_path, target_file_path, options = { client: GoodData.client })
378
+ download(source_relative_path, target_file_path, options.merge(:directory => options[:directory],
379
+ :staging_url => user_webdav_path))
380
+ end
381
+
382
+ def upload_to_user_webdav(file, options = {})
383
+ upload(file, options.merge(:directory => options[:directory],
384
+ :staging_url => user_webdav_path))
385
+ end
386
+
387
+ def with_project(pid, &block)
388
+ GoodData.with_project(pid, client: self, &block)
389
+ end
390
+
391
+ def links
392
+ GoodData::Helpers.get_path(get('/gdc'), %w(about links))
393
+ end
394
+ end
395
+ end
396
+ end