cdp-sdk 0.14.2

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.
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'timeline-swagger-client'
4
+ require 'cdp/timeline/response'
5
+ require 'cdp/timeline/summary_response'
6
+ require 'cdp/timeline/event'
7
+ require 'cdp/timeline/client/swagger/configuration'
8
+
9
+ module CDP
10
+ module Timeline
11
+ module Client
12
+ module Swagger
13
+ class Client
14
+
15
+ MAX_ATTEMPTS = 5
16
+ TIMEOUT_MESSAGE = 'Connection timed out'
17
+
18
+ def initialize(config: Configuration.default)
19
+ @client = TimelineSwaggerClient::TimelineApi.new(
20
+ TimelineSwaggerClient::ApiClient.new(
21
+ translate_config(config)
22
+ )
23
+ )
24
+ end
25
+
26
+ def get_timeline(tenant_id:, entity_uuid:, event_types:, limit: 10, after: nil, event_source: nil, include_lead_tracker: nil)
27
+ opts = {}
28
+ opts[:limit] = limit if limit
29
+ opts[:after] = after if after
30
+ opts[:event_source] = event_source if event_source
31
+ opts[:include_lead_tracker] = include_lead_tracker unless include_lead_tracker.nil?
32
+ api_response = send_request(
33
+ :v1_timeline_get,
34
+ tenant_id,
35
+ entity_uuid,
36
+ event_types,
37
+ opts
38
+ )
39
+
40
+ parsed_items = api_response.events.map do |event|
41
+ transform_event(event)
42
+ end
43
+
44
+ paging = CDP::Timeline::Response::Paging.new
45
+ paging.cursor.after = api_response.paging.cursor.after
46
+
47
+ Timeline::Response.new(
48
+ success: true,
49
+ items: parsed_items,
50
+ paging: paging,
51
+ error: api_response.error
52
+ )
53
+ rescue TimelineSwaggerClient::ApiError => error
54
+ Timeline::Response.new(success: false, error: error)
55
+ end
56
+
57
+ def get_timeline_summary(tenant_id:, entity_uuid:, event_types:, event_source: nil)
58
+ opts = {}
59
+ opts[:event_source] = event_source if event_source
60
+
61
+ summary_response = Timeline::SummaryResponse.new
62
+ api_response = send_request(
63
+ :v1_timeline_summary_get,
64
+ tenant_id,
65
+ entity_uuid,
66
+ event_types,
67
+ opts
68
+ )
69
+ summary_response.events_summary = api_response.events_summary
70
+ summary_response
71
+ rescue TimelineSwaggerClient::ApiError => error
72
+ response = Timeline::SummaryResponse.new
73
+ response.error = error
74
+ response
75
+ end
76
+
77
+ private
78
+
79
+ def send_request(client_method, *params)
80
+ response = nil
81
+ error = nil
82
+
83
+ attempts = 1
84
+ begin
85
+ @client.public_send(client_method, *params)
86
+ rescue TimelineSwaggerClient::ApiError => api_error
87
+ if retryable_error?(api_error) && attempts < MAX_ATTEMPTS
88
+ attempts += 1
89
+ retry
90
+ else
91
+ raise
92
+ end
93
+ end
94
+ end
95
+
96
+ def retryable_error?(api_error)
97
+ api_error.message == TIMEOUT_MESSAGE || api_error.code >= 500
98
+ end
99
+
100
+ def translate_config(cdp_config)
101
+ TimelineSwaggerClient::Configuration.new do |config|
102
+ config.scheme = cdp_config.scheme
103
+ config.host = cdp_config.host
104
+ config.base_path = cdp_config.base_path
105
+ config.api_key['x-api-key'] = cdp_config.api_key if cdp_config.api_key.to_s != ''
106
+ end
107
+ end
108
+
109
+ def transform_event(event)
110
+ CDP::Timeline::Event.new(
111
+ event_uuid: event.event_uuid,
112
+ event_timestamp: event.event_timestamp,
113
+ event_identifier: event.event_identifier,
114
+ event_type: event.event_type,
115
+ event_canceled_at: event.event_canceled_at,
116
+ payload: event.payload,
117
+ )
118
+ end
119
+
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,32 @@
1
+ module CDP
2
+ module Timeline
3
+ module Client
4
+ module Swagger
5
+ class Configuration
6
+
7
+ attr_accessor :scheme
8
+ attr_accessor :host
9
+ attr_accessor :base_path
10
+ attr_accessor :api_key
11
+
12
+ def initialize
13
+ @scheme = 'https'
14
+ @host = 'cdp.rd.services'
15
+ @base_path = '/event_api'
16
+
17
+ yield(self) if block_given?
18
+ end
19
+
20
+ # The default Configuration object.
21
+ def self.default
22
+ @@default ||= Configuration.new
23
+ end
24
+
25
+ def configure
26
+ yield(self) if block_given?
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,56 @@
1
+ module CDP
2
+ module Timeline
3
+ class Event
4
+ attr_accessor :event_uuid
5
+ attr_accessor :event_identifier
6
+ attr_accessor :event_type
7
+ attr_accessor :event_timestamp
8
+ attr_accessor :event_canceled_at
9
+ attr_accessor :payload
10
+
11
+ def initialize(
12
+ event_uuid: nil,
13
+ event_identifier: nil,
14
+ event_type: nil,
15
+ event_timestamp: nil,
16
+ event_canceled_at: nil,
17
+ payload: nil
18
+ )
19
+ @event_uuid = event_uuid
20
+ @event_identifier = event_identifier
21
+ @event_type = event_type
22
+ @event_timestamp = event_timestamp
23
+ @event_canceled_at = event_canceled_at
24
+ @payload = payload
25
+ end
26
+
27
+ def ==(o)
28
+ return true if self.equal?(o)
29
+ self.class == o.class &&
30
+ event_uuid == o.event_uuid &&
31
+ event_identifier == o.event_identifier &&
32
+ event_timestamp == o.event_timestamp &&
33
+ event_canceled_at == o.event_canceled_at &&
34
+ event_type == o.event_type &&
35
+ payload == o.payload
36
+ end
37
+
38
+ # @see the `==` method
39
+ # @param [Object] Object to be compared
40
+ def eql?(o)
41
+ self == o
42
+ end
43
+
44
+ def to_hash
45
+ {
46
+ event_uuid: event_uuid,
47
+ event_identifier: event_identifier,
48
+ event_type: event_type,
49
+ event_timestamp: event_timestamp,
50
+ event_canceled_at: event_canceled_at,
51
+ payload: payload,
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,37 @@
1
+ module CDP
2
+ module Timeline
3
+ class Response
4
+ class Paging
5
+
6
+ class Cursor
7
+ attr_accessor :after
8
+ end
9
+
10
+ def initialize
11
+ @cursor = Cursor.new
12
+ end
13
+
14
+ attr_accessor :cursor
15
+ end
16
+
17
+ attr_reader :items, :paging, :error
18
+
19
+ def initialize(success: true, items: [], paging: nil, error: nil)
20
+ raise ArgumentError, "Invalid paging object." if paging && !paging.is_a?(Paging)
21
+
22
+ @success = success
23
+ @items = items
24
+ @paging = paging || Paging.new
25
+ @error = error
26
+ end
27
+
28
+ def success?
29
+ !!@success
30
+ end
31
+
32
+ def error?
33
+ !success?
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ module CDP
2
+ module Timeline
3
+ class SummaryResponse
4
+
5
+ attr_accessor :events_summary
6
+ attr_accessor :error
7
+
8
+ def initialize
9
+ @error = false
10
+ end
11
+
12
+ def success?
13
+ !@error
14
+ end
15
+
16
+ def error?
17
+ @error
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cdp/timeline/client/swagger/client'
4
+
5
+ module CDP
6
+ module Timeline
7
+
8
+ CDP_EVENT_SOURCE = 'CDP'
9
+ MONGO_EVENT_SOURCE = 'MONGO'
10
+
11
+ module_function
12
+
13
+ def timeline_for_entity(tenant_id:, entity_uuid:, event_types:, limit: 10, after: nil, event_source: nil, include_lead_tracker: nil)
14
+ client.get_timeline(
15
+ tenant_id: tenant_id,
16
+ entity_uuid: entity_uuid,
17
+ event_types: event_types,
18
+ limit: limit,
19
+ after: after,
20
+ event_source: event_source,
21
+ include_lead_tracker: include_lead_tracker
22
+ )
23
+ end
24
+
25
+ def timeline_summary_for_entity(tenant_id:, entity_uuid:, event_types:, event_source: nil)
26
+ client.get_timeline_summary(
27
+ tenant_id: tenant_id,
28
+ entity_uuid: entity_uuid,
29
+ event_types: event_types,
30
+ event_source: event_source
31
+ )
32
+ end
33
+
34
+ def client
35
+ @client ||= default_client
36
+ end
37
+
38
+ def client=(client)
39
+ @client = client
40
+ end
41
+
42
+ def default_client
43
+ Client::Swagger::Client.new
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,10 @@
1
+ CDP::Transaction.class_eval do
2
+ def <<(transaction)
3
+ raise ArgumentError, "transaction should be a CDP::Transaction" unless transaction.is_a?(CDP::Transaction)
4
+ raise ArgumentError, "transaction.item should be a CDP::Command" unless transaction.commands.all?{|command| command.is_a?(CDP::Command)}
5
+
6
+ transaction.commands.each do |command|
7
+ self.commands << command
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CDP
4
+ class Validator
5
+ def initialize(field_schema:)
6
+ @field_schema = field_schema
7
+ field_types = @field_schema[:field_types]
8
+
9
+ @fields_validations = build_statements(field_types)
10
+ end
11
+
12
+ def create(attributes:)
13
+ validator = ValidKit::Validator.new(@fields_validations.values.flatten)
14
+
15
+ validator.validate(attributes)
16
+ end
17
+
18
+ def update(attributes:)
19
+ update_validations = @fields_validations.slice(*attributes.keys.map(&:to_s))
20
+ validator = ValidKit::Validator.new(update_validations.values.flatten)
21
+
22
+ validator.validate(attributes)
23
+ end
24
+
25
+ def upsert(attributes:)
26
+ create(attributes: attributes)
27
+ end
28
+
29
+
30
+ def is_correlator?(field_name:)
31
+ return true if field_name == 'entity_uuid'
32
+ field = @field_schema[:field_types][field_name]
33
+
34
+ return false unless field && field.key?(:is_correlator)
35
+
36
+ field[:is_correlator]
37
+ end
38
+
39
+ private
40
+
41
+ def build_statements(field_types)
42
+ statements = {}
43
+
44
+ field_types.each do |_, field_type|
45
+ rules = []
46
+ validation_rules = field_type[:validation_rules]
47
+
48
+ next unless validation_rules
49
+
50
+ validation_rules.each do |key, value|
51
+ next unless value
52
+
53
+ rule = create_rule(key, value)
54
+ rules << rule if rule
55
+ end
56
+
57
+ statements[field_type[:name]] = ValidKit::Statement.new(path: "$.#{field_type[:name]}",
58
+ data_type: field_type[:data_type],
59
+ rules: rules)
60
+
61
+ end
62
+
63
+ statements
64
+ end
65
+
66
+ def create_rule(rule_type, rule_params)
67
+ case rule_type
68
+ when :length
69
+ ValidKit::Rule::Length.new(min: rule_params[:min], max: rule_params[:max])
70
+ when :required
71
+ ValidKit::Rule::Required.new
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/cdp/value.rb ADDED
@@ -0,0 +1,98 @@
1
+ module CDP
2
+ class Value
3
+ def value_type
4
+ raise ArgumentError, "value is empty" if self.value.nil?
5
+ self.value.value_type
6
+ end
7
+
8
+ def raw
9
+ case value_type
10
+ when :string_value
11
+ string_value
12
+ when :text_value
13
+ text_value
14
+ when :bool_value
15
+ bool_value
16
+ when :int_value
17
+ int_value
18
+ when :float_value
19
+ float_value
20
+ when :timestamp_value
21
+ time = timestamp_value
22
+ Time.at(time.seconds, time.nanos)
23
+ else
24
+ raise 'value type "%s" is not valid' % [value_type]
25
+ end
26
+ end
27
+
28
+ def string_value
29
+ raise ArgumentError, "value is empty" if self.value.nil?
30
+ self.value.string_value
31
+ end
32
+
33
+ def self.create_string(field_value)
34
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_string(field_value))
35
+ end
36
+
37
+ def text_value
38
+ raise ArgumentError, "value is empty" if self.value.nil?
39
+ self.value.text_value
40
+ end
41
+
42
+ def self.create_text(field_value)
43
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_text(field_value))
44
+ end
45
+
46
+ def bool_value
47
+ raise ArgumentError, "value is empty" if self.value.nil?
48
+ self.value.bool_value
49
+ end
50
+
51
+ def self.create_bool(field_value)
52
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_bool(field_value))
53
+ end
54
+
55
+ def int_value
56
+ raise ArgumentError, "value is empty" if self.value.nil?
57
+ self.value.int_value
58
+ end
59
+
60
+ def self.create_int(field_value)
61
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_int(field_value))
62
+ end
63
+
64
+ def float_value
65
+ raise ArgumentError, "value is empty" if self.value.nil?
66
+ self.value.float_value
67
+ end
68
+
69
+ def self.create_float(field_value)
70
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_float(field_value))
71
+ end
72
+
73
+ def timestamp_value
74
+ raise ArgumentError, "value is empty" if self.value.nil?
75
+ self.value.timestamp_value
76
+ end
77
+
78
+ def self.create_timestamp(field_value)
79
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_timestamp(field_value))
80
+ end
81
+
82
+ def array_value
83
+ raise ArgumentError, "value is empty" if self.value.nil?
84
+ self.value.array_value
85
+ end
86
+
87
+ def self.create_set_values(field_value)
88
+ set_values = field_value.map do |item|
89
+ Platform::Model::ValueBuilder.create_string(item)
90
+ end
91
+
92
+ CDP::Value.new(value: Platform::Model::ValueBuilder.create_array(
93
+ Platform::Model::ValueType::STRING,
94
+ set_values
95
+ ))
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CDP
4
+ VERSION = '0.14.2'
5
+ end
data/lib/cdp.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'platform-model'
4
+ require 'cdp/schema_client'
5
+ require 'cdp/version'
6
+
7
+ require 'persistency_pb'
8
+ require 'persistency_services_pb'
9
+ require 'legacy_pb'
10
+ require 'legacy_services_pb'
11
+
12
+ require 'cdp/builders/entity'
13
+ require 'cdp/builders/event'
14
+ require 'cdp/builders/after_created'
15
+ require 'cdp/builders/value'
16
+ require 'cdp/validator'
17
+ require 'cdp/builder'
18
+ require 'cdp/client'
19
+ require 'cdp/query/actions'
20
+ require 'cdp/persistency'
21
+ require 'cdp/transaction'
22
+ require 'cdp/value'
23
+
24
+ module CDP
25
+ class Error < StandardError; end
26
+
27
+ class InvalidCorrelatorError < Error; end
28
+
29
+ class SchemaMissingFieldError < Error; end
30
+
31
+ class InvalidFieldTypeError < Error; end
32
+
33
+ class InvalidEntityError < Error
34
+ def initialize(errors)
35
+ @errors = errors
36
+ super(errors)
37
+ end
38
+ end
39
+ end
data/lib/common_pb.rb ADDED
@@ -0,0 +1,30 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: common.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'value_pb'
7
+
8
+ Google::Protobuf::DescriptorPool.generated_pool.build do
9
+ add_file("common.proto", :syntax => :proto3) do
10
+ add_message "cdp.CommandReference" do
11
+ optional :id, :string, 1
12
+ end
13
+ add_message "cdp.Value" do
14
+ oneof :_value do
15
+ optional :value, :message, 1, "platformmodel.Value"
16
+ optional :reference, :message, 2, "cdp.CommandReference"
17
+ end
18
+ end
19
+ add_message "cdp.FieldCondition" do
20
+ optional :field_name, :string, 1
21
+ optional :field_value, :message, 2, "cdp.Value"
22
+ end
23
+ end
24
+ end
25
+
26
+ module CDP
27
+ CommandReference = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.CommandReference").msgclass
28
+ Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.Value").msgclass
29
+ FieldCondition = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.FieldCondition").msgclass
30
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Configuration
4
+ CDP_CORE_SERVICE_URL = ENV.fetch('CDP_CORE_SERVICE_URL', 'localhost:8080')
5
+ end
data/lib/legacy_pb.rb ADDED
@@ -0,0 +1,49 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: legacy.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'google/protobuf/struct_pb'
7
+
8
+ Google::Protobuf::DescriptorPool.generated_pool.build do
9
+ add_file("legacy.proto", :syntax => :proto3) do
10
+ add_message "cdp.legacy.ContactScoreRequest" do
11
+ optional :tenant_id, :int64, 1
12
+ repeated :contact_uuids, :string, 2
13
+ repeated :event_types, :string, 3
14
+ end
15
+ add_message "cdp.legacy.ContactScoreResponse" do
16
+ repeated :responses, :message, 1, "google.protobuf.Struct"
17
+ end
18
+ add_message "cdp.legacy.ExistsEventRequest" do
19
+ optional :tenant_id, :string, 1
20
+ optional :type, :string, 2
21
+ optional :event_identifier, :string, 3
22
+ optional :contact_uuid, :string, 4
23
+ end
24
+ add_message "cdp.legacy.ExistsEventResponse" do
25
+ optional :response, :bool, 1
26
+ end
27
+ add_message "cdp.legacy.GetEventRequest" do
28
+ optional :tenant_id, :string, 1
29
+ optional :type, :string, 2
30
+ optional :event_identifier, :string, 3
31
+ optional :contact_uuid, :string, 4
32
+ repeated :field_projection, :string, 5
33
+ end
34
+ add_message "cdp.legacy.GetEventResponse" do
35
+ repeated :responses, :message, 1, "google.protobuf.Struct"
36
+ end
37
+ end
38
+ end
39
+
40
+ module CDP
41
+ module Legacy
42
+ ContactScoreRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.legacy.ContactScoreRequest").msgclass
43
+ ContactScoreResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.legacy.ContactScoreResponse").msgclass
44
+ ExistsEventRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.legacy.ExistsEventRequest").msgclass
45
+ ExistsEventResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.legacy.ExistsEventResponse").msgclass
46
+ GetEventRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.legacy.GetEventRequest").msgclass
47
+ GetEventResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("cdp.legacy.GetEventResponse").msgclass
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: legacy.proto for package 'CDP.Legacy'
3
+
4
+ require 'grpc'
5
+ require 'legacy_pb'
6
+
7
+ module CDP
8
+ module Legacy
9
+ module Service
10
+ class Service
11
+
12
+ include ::GRPC::GenericService
13
+
14
+ self.marshal_class_method = :encode
15
+ self.unmarshal_class_method = :decode
16
+ self.service_name = 'cdp.legacy.Service'
17
+
18
+ rpc :GetContactScore, ::CDP::Legacy::ContactScoreRequest, ::CDP::Legacy::ContactScoreResponse
19
+ rpc :ExistsEvent, ::CDP::Legacy::ExistsEventRequest, ::CDP::Legacy::ExistsEventResponse
20
+ rpc :GetEvent, ::CDP::Legacy::GetEventRequest, ::CDP::Legacy::GetEventResponse
21
+ end
22
+
23
+ Stub = Service.rpc_stub_class
24
+ end
25
+ end
26
+ end