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.
- checksums.yaml +4 -4
- data/.gdc-ii-config.yaml +1 -1
- data/.sonar.settings +4 -0
- data/.travis.yml +78 -12
- data/CHANGELOG.md +37 -0
- data/Dockerfile +9 -3
- data/Dockerfile.jruby +11 -1
- data/LICENSE +4418 -17
- data/LICENSE.rb +1 -1
- data/README.md +19 -1
- data/Rakefile +8 -1
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/test_projects_cleanup.rb +45 -3
- data/ci/postgresql/pom.xml +57 -0
- data/dev-gooddata-sso.pub.encrypted +40 -40
- data/docker-compose.lcm.yml +3 -0
- data/gdc_fossa_ruby_sdk.yaml +1 -0
- data/gooddata.gemspec +8 -5
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +11 -1
- data/lcm.rake +10 -4
- data/lib/gooddata.rb +2 -0
- data/lib/gooddata/cloud_resources/{cloud_resouce_factory.rb → cloud_resource_factory.rb} +8 -0
- data/lib/gooddata/cloud_resources/cloud_resources.rb +1 -1
- data/lib/gooddata/cloud_resources/postgresql/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +107 -0
- data/lib/gooddata/commands/scaffold.rb +9 -10
- data/lib/gooddata/core/nil_logger.rb +3 -1
- data/lib/gooddata/helpers/data_helper.rb +1 -2
- data/lib/gooddata/helpers/global_helpers.rb +6 -5
- data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
- data/lib/gooddata/lcm/actions/associate_clients.rb +8 -2
- data/lib/gooddata/lcm/actions/base_action.rb +0 -2
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
- data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
- data/lib/gooddata/lcm/actions/provision_clients.rb +31 -10
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +3 -1
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +4 -0
- data/lib/gooddata/lcm/actions/synchronize_users.rb +7 -6
- data/lib/gooddata/lcm/lcm2.rb +1 -2
- data/lib/gooddata/lcm/types/base_type.rb +0 -2
- data/lib/gooddata/mixins/md_object_query.rb +8 -6
- data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
- data/lib/gooddata/models/client.rb +14 -12
- data/lib/gooddata/models/data_source.rb +664 -0
- data/lib/gooddata/models/domain.rb +3 -2
- data/lib/gooddata/models/from_wire.rb +1 -0
- data/lib/gooddata/models/metadata/analytical_dashboard.rb +49 -0
- data/lib/gooddata/models/metadata/analytical_visualization_object.rb +30 -0
- data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
- data/lib/gooddata/models/metadata/visualization_object.rb +50 -0
- data/lib/gooddata/models/process.rb +11 -3
- data/lib/gooddata/models/project.rb +104 -13
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
- data/lib/gooddata/models/user_group.rb +0 -1
- data/lib/gooddata/rest/connection.rb +6 -4
- data/lib/gooddata/rest/phmap.rb +1 -1
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +20 -20
- data/DEPENDENCIES.md +0 -880
data/LICENSE.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010-
|
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
|
-
|
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.
|
1
|
+
2.1.19
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.7.
|
1
|
+
3.7.26
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
|
3
|
-
example = 'Usage example: GD_ENV=testing GD_SPEC_PASSWORD=
|
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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
+
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
1
|
+
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
|
40
|
+
N/WeNcE=
|
data/docker-compose.lcm.yml
CHANGED
data/gdc_fossa_ruby_sdk.yaml
CHANGED
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.
|
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
|
-
|
65
|
-
|
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'
|
@@ -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
|
-
|
105
|
-
|
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
@@ -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
|
|
File without changes
|
@@ -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
|