gooddata 2.1.7-java → 2.1.12-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 +3 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +2 -4
- data/CHANGELOG.md +39 -0
- data/Dockerfile +17 -4
- data/Dockerfile.jruby +4 -4
- data/Dockerfile.ruby +5 -4
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/provision.sh +2 -0
- data/bin/release.sh +2 -0
- data/bin/rollout.sh +2 -0
- data/bin/run_brick.rb +31 -7
- data/bin/test_projects_cleanup.rb +10 -2
- data/bin/user_filters.sh +2 -0
- data/ci.rake +1 -1
- data/ci/bigquery/pom.xml +54 -0
- data/ci/redshift/pom.xml +73 -0
- data/ci/snowflake/pom.xml +57 -0
- data/dev-gooddata-sso.pub.encrypted +40 -40
- data/gdc_fossa_lcm.yaml +2 -0
- data/gdc_fossa_ruby_sdk.yaml +4 -0
- data/gooddata.gemspec +7 -3
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +22 -12
- data/lcm.rake +14 -0
- data/lib/gooddata/bricks/middleware/execution_result_middleware.rb +68 -0
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +2 -1
- data/lib/gooddata/bricks/middleware/mask_logger_decorator.rb +5 -1
- data/lib/gooddata/bricks/pipeline.rb +7 -0
- data/lib/gooddata/cloud_resources/bigquery/bigquery_client.rb +86 -0
- data/lib/gooddata/cloud_resources/bigquery/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/cloud_resouce_factory.rb +28 -0
- data/lib/gooddata/cloud_resources/cloud_resource_client.rb +24 -0
- data/lib/gooddata/cloud_resources/cloud_resources.rb +12 -0
- data/lib/gooddata/cloud_resources/redshift/drivers/log4j.properties +15 -0
- data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +101 -0
- data/lib/gooddata/cloud_resources/snowflake/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +84 -0
- data/lib/gooddata/exceptions/invalid_env_error.rb +15 -0
- data/lib/gooddata/helpers/data_helper.rb +10 -0
- data/lib/gooddata/helpers/global_helpers.rb +4 -0
- data/lib/gooddata/helpers/global_helpers_params.rb +4 -7
- data/lib/gooddata/lcm/actions/collect_clients.rb +6 -6
- data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +6 -6
- data/lib/gooddata/lcm/actions/collect_segment_clients.rb +4 -1
- data/lib/gooddata/lcm/actions/collect_segments.rb +1 -2
- data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +7 -6
- data/lib/gooddata/lcm/actions/create_segment_masters.rb +5 -3
- data/lib/gooddata/lcm/actions/set_master_project.rb +76 -0
- data/lib/gooddata/lcm/actions/synchronize_clients.rb +1 -1
- data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +1 -2
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +17 -2
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +23 -3
- data/lib/gooddata/lcm/actions/synchronize_users.rb +50 -30
- data/lib/gooddata/lcm/actions/update_release_table.rb +7 -1
- data/lib/gooddata/lcm/exceptions/lcm_execution_error.rb +16 -0
- data/lib/gooddata/lcm/helpers/release_table_helper.rb +16 -8
- data/lib/gooddata/lcm/lcm2.rb +27 -5
- data/lib/gooddata/models/domain.rb +17 -15
- data/lib/gooddata/models/execution.rb +0 -1
- data/lib/gooddata/models/execution_detail.rb +0 -1
- data/lib/gooddata/models/profile.rb +33 -11
- data/lib/gooddata/models/project.rb +45 -25
- data/lib/gooddata/models/project_creator.rb +2 -0
- data/lib/gooddata/models/schedule.rb +0 -1
- data/lib/gooddata/rest/client.rb +2 -2
- data/lib/gooddata/rest/connection.rb +5 -3
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +38 -15
- data/lib/gooddata/extensions/hash.rb +0 -18
@@ -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-snowflake-driver</artifactId>
|
9
|
+
<version>1.0-SNAPSHOT</version>
|
10
|
+
|
11
|
+
<dependencies>
|
12
|
+
<dependency>
|
13
|
+
<groupId>net.snowflake</groupId>
|
14
|
+
<artifactId>snowflake-jdbc</artifactId>
|
15
|
+
<version>3.6.22</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
|
+
PHRjAjc=
|
data/gdc_fossa_lcm.yaml
ADDED
data/gooddata.gemspec
CHANGED
@@ -49,12 +49,16 @@ Gem::Specification.new do |s|
|
|
49
49
|
s.add_development_dependency 'pronto', '~> 0.10' if RUBY_PLATFORM != 'java'
|
50
50
|
s.add_development_dependency 'pronto-rubocop', '~> 0.9' if RUBY_PLATFORM != 'java'
|
51
51
|
s.add_development_dependency 'pronto-reek', '~> 0.9' if RUBY_PLATFORM != 'java'
|
52
|
-
s.add_development_dependency 'vcr'
|
52
|
+
s.add_development_dependency 'vcr', '5.0.0'
|
53
53
|
s.add_development_dependency 'hashdiff', '~> 0.4'
|
54
54
|
|
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'
|
59
|
+
else
|
60
|
+
s.add_dependency 'activesupport', '>= 5.2.4.3', '< 6.0'
|
61
|
+
end
|
58
62
|
|
59
63
|
s.add_dependency 'aws-sdk-s3', '~> 1.16'
|
60
64
|
s.add_dependency 'docile', '~> 1.1'
|
@@ -67,7 +71,7 @@ Gem::Specification.new do |s|
|
|
67
71
|
s.add_dependency 'parseconfig', '~> 1.0'
|
68
72
|
s.add_dependency 'pmap', '~> 1.1'
|
69
73
|
s.add_dependency 'remote_syslog_logger', '~> 1.0.3'
|
70
|
-
s.add_dependency 'restforce', '
|
74
|
+
s.add_dependency 'restforce', '>= 2.4', '< 4.0'
|
71
75
|
s.add_dependency 'rest-client', '~> 2.0'
|
72
76
|
s.add_dependency 'rubyzip', '~> 1.2', '>= 1.2.1'
|
73
77
|
s.add_dependency 'salesforce_bulk_query', '~> 0.2'
|
@@ -20,7 +20,7 @@ data:
|
|
20
20
|
expr: container_pod:lcm_pod_container_status_restarts:increase10m >= 1
|
21
21
|
labels:
|
22
22
|
severity: warning
|
23
|
-
team: lcm
|
23
|
+
team: lcm
|
24
24
|
cluster_id: {{ .Values.clusterId }}
|
25
25
|
annotations:
|
26
26
|
description: "There is more than 0 restarts of {{`{{ $labels.pod }}`}} pod in the last 10 minutes"
|
@@ -28,8 +28,8 @@ data:
|
|
28
28
|
- alert: "[LCM] Pod has too many restarts on cluster={{ .Values.clusterId }}"
|
29
29
|
expr: container_pod:lcm_pod_container_status_restarts:increase10m >= 2
|
30
30
|
labels:
|
31
|
-
severity:
|
32
|
-
team: lcm
|
31
|
+
severity: warning
|
32
|
+
team: lcm
|
33
33
|
cluster_id: {{ .Values.clusterId }}
|
34
34
|
annotations:
|
35
35
|
description: "There is more than 1 restart of {{`{{ $labels.pod }}`}} pod in the last 10 minutes"
|
@@ -40,7 +40,7 @@ data:
|
|
40
40
|
expr: container_pod:lcm_pod_container_status_oomkilled:increase10m >= 1
|
41
41
|
labels:
|
42
42
|
severity: warning
|
43
|
-
team: lcm
|
43
|
+
team: lcm
|
44
44
|
cluster_id: {{ .Values.clusterId }}
|
45
45
|
annotations:
|
46
46
|
description: "{{`{{ $labels.pod }}`}} was OOMKilled in the last 30 minutes. Investigate and/or increase memoryRequest or memoryLimit."
|
@@ -48,8 +48,8 @@ data:
|
|
48
48
|
- alert: "[LCM] OOMKill occured on cluster={{ .Values.clusterId }}"
|
49
49
|
expr: container_pod:lcm_pod_container_status_oomkilled:increase10m >= 2
|
50
50
|
labels:
|
51
|
-
severity:
|
52
|
-
team: lcm
|
51
|
+
severity: warning
|
52
|
+
team: lcm
|
53
53
|
cluster_id: {{ .Values.clusterId }}
|
54
54
|
annotations:
|
55
55
|
description: "{{`{{ $labels.pod }}`}} was OOMKilled in the last 10 minutes. Investigate and/or increase memoryRequest or memoryLimit."
|
@@ -58,8 +58,8 @@ data:
|
|
58
58
|
expr: rate(container_cpu_cfs_throttled_seconds_total{namespace='{{ .Release.Namespace }}'}[1m]) > 1
|
59
59
|
for: 5m
|
60
60
|
labels:
|
61
|
-
severity:
|
62
|
-
team: lcm
|
61
|
+
severity: warning
|
62
|
+
team: lcm
|
63
63
|
cluster_id: {{ .Values.clusterId }}
|
64
64
|
annotations:
|
65
65
|
description: "{{`{{ $labels.pod_name }}`}} container is beeing throttled and probably hit CPU limit. Investigate root cause and increase limit and/or number of replicas if necessary."
|
@@ -68,8 +68,8 @@ data:
|
|
68
68
|
expr: rate(jvm_gc_pause_seconds_sum{kubernetes_namespace='{{ .Release.Namespace }}'}[1m]) > 1
|
69
69
|
for: 5m
|
70
70
|
labels:
|
71
|
-
severity:
|
72
|
-
team: lcm
|
71
|
+
severity: warning
|
72
|
+
team: lcm
|
73
73
|
cluster_id: {{ .Values.clusterId }}
|
74
74
|
annotations:
|
75
75
|
description: "{{`{{ $labels.kubernetes_pod_name }}`}} container is spending too much time in pause garbage collector. Investigate root cause and increase heap size and/or number of replicas if necessary."
|
@@ -77,9 +77,19 @@ data:
|
|
77
77
|
- alert: "[LCM] there is more than 100 jobs on cluster={{ .Values.clusterId }}"
|
78
78
|
expr: count(kube_job_info{namespace="lcm"}) > 100
|
79
79
|
labels:
|
80
|
-
severity:
|
81
|
-
team: lcm
|
80
|
+
severity: warning
|
81
|
+
team: lcm
|
82
82
|
cluster_id: {{ .Values.clusterId }}
|
83
83
|
annotations:
|
84
84
|
description: "There is more than 100 jobs in LCM namespace. They are likely not deleted."
|
85
85
|
summary: "There is more than 100 jobs in LCM namespace."
|
86
|
+
- alert: "[LCM] Resource quotas hit CPU limit on cluster={{ .Values.clusterId }}"
|
87
|
+
expr: kube_resourcequota{namespace='{{ .Release.Namespace }}',resource="limits.cpu",type="hard"} - ignoring(type) kube_resourcequota{namespace='{{ .Release.Namespace }}',resource="limits.cpu",type="used"} == 0
|
88
|
+
labels:
|
89
|
+
severity: warning
|
90
|
+
team: lcm
|
91
|
+
cluster_id: {{ .Values.clusterId }}
|
92
|
+
annotations:
|
93
|
+
description: "We are hitting CPU limit in LCM namespace."
|
94
|
+
summary: "We are hitting CPU limit in LCM namespace."
|
95
|
+
|
data/lcm.rake
CHANGED
@@ -118,6 +118,7 @@ end
|
|
118
118
|
namespace :docker do
|
119
119
|
desc 'Build Docker image'
|
120
120
|
task :build do
|
121
|
+
Rake::Task["maven:build_dependencies"].invoke
|
121
122
|
system('docker build -f Dockerfile.jruby -t gooddata/appstore .')
|
122
123
|
end
|
123
124
|
|
@@ -127,6 +128,19 @@ namespace :docker do
|
|
127
128
|
end
|
128
129
|
end
|
129
130
|
|
131
|
+
namespace :maven do
|
132
|
+
task :build_dependencies do
|
133
|
+
system('mvn -f ci/snowflake/pom.xml clean install -P binary-packaging')
|
134
|
+
system('cp -rf ci/snowflake/target/*.jar lib/gooddata/cloud_resources/snowflake/drivers/')
|
135
|
+
|
136
|
+
system('mvn -f ci/bigquery/pom.xml clean install -P binary-packaging')
|
137
|
+
system('cp -rf ci/bigquery/target/*.jar lib/gooddata/cloud_resources/bigquery/drivers/')
|
138
|
+
|
139
|
+
system('mvn -f ci/redshift/pom.xml clean install -P binary-packaging')
|
140
|
+
system('cp -rf ci/redshift/target/*.jar lib/gooddata/cloud_resources/redshift/drivers/')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
130
144
|
namespace :sdk do
|
131
145
|
desc 'Updates gooddata-ruby to the version specified in the root Gemfile'
|
132
146
|
task :update do
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Copyright (c) 2019, GoodData Corporation. All rights reserved.
|
2
|
+
# This source code is licensed under the BSD-style license found in the
|
3
|
+
# LICENSE file in the root directory of this source tree.
|
4
|
+
|
5
|
+
require_relative 'base_middleware'
|
6
|
+
|
7
|
+
# rubocop:disable Style/ClassVars
|
8
|
+
module GoodData
|
9
|
+
module Bricks
|
10
|
+
module ExecutionStatus
|
11
|
+
OK = 'OK'
|
12
|
+
ERROR = 'ERROR'
|
13
|
+
WARNING = 'WARNING'
|
14
|
+
end
|
15
|
+
|
16
|
+
class ExecutionResultMiddleware < Bricks::Middleware
|
17
|
+
@@result_log_path = nil
|
18
|
+
|
19
|
+
def call(params)
|
20
|
+
result_log_path(params)
|
21
|
+
@app.call(params)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Update process execution result when the script is executed inside a GDC ETL process execution (ruby bricks).
|
25
|
+
# Ruby bricks should update execution result at the end of script with status=WARNING or OK and summary message if the script exits normally.
|
26
|
+
# If any fatal error, script should update execution result with status=ERROR and error message,
|
27
|
+
# then throw exception to notify GDC platform that the script terminated unexpectedly.
|
28
|
+
# @param [HashMap] params contains GDC_EXECUTION_RESULT_LOG_PATH or GDC_LOG_DIRECTORY, GDC_EXECUTION_ID
|
29
|
+
# @param [ExecutionStatus] status execution status
|
30
|
+
# @param [String] message execution message
|
31
|
+
def self.update_execution_result(status, message = "")
|
32
|
+
if status != ExecutionStatus::OK && status != ExecutionStatus::ERROR && status != ExecutionStatus::WARNING
|
33
|
+
GoodData.logger.warn("Unknown execution status #{status}, ignored it.")
|
34
|
+
end
|
35
|
+
|
36
|
+
result = {
|
37
|
+
executionResult: {
|
38
|
+
status: status,
|
39
|
+
message: message
|
40
|
+
}
|
41
|
+
}
|
42
|
+
update_result(result)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def result_log_path(params)
|
48
|
+
log_directory = params['GDC_LOG_DIRECTORY']
|
49
|
+
execution_id = params['GDC_EXECUTION_ID']
|
50
|
+
result_log_path = params['GDC_EXECUTION_RESULT_LOG_PATH'] || ENV['GDC_EXECUTION_RESULT_LOG_PATH']
|
51
|
+
result_log_path = "#{log_directory}/#{execution_id}_result.json" if result_log_path.nil? && !log_directory.nil?
|
52
|
+
@@result_log_path = result_log_path
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.update_result(result)
|
56
|
+
if @@result_log_path.nil?
|
57
|
+
GoodData.gd_logger.warn("action=update_execution_result status=error Not found execution result logger file.") unless GoodData.gd_logger.nil?
|
58
|
+
return
|
59
|
+
end
|
60
|
+
|
61
|
+
File.open(@@result_log_path, 'w') { |file| file.write(JSON.pretty_generate(result)) }
|
62
|
+
rescue Exception => e # rubocop:disable RescueException
|
63
|
+
GoodData.gd_logger.error("action=update_execution_result status=error reason=#{e.message}") unless GoodData.gd_logger.nil?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
# rubocop:enable Style/ClassVars
|
@@ -36,7 +36,8 @@ module GoodData
|
|
36
36
|
log_directory = params['GDC_LOG_DIRECTORY']
|
37
37
|
execution_id = params['GDC_EXECUTION_ID']
|
38
38
|
FileUtils.mkpath log_directory
|
39
|
-
|
39
|
+
execution_log_path = params['GDC_EXECUTION_LOG_PATH'].nil? ? "#{log_directory}/#{execution_id}.log" : params['GDC_EXECUTION_LOG_PATH']
|
40
|
+
logger = Logger.new(execution_log_path)
|
40
41
|
logger.level = params['GDC_LOG_LEVEL'] || 'info'
|
41
42
|
values_to_mask = params['values_to_mask'] || []
|
42
43
|
logger = MaskLoggerDecorator.new(logger, values_to_mask)
|
@@ -20,7 +20,11 @@ module GoodData
|
|
20
20
|
# @return [[String]] array of all String in values
|
21
21
|
def extract_values(values)
|
22
22
|
if values.is_a?(String)
|
23
|
-
[
|
23
|
+
if values.nil? || values.empty? || values.gsub(/[*|\s]/, '') == ''
|
24
|
+
[]
|
25
|
+
else
|
26
|
+
[values]
|
27
|
+
end
|
24
28
|
elsif values.is_a?(Hash) || values.is_a?(Array)
|
25
29
|
(values.is_a?(Hash) ? values.values : values).reduce([]) do |strings, item|
|
26
30
|
strings.concat extract_values(item)
|
@@ -32,6 +32,7 @@ module GoodData
|
|
32
32
|
prepare([
|
33
33
|
LoggerMiddleware,
|
34
34
|
DecodeParamsMiddleware,
|
35
|
+
ExecutionResultMiddleware,
|
35
36
|
BenchMiddleware,
|
36
37
|
GoodDataMiddleware,
|
37
38
|
AWSMiddleware,
|
@@ -44,6 +45,7 @@ module GoodData
|
|
44
45
|
prepare([
|
45
46
|
LoggerMiddleware,
|
46
47
|
DecodeParamsMiddleware,
|
48
|
+
ExecutionResultMiddleware,
|
47
49
|
BenchMiddleware,
|
48
50
|
GoodDataMiddleware,
|
49
51
|
AWSMiddleware,
|
@@ -56,6 +58,7 @@ module GoodData
|
|
56
58
|
def self.release_brick_pipeline
|
57
59
|
prepare([
|
58
60
|
LoggerMiddleware,
|
61
|
+
ExecutionResultMiddleware,
|
59
62
|
DecodeParamsMiddleware,
|
60
63
|
BenchMiddleware,
|
61
64
|
GoodDataMiddleware,
|
@@ -68,6 +71,7 @@ module GoodData
|
|
68
71
|
def self.provisioning_brick_pipeline
|
69
72
|
prepare([
|
70
73
|
LoggerMiddleware,
|
74
|
+
ExecutionResultMiddleware,
|
71
75
|
DecodeParamsMiddleware,
|
72
76
|
BenchMiddleware,
|
73
77
|
GoodDataMiddleware,
|
@@ -80,6 +84,7 @@ module GoodData
|
|
80
84
|
def self.rollout_brick_pipeline
|
81
85
|
prepare([
|
82
86
|
LoggerMiddleware,
|
87
|
+
ExecutionResultMiddleware,
|
83
88
|
DecodeParamsMiddleware,
|
84
89
|
BenchMiddleware,
|
85
90
|
GoodDataMiddleware,
|
@@ -93,6 +98,7 @@ module GoodData
|
|
93
98
|
prepare(
|
94
99
|
[
|
95
100
|
LoggerMiddleware,
|
101
|
+
ExecutionResultMiddleware,
|
96
102
|
DecodeParamsMiddleware,
|
97
103
|
BenchMiddleware,
|
98
104
|
HelloWorldBrick
|
@@ -104,6 +110,7 @@ module GoodData
|
|
104
110
|
prepare(
|
105
111
|
[
|
106
112
|
LoggerMiddleware,
|
113
|
+
ExecutionResultMiddleware,
|
107
114
|
DecodeParamsMiddleware,
|
108
115
|
BenchMiddleware,
|
109
116
|
HelpBrick
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# Copyright (c) 2010-2019 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-bigquery-driver')
|
16
|
+
end
|
17
|
+
|
18
|
+
java_import 'com.google.auth.oauth2.ServiceAccountCredentials'
|
19
|
+
java_import 'com.google.cloud.bigquery.BigQuery'
|
20
|
+
java_import 'com.google.cloud.bigquery.BigQueryOptions'
|
21
|
+
java_import 'com.google.cloud.bigquery.FieldList'
|
22
|
+
java_import 'com.google.cloud.bigquery.FieldValue'
|
23
|
+
java_import 'com.google.cloud.bigquery.FieldValueList'
|
24
|
+
java_import 'com.google.cloud.bigquery.QueryJobConfiguration'
|
25
|
+
java_import 'com.google.cloud.bigquery.TableResult'
|
26
|
+
java_import 'org.apache.commons.text.StringEscapeUtils'
|
27
|
+
|
28
|
+
module GoodData
|
29
|
+
module CloudResources
|
30
|
+
class BigQueryClient < CloudResourceClient
|
31
|
+
class << self
|
32
|
+
def accept?(type)
|
33
|
+
type == 'bigquery'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(options = {})
|
38
|
+
raise("Data Source needs a client to BigQuery to be able to query the storage but 'bigquery_client' is empty.") unless options['bigquery_client']
|
39
|
+
|
40
|
+
if options['bigquery_client']['connection'].is_a?(Hash)
|
41
|
+
@project = options['bigquery_client']['connection']['project']
|
42
|
+
@schema = options['bigquery_client']['connection']['schema'] || 'public'
|
43
|
+
@authentication = options['bigquery_client']['connection']['authentication']
|
44
|
+
else
|
45
|
+
raise('Missing connection info for BigQuery client')
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def realize_query(query, _params)
|
51
|
+
GoodData.gd_logger.info("Realize SQL query: type=bigquery status=started")
|
52
|
+
|
53
|
+
client = create_client
|
54
|
+
filename = "#{SecureRandom.urlsafe_base64(6)}_#{Time.now.to_i}.csv"
|
55
|
+
measure = Benchmark.measure do
|
56
|
+
query_config = QueryJobConfiguration.newBuilder(query).setDefaultDataset(@schema).build
|
57
|
+
table_result = client.query(query_config)
|
58
|
+
|
59
|
+
if table_result.getTotalRows.positive?
|
60
|
+
result = table_result.iterateAll
|
61
|
+
field_list = table_result.getSchema.getFields
|
62
|
+
col_count = field_list.size
|
63
|
+
CSV.open(filename, 'wb') do |csv|
|
64
|
+
csv << Array(1..col_count).map { |i| field_list.get(i - 1).getName } # build the header
|
65
|
+
result.each do |row|
|
66
|
+
csv << Array(1..col_count).map { |i| row.get(i - 1).getValue&.to_s }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
GoodData.gd_logger.info("Realize SQL query: type=bigquery status=finished duration=#{measure.real}")
|
72
|
+
filename
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def create_client
|
78
|
+
GoodData.logger.info "Setting up connection to BigQuery"
|
79
|
+
client_email = @authentication['serviceAccount']['clientEmail']
|
80
|
+
private_key = @authentication['serviceAccount']['privateKey']
|
81
|
+
credentials = ServiceAccountCredentials.fromPkcs8(nil, client_email, StringEscapeUtils.unescapeJson(private_key), nil, nil)
|
82
|
+
BigQueryOptions.newBuilder.setProjectId(@project).setCredentials(credentials).build.getService
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|