multiwoven-integrations 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70c20cbce32a5325dde37e8cb8e1930905d3d9003300d9d552db1f50f63817b0
4
- data.tar.gz: 54e03d9a4dd254d20fbee73ca9479b849beab979b5d9f7b76a708c34fa4881cb
3
+ metadata.gz: 4383545bc6859b88187d4e38e70be9166e792cadf23b44ac22437202c836db9b
4
+ data.tar.gz: febd77085d1f369c6444275fb6a2079a2c2c25abdd8671587c1e93e4512663e7
5
5
  SHA512:
6
- metadata.gz: f13156eac84b28e95904d9e32025f3e9943da758cfb14d69561ba1d69b40fd25c4eb9f1d97e91d34013eddf723d17ac579a35ab713a7272a6da78fa10d56c298
7
- data.tar.gz: 35345fcd1d52d6237be64829092611ae69c629c13ca8964f38de7cf0fd4e133914c54265f87d3c9259dbf5948aa67ea4b017e31be5e2faecec3cd85d56493552
6
+ metadata.gz: feb86afd8c6817e3fb67f8f7f525a6db44fe4325ac69b1fdda1e72dc27e4ab7d7f6e5a6415481c7a1bfc31c794590e63a8d73cef2e2efe157bd0e94f92d86a66
7
+ data.tar.gz: 36f2532bf27e28434ddd1c639ed3ba2ef64ace163de40f7030763d58f1c28fda947b312ed563b50d5dbfa10ab3828cbc2c7173f15cbd7a28c4918f634d1f8740
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven
4
+ module Integrations
5
+ module Destination
6
+ module DatabricksLakehouse
7
+ include Multiwoven::Integrations::Core
8
+ class Client < DestinationConnector
9
+ MAX_CHUNK_SIZE = 10
10
+ def check_connection(connection_config)
11
+ connection_config = connection_config.with_indifferent_access
12
+ db = create_connection(connection_config)
13
+ response = db.get("/api/2.0/clusters/list")
14
+ if response.status == 200
15
+ success_status
16
+ else
17
+ failure_status(nil)
18
+ end
19
+ rescue StandardError => e
20
+ handle_exception(e, {
21
+ context: "DATABRICKS:LAKEHOUSE:CHECK_CONNECTION:EXCEPTION",
22
+ type: "error"
23
+ })
24
+ failure_status(e)
25
+ end
26
+
27
+ def discover(connection_config)
28
+ connection_config = connection_config.with_indifferent_access
29
+ table_query = "SHOW TABLES IN #{connection_config[:catalog]}.#{connection_config[:schema]};"
30
+ db = create_connection(connection_config)
31
+ records = []
32
+ table_response = db.post("/api/2.0/sql/statements", generate_body(connection_config[:warehouse_id], table_query).to_json)
33
+ table_response_body = JSON.parse(table_response.body)
34
+ table_response_body["result"]["data_array"].each do |table|
35
+ table_name = table[1]
36
+ query = "DESCRIBE TABLE #{connection_config[:catalog]}.#{connection_config[:schema]}.#{table_name};"
37
+ column_response = db.post("/api/2.0/sql/statements", generate_body(connection_config[:warehouse_id], query).to_json)
38
+ column_response_body = JSON.parse(column_response.body)
39
+ records << [table_name, column_response_body["result"]["data_array"]]
40
+ end
41
+ catalog = Catalog.new(streams: create_streams(records))
42
+ catalog.to_multiwoven_message
43
+ rescue StandardError => e
44
+ handle_exception(
45
+ "DATABRICKS:LAKEHOUSE:DISCOVER:EXCEPTION",
46
+ "error",
47
+ e
48
+ )
49
+ end
50
+
51
+ def write(sync_config, records, action = "destination_insert")
52
+ connection_config = sync_config.destination.connection_specification.with_indifferent_access
53
+ table_name = "#{connection_config[:catalog]}.#{connection_config[:schema]}.#{sync_config.stream.name}"
54
+ primary_key = sync_config.model.primary_key
55
+ db = create_connection(connection_config)
56
+ write_success = 0
57
+ write_failure = 0
58
+ log_message_array = []
59
+
60
+ records.each do |record|
61
+ query = Multiwoven::Integrations::Core::QueryBuilder.perform(action, table_name, record, primary_key)
62
+ logger.debug("DATABRICKS:LAKEHOUSE:WRITE:QUERY query = #{query} sync_id = #{sync_config.sync_id} sync_run_id = #{sync_config.sync_run_id}")
63
+ begin
64
+ arg = ["/api/2.0/sql/statements", generate_body(connection_config[:warehouse_id], query)]
65
+ response = db.post("/api/2.0/sql/statements", generate_body(connection_config[:warehouse_id], query).to_json)
66
+ if response.status == 200
67
+ write_success += 1
68
+ else
69
+ write_failure += 1
70
+ end
71
+ log_message_array << log_request_response("info", arg, response)
72
+ rescue StandardError => e
73
+ handle_exception(e, {
74
+ context: "DATABRICKS:LAKEHOUSE:RECORD:WRITE:EXCEPTION",
75
+ type: "error",
76
+ sync_id: sync_config.sync_id,
77
+ sync_run_id: sync_config.sync_run_id
78
+ })
79
+ write_failure += 1
80
+ end
81
+ end
82
+ tracking_message(write_success, write_failure)
83
+ rescue StandardError => e
84
+ handle_exception(e, {
85
+ context: "DATABRICKS:LAKEHOUSE:RECORD:WRITE:EXCEPTION",
86
+ type: "error",
87
+ sync_id: sync_config.sync_id,
88
+ sync_run_id: sync_config.sync_run_id
89
+ })
90
+ end
91
+
92
+ private
93
+
94
+ def create_connection(connection_config)
95
+ Faraday.new(url: connection_config[:host]) do |conn|
96
+ conn.headers["Authorization"] = "Bearer #{connection_config[:api_token]}"
97
+ conn.headers["Content-Type"] = "application/json"
98
+ conn.adapter Faraday.default_adapter
99
+ end
100
+ end
101
+
102
+ def generate_body(warehouse_id, query)
103
+ {
104
+ warehouse_id: warehouse_id,
105
+ statement: query,
106
+ wait_timeout: "15s"
107
+ }
108
+ end
109
+
110
+ def create_streams(records)
111
+ message = []
112
+ group_by_table(records).each_value do |r|
113
+ message << Multiwoven::Integrations::Protocol::Stream.new(name: r[:tablename], action: StreamAction["fetch"], json_schema: convert_to_json_schema(r[:columns]))
114
+ end
115
+ message
116
+ end
117
+
118
+ def group_by_table(records)
119
+ result = {}
120
+ records.each_with_index do |entries, index|
121
+ table_name = records[index][0]
122
+ column = []
123
+ entry_data = entries[1]
124
+ entry_data.each do |entry|
125
+ column << {
126
+ column_name: entry[0],
127
+ data_type: entry[1],
128
+ is_nullable: true
129
+ }
130
+ end
131
+ result[index] ||= {}
132
+ result[index][:tablename] = table_name
133
+ result[index][:columns] = column
134
+ end
135
+ result
136
+ end
137
+
138
+ def tracking_message(success, failure)
139
+ Multiwoven::Integrations::Protocol::TrackingMessage.new(
140
+ success: success, failed: failure
141
+ ).to_multiwoven_message
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "DatabricksLakehouse",
4
+ "title": "Databricks Lakehouse",
5
+ "connector_type": "destination",
6
+ "category": "Marketing Automation",
7
+ "documentation_url": "https://docs.multiwoven.com/destinations/databricks_lakehouse",
8
+ "github_issue_label": "destination-databricks-lakehouse",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "multiwoven"]
14
+ }
15
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "documentation_url": "https://docs.multiwoven.com/integrations/destination/databrick_lakehouse",
3
+ "stream_type": "static",
4
+ "connection_specification": {
5
+ "$schema": "http://json-schema.org/draft-07/schema#",
6
+ "title": "Databricks Lakehouse",
7
+ "type": "object",
8
+ "required": ["host", "api_token", "warehouse_id", "catalog", "schema"],
9
+ "properties": {
10
+ "host": {
11
+ "description": "The databrick lakehouse host domain.",
12
+ "type": "string",
13
+ "title": "Host",
14
+ "order": 0
15
+ },
16
+ "api_token": {
17
+ "description": "The databrick lakehouse api token.",
18
+ "type": "string",
19
+ "multiwoven_secret": true,
20
+ "title": "API Token",
21
+ "order": 1
22
+ },"warehouse_id": {
23
+ "description": "The databrick lakehouse warehouse ID.",
24
+ "type": "string",
25
+ "title": "Warehouse ID",
26
+ "order": 2
27
+ },
28
+ "catalog": {
29
+ "description": "The name of the catalog",
30
+ "default": "hive_metastore",
31
+ "type": "string",
32
+ "title": "Databricks catalog",
33
+ "order": 3
34
+ },
35
+ "schema": {
36
+ "description": "The default schema tables are written.",
37
+ "default": "default",
38
+ "type": "string",
39
+ "title": "Database schema",
40
+ "order": 4
41
+ }
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,65 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+
4
+ <svg
5
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+ xmlns:cc="http://creativecommons.org/ns#"
7
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+ xmlns:svg="http://www.w3.org/2000/svg"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ version="1.1"
13
+ id="Layer_1"
14
+ x="0px"
15
+ y="0px"
16
+ viewBox="0 0 64 64"
17
+ enable-background="new 0 0 640 96"
18
+ xml:space="preserve"
19
+ sodipodi:docname="databricks-icon.svg"
20
+ width="64"
21
+ height="64"
22
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
23
+ id="metadata45"><rdf:RDF><cc:Work
24
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
25
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
26
+ id="defs43" /><sodipodi:namedview
27
+ pagecolor="#ffffff"
28
+ bordercolor="#666666"
29
+ borderopacity="1"
30
+ objecttolerance="10"
31
+ gridtolerance="10"
32
+ guidetolerance="10"
33
+ inkscape:pageopacity="0"
34
+ inkscape:pageshadow="2"
35
+ inkscape:window-width="1920"
36
+ inkscape:window-height="1001"
37
+ id="namedview41"
38
+ showgrid="false"
39
+ inkscape:zoom="2.996365"
40
+ inkscape:cx="53.009829"
41
+ inkscape:cy="48"
42
+ inkscape:window-x="-9"
43
+ inkscape:window-y="-9"
44
+ inkscape:window-maximized="1"
45
+ inkscape:current-layer="Layer_1" />
46
+
47
+
48
+
49
+ <g
50
+ id="g50"
51
+ transform="matrix(0.75294118,0,0,0.75294118,1.0541175,18.823529)"><path
52
+ style="fill:#db1905"
53
+ inkscape:connector-curvature="0"
54
+ id="path2"
55
+ d="M 0,24.8 V 38.5 L 41.1,60 82.2,38.5 v -13.7 0 L 67.7,17.4 82.2,9.8 v -13.6 0 0 -0.1 L 82.1,-3.8 41.1,-25 0.1,-3.9 H 0 V 9.8 L 14.5,17.4 0,24.8" /><polygon
56
+ transform="translate(0,-36)"
57
+ style="fill:#ff5224"
58
+ id="polygon4"
59
+ points="0,60.8 41.1,82.3 82.2,60.8 67.7,53.4 41.1,67.3 14.5,53.4 " /><polygon
60
+ transform="translate(0,-36)"
61
+ style="fill:#ff5224"
62
+ id="polygon6"
63
+ points="82.2,32.2 41.1,53.7 0,32.2 41.1,11 " /></g>
64
+
65
+ </svg>
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Multiwoven
4
4
  module Integrations
5
- VERSION = "0.4.0"
5
+ VERSION = "0.5.0"
6
6
 
7
7
  ENABLED_SOURCES = %w[
8
8
  Snowflake
@@ -33,6 +33,7 @@ module Multiwoven
33
33
  Zendesk
34
34
  Iterable
35
35
  MariaDB
36
+ DatabricksLakehouse
36
37
  ].freeze
37
38
  end
38
39
  end
@@ -55,8 +55,7 @@ module Multiwoven::Integrations::Source
55
55
  if connection_config[:auth_type] == "user"
56
56
  Aws::Credentials.new(connection_config[:access_id], connection_config[:secret_access])
57
57
  elsif connection_config[:auth_type] == "role"
58
- credentials = Aws::Credentials.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
59
- sts_client = Aws::STS::Client.new(region: connection_config[:region], credentials: credentials)
58
+ sts_client = Aws::STS::Client.new(region: connection_config[:region])
60
59
  resp = sts_client.assume_role({
61
60
  role_arn: connection_config[:arn],
62
61
  role_session_name: session,
@@ -77,6 +77,7 @@ require_relative "integrations/destination/http/client"
77
77
  require_relative "integrations/destination/zendesk/client"
78
78
  require_relative "integrations/destination/iterable/client"
79
79
  require_relative "integrations/destination/maria_db/client"
80
+ require_relative "integrations/destination/databricks_lakehouse/client"
80
81
 
81
82
  module Multiwoven
82
83
  module Integrations
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiwoven-integrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Subin T P
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-01 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -492,6 +492,10 @@ files:
492
492
  - lib/multiwoven/integrations/destination/airtable/config/spec.json
493
493
  - lib/multiwoven/integrations/destination/airtable/icon.svg
494
494
  - lib/multiwoven/integrations/destination/airtable/schema_helper.rb
495
+ - lib/multiwoven/integrations/destination/databricks_lakehouse/client.rb
496
+ - lib/multiwoven/integrations/destination/databricks_lakehouse/config/meta.json
497
+ - lib/multiwoven/integrations/destination/databricks_lakehouse/config/spec.json
498
+ - lib/multiwoven/integrations/destination/databricks_lakehouse/icon.svg
495
499
  - lib/multiwoven/integrations/destination/facebook_custom_audience/client.rb
496
500
  - lib/multiwoven/integrations/destination/facebook_custom_audience/config/catalog.json
497
501
  - lib/multiwoven/integrations/destination/facebook_custom_audience/config/meta.json