gooddata 2.1.19-java → 2.3.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gdc-ii-config.yaml +42 -1
  3. data/.github/workflows/build.yml +67 -0
  4. data/.github/workflows/pre-merge.yml +72 -0
  5. data/.pronto.yml +1 -0
  6. data/.rubocop.yml +2 -14
  7. data/CHANGELOG.md +47 -0
  8. data/Dockerfile +27 -14
  9. data/Dockerfile.jruby +5 -15
  10. data/Dockerfile.ruby +5 -7
  11. data/Gemfile +4 -2
  12. data/README.md +6 -6
  13. data/Rakefile +1 -1
  14. data/SDK_VERSION +1 -1
  15. data/VERSION +1 -1
  16. data/bin/run_brick.rb +7 -0
  17. data/ci/mssql/pom.xml +62 -0
  18. data/ci/mysql/pom.xml +62 -0
  19. data/ci/redshift/pom.xml +4 -5
  20. data/docker-compose.lcm.yml +42 -4
  21. data/docker-compose.yml +42 -0
  22. data/gooddata.gemspec +21 -21
  23. data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
  24. data/lcm.rake +11 -8
  25. data/lib/gooddata/bricks/base_pipeline.rb +26 -0
  26. data/lib/gooddata/bricks/brick.rb +0 -1
  27. data/lib/gooddata/bricks/middleware/aws_middleware.rb +35 -9
  28. data/lib/gooddata/bricks/middleware/execution_result_middleware.rb +3 -3
  29. data/lib/gooddata/bricks/pipeline.rb +2 -14
  30. data/lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb +98 -0
  31. data/lib/gooddata/cloud_resources/mssql/drivers/.gitkeepme +0 -0
  32. data/lib/gooddata/cloud_resources/mssql/mssql_client.rb +122 -0
  33. data/lib/gooddata/cloud_resources/mysql/drivers/.gitkeepme +0 -0
  34. data/lib/gooddata/cloud_resources/mysql/mysql_client.rb +121 -0
  35. data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +0 -1
  36. data/lib/gooddata/cloud_resources/redshift/drivers/.gitkeepme +0 -0
  37. data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +0 -2
  38. data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +18 -1
  39. data/lib/gooddata/helpers/data_helper.rb +9 -4
  40. data/lib/gooddata/lcm/actions/base_action.rb +157 -0
  41. data/lib/gooddata/lcm/actions/collect_data_product.rb +2 -1
  42. data/lib/gooddata/lcm/actions/collect_meta.rb +3 -1
  43. data/lib/gooddata/lcm/actions/collect_projects_warning_status.rb +53 -0
  44. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +14 -0
  45. data/lib/gooddata/lcm/actions/initialize_continue_on_error_option.rb +87 -0
  46. data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +31 -4
  47. data/lib/gooddata/lcm/actions/provision_clients.rb +34 -5
  48. data/lib/gooddata/lcm/actions/synchronize_cas.rb +24 -4
  49. data/lib/gooddata/lcm/actions/synchronize_clients.rb +112 -11
  50. data/lib/gooddata/lcm/actions/synchronize_dataset_mappings.rb +89 -0
  51. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +48 -11
  52. data/lib/gooddata/lcm/actions/synchronize_kd_dashboard_permission.rb +103 -0
  53. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +79 -23
  54. data/lib/gooddata/lcm/actions/synchronize_ldm_layout.rb +98 -0
  55. data/lib/gooddata/lcm/actions/synchronize_pp_dashboard_permission.rb +108 -0
  56. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +31 -1
  57. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +26 -18
  58. data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +30 -4
  59. data/lib/gooddata/lcm/actions/synchronize_users.rb +11 -10
  60. data/lib/gooddata/lcm/actions/update_metric_formats.rb +202 -0
  61. data/lib/gooddata/lcm/data/delete_from_lcm_release.sql.erb +5 -0
  62. data/lib/gooddata/lcm/exceptions/lcm_execution_warning.rb +15 -0
  63. data/lib/gooddata/lcm/helpers/check_helper.rb +19 -0
  64. data/lib/gooddata/lcm/helpers/release_table_helper.rb +42 -8
  65. data/lib/gooddata/lcm/lcm2.rb +50 -4
  66. data/lib/gooddata/lcm/user_bricks_helper.rb +9 -0
  67. data/lib/gooddata/mixins/inspector.rb +1 -1
  68. data/lib/gooddata/mixins/md_object_query.rb +1 -0
  69. data/lib/gooddata/models/data_source.rb +5 -1
  70. data/lib/gooddata/models/dataset_mapping.rb +36 -0
  71. data/lib/gooddata/models/ldm_layout.rb +38 -0
  72. data/lib/gooddata/models/metadata/label.rb +26 -27
  73. data/lib/gooddata/models/project.rb +230 -30
  74. data/lib/gooddata/models/project_creator.rb +83 -6
  75. data/lib/gooddata/models/schedule.rb +13 -1
  76. data/lib/gooddata/models/segment.rb +2 -1
  77. data/lib/gooddata/models/user_filters/user_filter_builder.rb +162 -68
  78. data/lib/gooddata/rest/connection.rb +5 -3
  79. data/lib/gooddata/rest/phmap.rb +2 -0
  80. data/lib/gooddata.rb +1 -0
  81. data/lib/gooddata_brick_base.rb +35 -0
  82. data/sonar-project.properties +6 -0
  83. metadata +96 -65
  84. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +0 -37
  85. data/lib/gooddata/cloud_resources/redshift/drivers/log4j.properties +0 -15
data/ci/mysql/pom.xml ADDED
@@ -0,0 +1,62 @@
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-mysql-driver</artifactId>
9
+ <version>1.0-SNAPSHOT</version>
10
+
11
+ <dependencies>
12
+ <dependency>
13
+ <groupId>mysql</groupId>
14
+ <artifactId>mysql-connector-java</artifactId>
15
+ <version>5.1.49</version>
16
+ </dependency>
17
+ <dependency>
18
+ <groupId>org.mongodb</groupId>
19
+ <artifactId>mongosql-auth</artifactId>
20
+ <version>1.2.0</version>
21
+ </dependency>
22
+ <dependency>
23
+ <groupId>org.slf4j</groupId>
24
+ <artifactId>slf4j-api</artifactId>
25
+ <version>1.7.2</version>
26
+ </dependency>
27
+ </dependencies>
28
+
29
+ <profiles>
30
+ <profile>
31
+ <id>binary-packaging</id>
32
+ <build>
33
+ <plugins>
34
+ <plugin>
35
+ <artifactId>maven-dependency-plugin</artifactId>
36
+ <executions>
37
+ <execution>
38
+ <phase>package</phase>
39
+ <goals>
40
+ <goal>copy-dependencies</goal>
41
+ </goals>
42
+ <configuration>
43
+ <outputDirectory>${project.build.directory}</outputDirectory>
44
+ <!-- compile scope gives runtime and compile dependencies (skips test deps) -->
45
+ <includeScope>runtime</includeScope>
46
+ </configuration>
47
+ </execution>
48
+ </executions>
49
+ </plugin>
50
+ </plugins>
51
+ </build>
52
+ </profile>
53
+ </profiles>
54
+
55
+ <repositories>
56
+ <repository>
57
+ <id>my-repo1</id>
58
+ <name>my custom repo</name>
59
+ <url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
60
+ </repository>
61
+ </repositories>
62
+ </project>
data/ci/redshift/pom.xml CHANGED
@@ -30,10 +30,9 @@
30
30
  <version>1.11.633</version>
31
31
  </dependency>
32
32
  <dependency>
33
- <groupId>log4j</groupId>
34
- <artifactId>log4j</artifactId>
35
- <version>1.2.17</version>
36
- <scope>compile</scope>
33
+ <groupId>org.slf4j</groupId>
34
+ <artifactId>slf4j-api</artifactId>
35
+ <version>1.7.2</version>
37
36
  </dependency>
38
37
  </dependencies>
39
38
 
@@ -67,7 +66,7 @@
67
66
  <repository>
68
67
  <id>my-repo1</id>
69
68
  <name>my custom repo</name>
70
- <url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
69
+ <url>https://sonatype-nexus.intgdc.com/repository/public/</url>
71
70
  </repository>
72
71
  </repositories>
73
72
  </project>
@@ -13,9 +13,48 @@ 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
+ - S3_ACCESS_KEY
17
+ - S3_SECRET_KEY
18
+ - S3_SECRET_KEY_ESCAPED
19
+ - S3_EU_ACCESS_KEY
20
+ - S3_EU_SECRET_KEY
21
+ - S3_EU_SECRET_KEY_ESCAPED
22
+ - SNOWFLAKE_PASSWORD
23
+ - SNOWFLAKE_SECRET_KEY
24
+ - REDSHIFT_PASSWORD
25
+ - REDSHIFT_ACCESS_KEY
26
+ - REDSHIFT_SECRET_KEY
27
+ - BIGQUERY_PRIVATE_KEY
28
+ - MYSQL_INTEGRATION_TEST_PASSWORD
29
+ - MYSQL_MONGOBI_INTEGRATION_TEST_PASSWORD
30
+ - MONGO_INTEGRATION_TEST_PASSWORD
31
+ - MSSQL_INTEGRATION_TEST_PASSWORD
32
+ - POSTGRESQL_INTEGRATION_TEST_PASSWORD
33
+ - BLOB_STORAGE_CONNECTION
34
+ - RT_S3_BUCKET_NAME
35
+ - RT_S3_ACCESS_KEY
36
+ - RT_S3_SECRET_KEY
37
+ - GD_DEV_DEV_TOKEN
38
+ - GD_DEV_PROD_TOKEN
39
+ - GD_DEV_VERTICA_DEV_TOKEN
40
+ - GD_DEV_VERTICA_PROD_TOKEN
41
+ - GD_DEV_PASSWORD
42
+ - GD_DEV_GD_PROJECT_TOKEN
43
+ - GD_DEV_DEFAULT_PASSWORD
44
+ - GD_TEST_DEV_TOKEN
45
+ - GD_TEST_PROD_TOKEN
46
+ - GD_TEST_VERTICA_DEV_TOKEN
47
+ - GD_TEST_VERTICA_PROD_TOKEN
48
+ - GD_TEST_PASSWORD
49
+ - GD_TEST_GD_PROJECT_TOKEN
50
+ - GD_TEST_DEFAULT_PASSWORD
51
+ - GD_STG_DEV_TOKEN
52
+ - GD_STG_PROD_TOKEN
53
+ - GD_STG_VERTICA_DEV_TOKEN
54
+ - GD_STG_VERTICA_PROD_TOKEN
55
+ - GD_STG_PASSWORD
56
+ - GD_STG_GD_PROJECT_TOKEN
57
+ - GD_STG_DEFAULT_PASSWORD
19
58
  volumes:
20
59
  - .:/src
21
60
  volumes_from:
@@ -23,7 +62,6 @@ services:
23
62
  mem_limit: 2500m
24
63
  localstack:
25
64
  image: hahihula/localstack_dockerfile
26
- container_name: testbucket.localstack
27
65
  expose:
28
66
  - "4572"
29
67
  environment:
data/docker-compose.yml CHANGED
@@ -26,6 +26,48 @@ services:
26
26
  - GD_SPEC_PASSWORD
27
27
  - GD_ENV
28
28
  - VCR_ON
29
+ - S3_ACCESS_KEY
30
+ - S3_SECRET_KEY
31
+ - S3_SECRET_KEY_ESCAPED
32
+ - S3_EU_ACCESS_KEY
33
+ - S3_EU_SECRET_KEY
34
+ - S3_EU_SECRET_KEY_ESCAPED
35
+ - SNOWFLAKE_PASSWORD
36
+ - SNOWFLAKE_SECRET_KEY
37
+ - REDSHIFT_PASSWORD
38
+ - REDSHIFT_ACCESS_KEY
39
+ - REDSHIFT_SECRET_KEY
40
+ - BIGQUERY_PRIVATE_KEY
41
+ - MYSQL_INTEGRATION_TEST_PASSWORD
42
+ - MYSQL_MONGOBI_INTEGRATION_TEST_PASSWORD
43
+ - MONGO_INTEGRATION_TEST_PASSWORD
44
+ - MSSQL_INTEGRATION_TEST_PASSWORD
45
+ - POSTGRESQL_INTEGRATION_TEST_PASSWORD
46
+ - BLOB_STORAGE_CONNECTION
47
+ - RT_S3_BUCKET_NAME
48
+ - RT_S3_ACCESS_KEY
49
+ - RT_S3_SECRET_KEY
50
+ - GD_DEV_DEV_TOKEN
51
+ - GD_DEV_PROD_TOKEN
52
+ - GD_DEV_VERTICA_DEV_TOKEN
53
+ - GD_DEV_VERTICA_PROD_TOKEN
54
+ - GD_DEV_PASSWORD
55
+ - GD_DEV_GD_PROJECT_TOKEN
56
+ - GD_DEV_DEFAULT_PASSWORD
57
+ - GD_TEST_DEV_TOKEN
58
+ - GD_TEST_PROD_TOKEN
59
+ - GD_TEST_VERTICA_DEV_TOKEN
60
+ - GD_TEST_VERTICA_PROD_TOKEN
61
+ - GD_TEST_PASSWORD
62
+ - GD_TEST_GD_PROJECT_TOKEN
63
+ - GD_TEST_DEFAULT_PASSWORD
64
+ - GD_STG_DEV_TOKEN
65
+ - GD_STG_PROD_TOKEN
66
+ - GD_STG_VERTICA_DEV_TOKEN
67
+ - GD_STG_VERTICA_PROD_TOKEN
68
+ - GD_STG_PASSWORD
69
+ - GD_STG_GD_PROJECT_TOKEN
70
+ - GD_STG_DEFAULT_PASSWORD
29
71
  volumes:
30
72
  - /etc/passwd:/etc/passwd:ro
31
73
  - .:/src
data/gooddata.gemspec CHANGED
@@ -1,13 +1,11 @@
1
1
  # encoding: utf-8
2
2
  $LOAD_PATH.push File.expand_path('../lib/', __FILE__)
3
3
  require 'gooddata/version'
4
-
5
4
  Gem::Specification.new do |s|
6
5
  s.name = 'gooddata'
7
6
  s.version = GoodData::VERSION
8
7
  s.licenses = ['BSD-3-Clause']
9
8
  s.platform = 'java' if RUBY_PLATFORM =~ /java/
10
-
11
9
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
12
10
  s.authors = [
13
11
  'Pavel Kolesnikov',
@@ -18,27 +16,27 @@ Gem::Specification.new do |s|
18
16
  'Petr Gadorek',
19
17
  'Jakub Mahnert'
20
18
  ]
21
-
22
19
  s.summary = 'A convenient Ruby wrapper around the GoodData RESTful API'
23
20
  s.description = 'Use the GoodData::Client class to integrate GoodData into your own application or use the CLI to work with GoodData directly from the command line.'
24
21
  s.email = 'lcm@gooddata.com'
25
22
  s.extra_rdoc_files = %w(LICENSE README.md)
26
-
27
23
  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
24
  s.files.reject! { |fn| fn.start_with? 'spec/' }
29
25
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
30
-
31
26
  s.homepage = 'http://github.com/gooddata/gooddata-ruby'
32
27
  s.require_paths = ['lib']
33
-
34
28
  # s.add_development_dependency 'bundler', "~> 1.14"
35
29
  s.add_development_dependency 'license_finder', '~> 2.0'
36
- s.add_development_dependency 'rake', '~> 11.1'
30
+ s.add_development_dependency 'rake', '~> 13.0'
37
31
  s.add_development_dependency 'redcarpet', '~> 3.1' if RUBY_PLATFORM != 'java'
38
- s.add_development_dependency 'rspec', '~> 3.5.0'
39
- s.add_development_dependency 'rspec-expectations', '~> 3.5'
40
- s.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
41
- s.add_development_dependency 'rubocop', '~> 0.59.1'
32
+ s.add_development_dependency 'rspec', '~> 3.12.0'
33
+ s.add_development_dependency 'rspec-expectations', '~> 3.12'
34
+ s.add_development_dependency 'rspec_junit_formatter', '~> 0.6.0'
35
+ if RUBY_VERSION >= '2.6'
36
+ s.add_development_dependency 'rubocop', '>= 1.28'
37
+ else
38
+ s.add_development_dependency 'rubocop', '~> 0.81'
39
+ end
42
40
  s.add_development_dependency 'simplecov', '~> 0.12'
43
41
  s.add_development_dependency 'webmock', '~> 2.3.1'
44
42
  s.add_development_dependency 'yard', '~> 0.9.11'
@@ -46,16 +44,16 @@ Gem::Specification.new do |s|
46
44
  s.add_development_dependency 'pry'
47
45
  s.add_development_dependency 'pry-byebug', '~> 3.6' if RUBY_PLATFORM != 'java'
48
46
 
49
- s.add_development_dependency 'pronto', '~> 0.10' if RUBY_PLATFORM != 'java'
50
- s.add_development_dependency 'pronto-rubocop', '~> 0.9' if RUBY_PLATFORM != 'java'
51
- s.add_development_dependency 'pronto-reek', '~> 0.9' if RUBY_PLATFORM != 'java'
47
+ s.add_development_dependency 'pronto', '>= 0.10' if RUBY_PLATFORM != 'java'
48
+ s.add_development_dependency 'pronto-rubocop', '>= 0.9' if RUBY_PLATFORM != 'java'
49
+ s.add_development_dependency 'pronto-reek', '>= 0.9' if RUBY_PLATFORM != 'java'
52
50
  s.add_development_dependency 'vcr', '5.0.0'
53
51
  s.add_development_dependency 'hashdiff', '~> 0.4'
54
52
 
55
53
  s.add_development_dependency 'sqlite3' if RUBY_PLATFORM != 'java'
56
54
 
57
- if RUBY_VERSION >= '2.5'
58
- s.add_dependency 'activesupport', '>= 6.0.3.1', '< 6.2'
55
+ if RUBY_VERSION >= '2.5'
56
+ s.add_dependency 'activesupport', '< 7.0.0'
59
57
  else
60
58
  s.add_dependency 'activesupport', '>= 5.2.4.3', '< 6.0'
61
59
  end
@@ -66,18 +64,20 @@ Gem::Specification.new do |s|
66
64
  else
67
65
  s.add_dependency 'docile', '> 1.1', '< 1.4.0'
68
66
  end
67
+ s.add_dependency 'azure-storage-blob', '~> 2.0'
68
+ s.add_dependency 'nokogiri', '~> 1', '>= 1.10.8'
69
69
  s.add_dependency 'gli', '~> 2.15'
70
- s.add_dependency 'gooddata_datawarehouse', '~> 0.0.10' if RUBY_PLATFORM == 'java'
70
+ s.add_dependency 'gooddata_datawarehouse', '~> 0.0.11' if RUBY_PLATFORM == 'java'
71
71
  s.add_dependency 'highline', '= 2.0.0.pre.develop.14'
72
- s.add_dependency 'json_pure', '~> 1.8'
72
+ s.add_dependency 'json_pure', '~> 2.6'
73
73
  s.add_dependency 'multi_json', '~> 1.12'
74
74
  s.add_dependency 'parseconfig', '~> 1.0'
75
75
  s.add_dependency 'pmap', '~> 1.1'
76
+ s.add_dependency 'sequel', '< 5.72.0'
76
77
  s.add_dependency 'remote_syslog_logger', '~> 1.0.3'
77
- s.add_dependency 'restforce', '>= 2.4', '< 4.0'
78
+ s.add_dependency 'restforce', '>= 2.4'
78
79
  s.add_dependency 'rest-client', '~> 2.0'
79
- s.add_dependency 'rubyzip', '~> 1.2', '>= 1.2.1'
80
- s.add_dependency 'salesforce_bulk_query', '~> 0.2'
80
+ s.add_dependency 'rubyzip'
81
81
  s.add_dependency 'terminal-table', '~> 1.7'
82
82
  s.add_dependency 'thread_safe'
83
83
  s.add_dependency 'backports'
@@ -1,4 +1,4 @@
1
1
  apiVersion: v1
2
2
  name: lcm-bricks
3
3
  description: LCM Bricks
4
- version: 2.0.6
4
+ version: 2.0.8
data/lcm.rake CHANGED
@@ -101,14 +101,8 @@ namespace :test do
101
101
  test_cases.each do |t|
102
102
  desc "Run #{t} tests in Docker"
103
103
  task t do
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
-
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!')
112
106
  end
113
107
  end
114
108
  end
@@ -144,6 +138,15 @@ namespace :maven do
144
138
 
145
139
  system('mvn -f ci/redshift/pom.xml clean install -P binary-packaging')
146
140
  system('cp -rf ci/redshift/target/*.jar lib/gooddata/cloud_resources/redshift/drivers/')
141
+
142
+ system('mvn -f ci/postgresql/pom.xml clean install -P binary-packaging')
143
+ system('cp -rf ci/postgresql/target/*.jar lib/gooddata/cloud_resources/postgresql/drivers/')
144
+
145
+ system('mvn -f ci/mssql/pom.xml clean install -P binary-packaging')
146
+ system('cp -rf ci/mssql/target/*.jar lib/gooddata/cloud_resources/mssql/drivers/')
147
+
148
+ system('mvn -f ci/mysql/pom.xml clean install -P binary-packaging')
149
+ system('cp -rf ci/mysql/target/*.jar lib/gooddata/cloud_resources/mysql/drivers/')
147
150
  end
148
151
  end
149
152
 
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Copyright (c) 2010-2022 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
+ module GoodData
9
+ module Bricks
10
+ class BasePipeline
11
+ # Pipeline preparation code
12
+ def self.prepare(pipeline)
13
+ pipeline.reverse.reduce(nil) do |memo, app|
14
+ if memo.nil?
15
+ app.respond_to?(:new) ? app.new : app
16
+ elsif app.respond_to?(:new)
17
+ app.new(app: memo)
18
+ else
19
+ app.app = memo
20
+ app
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,7 +5,6 @@
5
5
  # LICENSE file in the root directory of this source tree.
6
6
 
7
7
  require_relative 'utils'
8
- require_relative 'middleware/middleware'
9
8
 
10
9
  module GoodData
11
10
  module Bricks
@@ -1,6 +1,6 @@
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.
6
6
 
@@ -12,21 +12,47 @@ module GoodData
12
12
  class AWSMiddleware < Bricks::Middleware
13
13
  def call(params)
14
14
  params = params.to_hash
15
- if params.key?('aws_client')
15
+ s3_config = get_s3_config(params)
16
+
17
+ unless s3_config.empty?
16
18
  GoodData.logger.info('Setting up AWS-S3 connection')
17
- raise 'Unable to connect to AWS. Parameter "aws_client" seems to be empty' unless params['aws_client']
18
- raise 'Unable to connect to AWS. Parameter "access_key_id" is missing' if params['aws_client']['access_key_id'].blank?
19
- raise 'Unable to connect to AWS. Parameter "secret_access_key" is missing' if params['aws_client']['secret_access_key'].blank?
20
- params['aws_client'] = rewrite_for_aws_sdk_v2(params['aws_client'])
21
- symbolized_config = GoodData::Helpers.symbolize_keys(params['aws_client'])
22
- s3 = Aws::S3::Resource.new(symbolized_config)
23
- params['aws_client']['s3_client'] = s3
19
+ if params.key?('aws_client')
20
+ params['s3_client'] = {}
21
+ elsif params.key?('s3_client')
22
+ params['input_source'] = {} unless params.key?('input_source')
23
+ params['input_source']['bucket'] = params['s3_client']['bucket']
24
+ end
25
+ s3_config = rewrite_for_aws_sdk_v2(s3_config)
26
+ symbolized_config = GoodData::Helpers.symbolize_keys(s3_config)
27
+ params['s3_client']['client'] = Aws::S3::Resource.new(symbolized_config)
24
28
  end
25
29
  @app.call(params)
26
30
  end
27
31
 
28
32
  private
29
33
 
34
+ def get_s3_config(params)
35
+ s3_config = {}
36
+ if params.key?('aws_client')
37
+ GoodData.logger.warn('Found two configuration aws_client and s3_client for S3 input source, use aws_client configuration') if params.key?('s3_client')
38
+ raise 'Unable to connect to AWS. Parameter "aws_client" seems to be empty' unless params['aws_client']
39
+ raise 'Unable to connect to AWS. Parameter "access_key_id" is missing' if params['aws_client']['access_key_id'].blank?
40
+ raise 'Unable to connect to AWS. Parameter "secret_access_key" is missing' if params['aws_client']['secret_access_key'].blank?
41
+
42
+ s3_config = params['aws_client']
43
+ elsif params.key?('s3_client')
44
+ raise 'Unable to connect to AWS. Parameter "s3_client" seems to be empty' unless params['s3_client']
45
+ raise 'Unable to connect to AWS. Parameter "accessKey" is missing' if params['s3_client']['accessKey'].blank?
46
+ raise 'Unable to connect to AWS. Parameter "secretKey" is missing' if params['s3_client']['secretKey'].blank?
47
+ raise 'Unable to connect to AWS. Parameter "bucket" is missing' if params['s3_client']['bucket'].blank?
48
+
49
+ s3_config['access_key_id'] = params['s3_client']['accessKey']
50
+ s3_config['secret_access_key'] = params['s3_client']['secretKey']
51
+ s3_config['region'] = params['s3_client']['region']
52
+ end
53
+ s3_config
54
+ end
55
+
30
56
  def rewrite_for_aws_sdk_v2(config)
31
57
  config['region'] = 'us-west-2' unless config['region']
32
58
  if config['use_ssl']
@@ -39,7 +39,7 @@ module GoodData
39
39
  message: message
40
40
  }
41
41
  }
42
- update_result(result)
42
+ update_result(result, status)
43
43
  end
44
44
 
45
45
  private
@@ -52,9 +52,9 @@ module GoodData
52
52
  @@result_log_path = result_log_path
53
53
  end
54
54
 
55
- def self.update_result(result)
55
+ def self.update_result(result, status = ExecutionStatus::ERROR)
56
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?
57
+ GoodData.gd_logger&.warn("action=update_execution_result status=#{status} Not found execution result logger file.")
58
58
  return
59
59
  end
60
60
 
@@ -10,23 +10,11 @@ require_relative 'release_brick'
10
10
  require_relative 'provisioning_brick'
11
11
  require_relative 'rollout_brick'
12
12
  require_relative 'hello_world_brick'
13
+ require_relative 'base_pipeline'
13
14
 
14
15
  module GoodData
15
16
  module Bricks
16
- class Pipeline
17
- # Pipeline preparation code
18
- def self.prepare(pipeline)
19
- pipeline.reverse.reduce(nil) do |memo, app|
20
- if memo.nil?
21
- app.respond_to?(:new) ? app.new : app
22
- elsif app.respond_to?(:new)
23
- app.new(app: memo)
24
- else
25
- app.app = memo
26
- app
27
- end
28
- end
29
- end
17
+ class Pipeline < GoodData::Bricks::BasePipeline
30
18
 
31
19
  def self.users_brick_pipeline
32
20
  prepare([
@@ -0,0 +1,98 @@
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 'pathname'
10
+ require "azure/storage/blob"
11
+
12
+ module GoodData
13
+ class BlobStorageClient
14
+ SAS_URL_PATTERN = %r{(^https?:\/\/[^\/]*)\/.*\?(.*)}
15
+ INVALID_BLOB_GENERAL_MESSAGE = "The connection string is not valid."
16
+ INVALID_BLOB_SIG_WELL_FORMED_MESSAGE = "The signature format is not valid."
17
+ INVALID_BLOB_CONTAINER_MESSAGE = "ContainerNotFound"
18
+ INVALID_BLOB_CONTAINER_FORMED_MESSAGE = "The container with the specified name is not found."
19
+ INVALID_BLOB_EXPIRED_ORIGINAL_MESSAGE = "Signature not valid in the specified time frame"
20
+ INVALID_BLOB_EXPIRED_MESSAGE = "The signature expired."
21
+ INVALID_BLOB_INVALID_CONNECTION_STRING_MESSAGE = "The connection string is not valid."
22
+ INVALID_BLOB_PATH_MESSAGE = "BlobNotFound"
23
+ INVALID_BLOB_INVALID_PATH_MESSAGE = "The path to the data is not found."
24
+
25
+ attr_reader :use_sas
26
+
27
+ def initialize(options = {})
28
+ raise("Data Source needs a client to Blob Storage to be able to get blob file but 'blobStorage_client' is empty.") unless options['blobStorage_client']
29
+
30
+ if options['blobStorage_client']['connectionString'] && options['blobStorage_client']['container']
31
+ @connection_string = options['blobStorage_client']['connectionString']
32
+ @container = options['blobStorage_client']['container']
33
+ @path = options['blobStorage_client']['path']
34
+ @use_sas = false
35
+ build_sas(@connection_string)
36
+ else
37
+ raise('Missing connection info for Blob Storage client')
38
+ end
39
+ end
40
+
41
+ def realize_blob(file, _params)
42
+ GoodData.gd_logger.info("Realizing download from Blob Storage. Container #{@container}.")
43
+ filename = ''
44
+ begin
45
+ connect
46
+ filename = "#{SecureRandom.urlsafe_base64(6)}_#{Time.now.to_i}.csv"
47
+ blob_name = get_blob_name(@path, file)
48
+
49
+ measure = Benchmark.measure do
50
+ _blob, content = @client.get_blob(@container, blob_name)
51
+ File.open(filename, "wb") { |f| f.write(content) }
52
+ end
53
+ rescue => e
54
+ raise_error(e)
55
+ end
56
+ GoodData.gd_logger.info("Done downloading file type=blobStorage status=finished duration=#{measure.real}")
57
+ filename
58
+ end
59
+
60
+ def connect
61
+ GoodData.logger.info "Setting up connection to Blob Storage"
62
+ if use_sas
63
+ @client = Azure::Storage::Blob::BlobService.create(:storage_blob_host => @host, :storage_sas_token => @sas_token)
64
+ else
65
+ @client = Azure::Storage::Blob::BlobService.create_from_connection_string(@connection_string)
66
+ end
67
+ end
68
+
69
+ def build_sas(url)
70
+ matches = url.scan(SAS_URL_PATTERN)
71
+ return unless matches && matches[0]
72
+
73
+ @use_sas = true
74
+ @host = matches[0][0]
75
+ @sas_token = matches[0][1]
76
+ end
77
+
78
+ def raise_error(e)
79
+ if e.message && e.message.include?(INVALID_BLOB_EXPIRED_ORIGINAL_MESSAGE)
80
+ raise INVALID_BLOB_EXPIRED_MESSAGE
81
+ elsif e.message && e.message.include?(INVALID_BLOB_SIG_WELL_FORMED_MESSAGE)
82
+ raise INVALID_BLOB_SIG_WELL_FORMED_MESSAGE
83
+ elsif e.message && e.message.include?(INVALID_BLOB_CONTAINER_MESSAGE)
84
+ raise INVALID_BLOB_CONTAINER_FORMED_MESSAGE
85
+ elsif e.message && e.message.include?(INVALID_BLOB_PATH_MESSAGE)
86
+ raise INVALID_BLOB_INVALID_PATH_MESSAGE
87
+ else
88
+ raise INVALID_BLOB_GENERAL_MESSAGE
89
+ end
90
+ end
91
+
92
+ def get_blob_name(path, file)
93
+ return file unless path
94
+
95
+ path.rindex('/') == path.length - 1 ? "#{path}#{file}" : "#{path}/#{file}"
96
+ end
97
+ end
98
+ end