gooddata 2.1.12-java → 2.1.19-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gdc-ii-config.yaml +1 -1
  3. data/.sonar.settings +4 -0
  4. data/.travis.yml +78 -12
  5. data/CHANGELOG.md +37 -0
  6. data/Dockerfile +9 -3
  7. data/Dockerfile.jruby +11 -1
  8. data/LICENSE +4418 -17
  9. data/LICENSE.rb +1 -1
  10. data/README.md +19 -1
  11. data/Rakefile +8 -1
  12. data/SDK_VERSION +1 -1
  13. data/VERSION +1 -1
  14. data/bin/test_projects_cleanup.rb +45 -3
  15. data/ci/postgresql/pom.xml +57 -0
  16. data/dev-gooddata-sso.pub.encrypted +40 -40
  17. data/docker-compose.lcm.yml +3 -0
  18. data/gdc_fossa_ruby_sdk.yaml +1 -0
  19. data/gooddata.gemspec +8 -5
  20. data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
  21. data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +11 -1
  22. data/lcm.rake +10 -4
  23. data/lib/gooddata.rb +2 -0
  24. data/lib/gooddata/cloud_resources/{cloud_resouce_factory.rb → cloud_resource_factory.rb} +8 -0
  25. data/lib/gooddata/cloud_resources/cloud_resources.rb +1 -1
  26. data/lib/gooddata/cloud_resources/postgresql/drivers/.gitkeepme +0 -0
  27. data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +107 -0
  28. data/lib/gooddata/commands/scaffold.rb +9 -10
  29. data/lib/gooddata/core/nil_logger.rb +3 -1
  30. data/lib/gooddata/helpers/data_helper.rb +1 -2
  31. data/lib/gooddata/helpers/global_helpers.rb +6 -5
  32. data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
  33. data/lib/gooddata/lcm/actions/associate_clients.rb +8 -2
  34. data/lib/gooddata/lcm/actions/base_action.rb +0 -2
  35. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
  36. data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
  37. data/lib/gooddata/lcm/actions/provision_clients.rb +31 -10
  38. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +3 -1
  39. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +4 -0
  40. data/lib/gooddata/lcm/actions/synchronize_users.rb +7 -6
  41. data/lib/gooddata/lcm/lcm2.rb +1 -2
  42. data/lib/gooddata/lcm/types/base_type.rb +0 -2
  43. data/lib/gooddata/mixins/md_object_query.rb +8 -6
  44. data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
  45. data/lib/gooddata/models/client.rb +14 -12
  46. data/lib/gooddata/models/data_source.rb +664 -0
  47. data/lib/gooddata/models/domain.rb +3 -2
  48. data/lib/gooddata/models/from_wire.rb +1 -0
  49. data/lib/gooddata/models/metadata/analytical_dashboard.rb +49 -0
  50. data/lib/gooddata/models/metadata/analytical_visualization_object.rb +30 -0
  51. data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
  52. data/lib/gooddata/models/metadata/visualization_object.rb +50 -0
  53. data/lib/gooddata/models/process.rb +11 -3
  54. data/lib/gooddata/models/project.rb +104 -13
  55. data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
  56. data/lib/gooddata/models/user_group.rb +0 -1
  57. data/lib/gooddata/rest/connection.rb +6 -4
  58. data/lib/gooddata/rest/phmap.rb +1 -1
  59. data/rubydev_public.gpg.encrypted +51 -51
  60. data/rubydev_secret_keys.gpg.encrypted +109 -109
  61. metadata +20 -20
  62. data/DEPENDENCIES.md +0 -880
data/LICENSE.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
3
+ # Copyright (c) 2010-2021 GoodData Corporation. All rights reserved.
4
4
  # This source code is licensed under the BSD-style license found in the
5
5
  # LICENSE file in the root directory of this source tree.
data/README.md CHANGED
@@ -9,6 +9,8 @@ The best documentation for the GoodData API can be found using these resources:
9
9
  * http://developer.gooddata.com/api
10
10
  * https://secure.gooddata.com/gdc
11
11
  * http://rubydoc.info/gems/gooddata/frames
12
+
13
+ Feel free to check out the [GoodData community website](http://community.gooddata.com/) if you have any questions about the GoodData Analytics platform, our API, or this library.
12
14
 
13
15
  ## Status
14
16
 
@@ -19,6 +21,21 @@ The best documentation for the GoodData API can be found using these resources:
19
21
  [![Build Status](https://travis-ci.org/gooddata/gooddata-ruby.png)](https://travis-ci.org/gooddata/gooddata-ruby)
20
22
  [![Coverage Status](https://coveralls.io/repos/gooddata/gooddata-ruby/badge.png)](https://coveralls.io/r/gooddata/gooddata-ruby)
21
23
 
24
+ ## Supported versions
25
+
26
+ In order to make the user experience with integrating GoodData Ruby SDK as smooth and secure as possible and to ensure that the SDK is using the latest features of the platform, we only provide support to the two most recent major versions of Ruby SDK.
27
+
28
+ The most recent majors will be supported in the following modes:
29
+
30
+ - The latest major version will receive all new functionality and all bug fixes.
31
+ - The previous major version will only receive fixes to critical issues and security fixes. These fixes will be applied on top of last released version of the previous major.
32
+ - GoodData customer support will provide support for the latest major and previous major version only.
33
+
34
+ - The customers are encouraged to always use the latest version of the Ruby SDK.
35
+ - In case of using older versions, the user might face API incompatibility, performance or security issues.
36
+
37
+ Please follow the installation instructions in the repository to update to the newest version.
38
+
22
39
  ## Install
23
40
 
24
41
  If you are using bundler, add
@@ -78,4 +95,5 @@ For full contributor info see [contributors page](https://github.com/gooddata/go
78
95
 
79
96
  ## Copyright
80
97
 
81
- Copyright (c) 2010 - 2018 GoodData Corporation and Thomas Watson Steen. See [LICENSE](/LICENSE) for details.
98
+ (c) 2010-2021 GoodData Corporation
99
+ This repository is governed by the terms and conditions in the LICENSE. This repository contains a number of open source packages detailed in NOTICES, including the GoodData Ruby SDK, which is licensed under the BSD-3-Clause license and contains additional open source components detailed in the file called LICENSE_FOR_RUBY_SDK_COMPONENT.
data/Rakefile CHANGED
@@ -33,7 +33,14 @@ namespace :gem do
33
33
  desc "Release gem version #{GoodData::VERSION} to rubygems"
34
34
  task :release do
35
35
  gem = "gooddata-#{GoodData::VERSION}.gem"
36
-
36
+ origin_license_file = 'LICENSE'
37
+ new_license_file = 'LICENSE_FOR_RUBY_SDK_COMPONENT.txt'
38
+ notices_file = 'NOTICES.txt'
39
+ File.delete(origin_license_file) if File.exist?(origin_license_file)
40
+ File.delete(notices_file) if File.exist?(notices_file)
41
+ puts "Deleted files: #{origin_license_file} and #{notices_file}"
42
+ File.rename(new_license_file, origin_license_file) if File.exists?(new_license_file)
43
+ puts "Renamed file #{new_license_file} to #{origin_license_file}"
37
44
  puts "Building #{gem} ..."
38
45
  res = `gem build ./gooddata.gemspec`
39
46
  file = res.match('File: (.*)')[1]
data/SDK_VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.12
1
+ 2.1.19
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.7.20
1
+ 3.7.26
@@ -1,6 +1,6 @@
1
1
  require 'optparse'
2
2
 
3
- example = 'Usage example: GD_ENV=testing GD_SPEC_PASSWORD=secret bundle exec ruby bin/test_projects_cleanup.rb'
3
+ example = 'Usage example: GD_ENV=testing GD_SPEC_PASSWORD= bundle exec ruby bin/test_projects_cleanup.rb'
4
4
 
5
5
  options = {}
6
6
  OptionParser.new do |opts|
@@ -22,6 +22,39 @@ require_relative '../spec/environment/environment'
22
22
  GoodData::Environment.load
23
23
  config = GoodData::Environment::ConnectionHelper::LCM_ENVIRONMENT
24
24
  secrets = GoodData::Environment::ConnectionHelper::SECRETS
25
+ default_domain = GoodData::Environment::ConnectionHelper::DEFAULT_DOMAIN
26
+
27
+ def delete_segment_by_title(title, segments, days = 14, force = false)
28
+ return if segments.empty?
29
+ dead_line = Time.now - days * 60 * 60 * 24
30
+
31
+ filtered_segments = segments.select do |s|
32
+ if s.id.match(title) && s.id.length > 14 && s.id[s.id.length-14..-1]
33
+ segment_created = s.id[s.id.length-14..-1]
34
+ created = Time.parse(segment_created) if segment_created
35
+
36
+ s if created.year >= Time.new.year && created < dead_line
37
+ end
38
+ end
39
+
40
+ filtered_segments.each do |segment|
41
+ begin
42
+ if force
43
+ segment.clients.each do |segment_client|
44
+ GoodData.logger.info("Deleting segment: #{segment.id} - client: #{segment_client.client_id}")
45
+ segment_client.dissociate
46
+ end
47
+
48
+ puts "Deleting segment: #{segment.id}"
49
+ segment && segment.delete(force: true)
50
+ else
51
+ puts "Would delete segment: #{segment.id}"
52
+ end
53
+ rescue RuntimeError, StandardError => ex
54
+ puts "Failed to delete segment #{segment.id}, reason: #{ex}"
55
+ end
56
+ end
57
+ end
25
58
 
26
59
  def delete_project_by_title(title, projects, days = 14, force = false)
27
60
  dead_line = Time.now - days * 60 * 60 * 24
@@ -73,8 +106,16 @@ def delete_ads_by_title(title, client, days = 14, force = false)
73
106
  puts "#{deleted} ADS instances with title \"#{title}\" #{'would be ' unless force}deleted."
74
107
  end
75
108
 
76
- def clean_up!(client, force, days)
109
+ def clean_up!(client, force, days, opts = {})
77
110
  projects = client.projects
111
+
112
+ if opts[:domain_id]
113
+ domain = client.domain(opts[:domain_id])
114
+
115
+ # segments id format: {title}_{hostname}_{datetime}
116
+ delete_segment_by_title(/CAR_DEMO_PREMIUM/, domain.segments, days, force)
117
+ end
118
+
78
119
  delete_project_by_title(/Insurance Demo Master/, projects, days, force)
79
120
  delete_project_by_title(/Car Demo Master/, projects, days, force)
80
121
  delete_project_by_title(/Insurance Demo Workspace/, projects, days, force)
@@ -117,7 +158,8 @@ prod_client = init_client(username, password, "https://#{config[:prod_server]}")
117
158
 
118
159
  force = options[:force]
119
160
  days = options[:days] || 3
161
+
120
162
  clean_up!(dev_client, force, days)
121
- clean_up!(prod_client, force, days)
163
+ clean_up!(prod_client, force, days, {domain_id: default_domain})
122
164
 
123
165
  dev_client.disconnect
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
+ <modelVersion>4.0.0</modelVersion>
6
+
7
+ <groupId>com.gooddata.lcm</groupId>
8
+ <artifactId>lcm-postgresql-driver</artifactId>
9
+ <version>1.0-SNAPSHOT</version>
10
+
11
+ <dependencies>
12
+ <dependency>
13
+ <groupId>org.postgresql</groupId>
14
+ <artifactId>postgresql</artifactId>
15
+ <version>42.2.19</version>
16
+ </dependency>
17
+ <dependency>
18
+ <groupId>org.slf4j</groupId>
19
+ <artifactId>slf4j-api</artifactId>
20
+ <version>1.7.2</version>
21
+ </dependency>
22
+ </dependencies>
23
+
24
+ <profiles>
25
+ <profile>
26
+ <id>binary-packaging</id>
27
+ <build>
28
+ <plugins>
29
+ <plugin>
30
+ <artifactId>maven-dependency-plugin</artifactId>
31
+ <executions>
32
+ <execution>
33
+ <phase>package</phase>
34
+ <goals>
35
+ <goal>copy-dependencies</goal>
36
+ </goals>
37
+ <configuration>
38
+ <outputDirectory>${project.build.directory}</outputDirectory>
39
+ <!-- compile scope gives runtime and compile dependencies (skips test deps) -->
40
+ <includeScope>runtime</includeScope>
41
+ </configuration>
42
+ </execution>
43
+ </executions>
44
+ </plugin>
45
+ </plugins>
46
+ </build>
47
+ </profile>
48
+ </profiles>
49
+
50
+ <repositories>
51
+ <repository>
52
+ <id>my-repo1</id>
53
+ <name>my custom repo</name>
54
+ <url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
55
+ </repository>
56
+ </repositories>
57
+ </project>
@@ -1,40 +1,40 @@
1
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- NHuYZ7JPZLCmRVRjPa1ivd7h0CfkwJpKn2bUHusgXNgmKRWoAUaQ3piGRNqa
17
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- +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
- 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
- iNP04r4XV2oq1j8pAp6KZQU/j0q17HXWFBopGyGjE18cPpo4bR3NxChodFKe
32
- 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
- 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
- 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
- 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
- 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
- ALonjlg+GgzuFtodh6qe/Qx1zjNGLHaT1T/02hWl4ERYSMxkoGPLC7dPjLdc
38
- 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
- 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
40
- PHRjAjc=
1
+ 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
40
+ N/WeNcE=
@@ -13,6 +13,9 @@ services:
13
13
  - JRUBY_OPTS=-J-Xmx1g
14
14
  - GD_SPEC_PASSWORD
15
15
  - VCR_ON
16
+ - POSTGRES_DB=gooddata
17
+ - POSTGRES_USER=gooddata
18
+ - POSTGRES_PASSWORD=changeit
16
19
  volumes:
17
20
  - .:/src
18
21
  volumes_from:
@@ -1,4 +1,5 @@
1
1
  ---
2
+ generate_attribution_file: true
2
3
  fossa_project: "gooddata-ruby-sdk"
3
4
  ignored_paths:
4
5
  - 'ci/.*'
data/gooddata.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'gooddata/version'
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'gooddata'
7
7
  s.version = GoodData::VERSION
8
- s.licenses = ['BSD']
8
+ s.licenses = ['BSD-3-Clause']
9
9
  s.platform = 'java' if RUBY_PLATFORM =~ /java/
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.email = 'lcm@gooddata.com'
25
25
  s.extra_rdoc_files = %w(LICENSE README.md)
26
26
 
27
- s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
27
+ s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR).map { |f| f unless %w(NOTICES.txt LICENSE_FOR_RUBY_SDK_COMPONENT.txt).include?(f) }
28
28
  s.files.reject! { |fn| fn.start_with? 'spec/' }
29
29
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
30
30
 
@@ -55,14 +55,17 @@ Gem::Specification.new do |s|
55
55
  s.add_development_dependency 'sqlite3' if RUBY_PLATFORM != 'java'
56
56
 
57
57
  if RUBY_VERSION >= '2.5'
58
- s.add_dependency 'activesupport', '>= 6.0.3.1', '< 6.1'
58
+ s.add_dependency 'activesupport', '>= 6.0.3.1', '< 6.2'
59
59
  else
60
60
  s.add_dependency 'activesupport', '>= 5.2.4.3', '< 6.0'
61
61
  end
62
62
 
63
63
  s.add_dependency 'aws-sdk-s3', '~> 1.16'
64
- s.add_dependency 'docile', '~> 1.1'
65
- s.add_dependency 'erubis', '~> 2.7'
64
+ if RUBY_VERSION >= '2.5'
65
+ s.add_dependency 'docile', '~> 1.1'
66
+ else
67
+ s.add_dependency 'docile', '> 1.1', '< 1.4.0'
68
+ end
66
69
  s.add_dependency 'gli', '~> 2.15'
67
70
  s.add_dependency 'gooddata_datawarehouse', '~> 0.0.10' if RUBY_PLATFORM == 'java'
68
71
  s.add_dependency 'highline', '= 2.0.0.pre.develop.14'
@@ -1,4 +1,4 @@
1
1
  apiVersion: v1
2
2
  name: lcm-bricks
3
3
  description: LCM Bricks
4
- version: 2.0.3
4
+ version: 2.0.6
@@ -92,4 +92,14 @@ data:
92
92
  annotations:
93
93
  description: "We are hitting CPU limit in LCM namespace."
94
94
  summary: "We are hitting CPU limit in LCM namespace."
95
-
95
+ - alert: "[LCM] POD is in undesirable state on cluster={{ .Values.clusterId }}"
96
+ expr: kube_pod_status_phase{namespace='{{ .Release.Namespace }}', phase!~"Running|Succeeded|Failed"} > 0
97
+ for: 5m
98
+ labels:
99
+ cluster_id: {{ .Values.clusterId }}
100
+ severity: critical
101
+ team: lcm
102
+ annotations:
103
+ description: "POD {{`{{ $labels.pod }}`}} is not in desirable state"
104
+ summary: "POD is not in desirable state"
105
+ runbook: "https://confluence.intgdc.com/display/plat/Generic+runbooks#Genericrunbooks-Podisinundesirablestate"
data/lcm.rake CHANGED
@@ -3,7 +3,7 @@ require 'fileutils'
3
3
  require 'pathname'
4
4
  require 'rspec/core/rake_task'
5
5
 
6
- test_cases = %i[integration slow userprov load]
6
+ test_cases = %i[integration-e2e integration-release integration-others slow userprov load]
7
7
 
8
8
  # Schema for new Bricks.
9
9
  brick_info_schema = {
@@ -79,7 +79,7 @@ namespace :test do
79
79
  test_cases.each do |test_case|
80
80
  desc "Run #{test_case} tests"
81
81
  RSpec::Core::RakeTask.new(test_case) do |task|
82
- task.pattern = "spec/lcm/#{test_case}/**/*_spec.rb"
82
+ task.pattern = test_case['integration'] ? "spec/lcm/integration/spec/#{test_case.to_s.split('-')[-1]}/*_spec.rb" : "spec/lcm/#{test_case}/**/*_spec.rb"
83
83
  end
84
84
  end
85
85
 
@@ -101,8 +101,14 @@ namespace :test do
101
101
  test_cases.each do |t|
102
102
  desc "Run #{t} tests in Docker"
103
103
  task t do
104
- system("docker-compose -f docker-compose.lcm.yml run --rm appstore bundle exec rake -f lcm.rake test:#{t}") ||
105
- fail('Test execution failed!')
104
+ if t.to_s == 'integration'
105
+ system("docker-compose -f docker-compose.lcm.yml run --rm appstore /bin/bash -c ./spec/integration_with_postgresql.sh") ||
106
+ fail('Test execution failed!')
107
+ else
108
+ system("docker-compose -f docker-compose.lcm.yml run --rm appstore bundle exec rake -f lcm.rake test:#{t}") ||
109
+ fail('Test execution failed!')
110
+ end
111
+
106
112
  end
107
113
  end
108
114
  end
data/lib/gooddata.rb CHANGED
@@ -37,3 +37,5 @@ require 'backports/2.1.0/array/to_h'
37
37
 
38
38
  # Helpers
39
39
  require 'gooddata/helpers/global_helpers'
40
+
41
+ require 'active_support/core_ext/hash/compact' unless RUBY_VERSION >= '2.5'
@@ -11,7 +11,15 @@ module GoodData
11
11
  module CloudResources
12
12
  class CloudResourceFactory
13
13
  class << self
14
+ def load_cloud_resource(type)
15
+ base = "#{Pathname(__FILE__).dirname.expand_path}#{File::SEPARATOR}#{type}#{File::SEPARATOR}"
16
+ Dir.glob(base + '**/*.rb').each do |file|
17
+ require file
18
+ end
19
+ end
20
+
14
21
  def create(type, data = {}, opts = {})
22
+ load_cloud_resource(type)
15
23
  clients = CloudResourceClient.descendants.select { |c| c.respond_to?("accept?") && c.send("accept?", type) }
16
24
  raise "DataSource does not support type \"#{type}\"" if clients.empty?
17
25
 
@@ -7,6 +7,6 @@
7
7
  require 'pathname'
8
8
 
9
9
  base = Pathname(__FILE__).dirname.expand_path
10
- Dir.glob(base + '**/*.rb').each do |file|
10
+ Dir.glob(base + '*.rb').each do |file|
11
11
  require file
12
12
  end
@@ -0,0 +1,107 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Copyright (c) 2021 GoodData Corporation. All rights reserved.
5
+ # This source code is licensed under the BSD-style license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+
8
+ require 'securerandom'
9
+ require 'java'
10
+ require 'pathname'
11
+ require_relative '../cloud_resource_client'
12
+
13
+ base = Pathname(__FILE__).dirname.expand_path
14
+ Dir.glob(base + 'drivers/*.jar').each do |file|
15
+ require file unless file.start_with?('lcm-postgresql-driver')
16
+ end
17
+
18
+ module GoodData
19
+ module CloudResources
20
+ class PostgresClient < CloudResourceClient
21
+ JDBC_POSTGRES_PATTERN = %r{jdbc:postgresql:\/\/([^:^\/]+)(:([0-9]+))?(\/)?}
22
+ POSTGRES_DEFAULT_PORT = 5432
23
+ JDBC_POSTGRES_PROTOCOL = 'jdbc:postgresql://'
24
+ SSL_JAVA_FACTORY = '&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory'
25
+ VERIFY_FULL = 'verify-full'
26
+ PREFER = 'prefer'
27
+ REQUIRE = 'require'
28
+ POSTGRES_SET_SCHEMA_COMMAND = "set search_path to"
29
+ POSTGRES_FETCH_SIZE = 1000
30
+
31
+ class << self
32
+ def accept?(type)
33
+ type == 'postgresql'
34
+ end
35
+ end
36
+
37
+ def initialize(options = {})
38
+ raise("Data Source needs a client to Postgres to be able to query the storage but 'postgresql_client' is empty.") unless options['postgresql_client']
39
+
40
+ if options['postgresql_client']['connection'].is_a?(Hash)
41
+ @database = options['postgresql_client']['connection']['database']
42
+ @schema = options['postgresql_client']['connection']['schema'] || 'public'
43
+ @authentication = options['postgresql_client']['connection']['authentication']
44
+ @ssl_mode = options['postgresql_client']['connection']['sslMode']
45
+ raise "SSL Mode should be prefer, require and verify-full" unless @ssl_mode == 'prefer' || @ssl_mode == 'require' || @ssl_mode == 'verify-full'
46
+
47
+ @url = build_url(options['postgresql_client']['connection']['url'])
48
+ else
49
+ raise('Missing connection info for Postgres client')
50
+ end
51
+
52
+ Java.org.postgresql.Driver
53
+ end
54
+
55
+ def realize_query(query, _params)
56
+ GoodData.gd_logger.info("Realize SQL query: type=postgresql status=started")
57
+
58
+ connect
59
+ filename = "#{SecureRandom.urlsafe_base64(6)}_#{Time.now.to_i}.csv"
60
+ measure = Benchmark.measure do
61
+ statement = @connection.create_statement
62
+ statement.set_fetch_size(POSTGRES_FETCH_SIZE)
63
+ has_result = statement.execute(query)
64
+ if has_result
65
+ result = statement.get_result_set
66
+ metadata = result.get_meta_data
67
+ col_count = metadata.column_count
68
+ CSV.open(filename, 'wb') do |csv|
69
+ csv << Array(1..col_count).map { |i| metadata.get_column_name(i) } # build the header
70
+ csv << Array(1..col_count).map { |i| result.get_string(i)&.to_s } while result.next
71
+ end
72
+ end
73
+ end
74
+ GoodData.gd_logger.info("Realize SQL query: type=postgresql status=finished duration=#{measure.real}")
75
+ filename
76
+ ensure
77
+ @connection&.close
78
+ @connection = nil
79
+ end
80
+
81
+ def connect
82
+ GoodData.logger.info "Setting up connection to Postgresql #{@url}"
83
+
84
+ prop = java.util.Properties.new
85
+ prop.setProperty('user', @authentication['basic']['userName'])
86
+ prop.setProperty('password', @authentication['basic']['password'])
87
+ prop.setProperty('schema', @schema)
88
+
89
+ @connection = java.sql.DriverManager.getConnection(@url, prop)
90
+ statement = @connection.create_statement
91
+ statement.execute("#{POSTGRES_SET_SCHEMA_COMMAND} #{@schema}")
92
+ @connection.set_auto_commit(false)
93
+ end
94
+
95
+ def build_url(url)
96
+ matches = url.scan(JDBC_POSTGRES_PATTERN)
97
+ raise 'Cannot reach the url' unless matches
98
+
99
+ host = matches[0][0]
100
+ port = matches[0][2]&.to_i || POSTGRES_DEFAULT_PORT
101
+ raise "Custom port #{port} is not supported. Remove it or use the default port '5432'" if POSTGRES_DEFAULT_PORT != port
102
+
103
+ "#{JDBC_POSTGRES_PROTOCOL}#{host}:#{port}/#{@database}?sslmode=#{@ssl_mode}#{VERIFY_FULL == @ssl_mode ? SSL_JAVA_FACTORY : ''}"
104
+ end
105
+ end
106
+ end
107
+ end