Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Add example errors connector and move simple example connector to a different namespace #437

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@ gem 'elasticsearch', '~> 8.5.0'
# Dependencies for oauth
gem 'signet', '~> 0.16.0'

# Dependency for example connector
gem 'faker', '~> 2.22.0'
Copy link
Contributor

@timgrein timgrein Nov 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👏 That'll be super helpful for the filtering example connector, too

# Dependency for mongo connector
gem 'mongo', '~> 2.18'
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ GEM
multi_json
et-orbi (1.2.7)
tzinfo
faker (2.22.0)
i18n (>= 1.8.11, < 2)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
Expand Down Expand Up @@ -220,6 +222,7 @@ DEPENDENCIES
dry-validation (= 1.7.0)
ecs-logging (~> 1.0.0)
elasticsearch (~> 8.5.0)
faker (~> 2.22.0)
faraday (~> 1.10.0)
faraday_middleware (= 1.0.0)
forwardable (~> 1.3.2)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.7.0.0
8.6.0.0
87 changes: 0 additions & 87 deletions lib/connectors/example/connector.rb

This file was deleted.

98 changes: 98 additions & 0 deletions lib/connectors/example/simple/connector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License;
# you may not use this file except in compliance with the Elastic License.
#

# frozen_string_literal: true

require 'connectors/base/connector'
require 'core/filtering/validation_status'
require 'utility'

module Connectors
module Example
module Simple
class Connector < Connectors::Base::Connector
def self.service_type
'example'
end

def self.display_name
'Example Connector'
end

# Field 'Foo' won't have a default value. Field 'Bar' will have the default value 'Value'.
def self.configurable_fields
{
'foo' => {
'label' => 'Foo',
'value' => nil
},
:bar => {
:label => 'Bar',
:value => 'Value'
}
}
end

def initialize(configuration: {}, job_description: {})
super
end

def do_health_check
# Do the health check by trying to access 3rd-party system just to verify that everything is set up properly.
#
# To emulate unhealthy 3rd-party system situation, uncomment the following line:
# raise 'something went wrong'
end

def self.validate_filtering(filtering = {})
# TODO: real filtering validation will follow later
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've changed this logic to only be present in the base connector and only override self.advanced_snippet_validator (so we plugin a dedicated validation class).

Just as a heads up, when it's merged :-)

errors = [
{
:ids => ['missing-implementation'],
:messages => ['Filtering is not implemented yet for the example connector']
}
]

return { :state => Core::Filtering::ValidationStatus::INVALID, :errors => errors } if filtering.present?

{ :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
end

def yield_documents
attachments = [
load_attachment('first_attachment.txt'),
load_attachment('second_attachment.txt'),
load_attachment('third_attachment.txt'),
]

attachments.each_with_index do |att, index|
data = { id: (index + 1).to_s, name: "example document #{index + 1}", _attachment: File.read(att) }

# Uncomment one of these two lines to simulate longer running sync jobs
#
# sleep(rand(10..60).seconds)
# sleep(rand(1..10).minutes)

yield data
end
end

private

def load_attachment(path)
attachment_dir = "#{File.dirname(__FILE__)}/attachments"
attachment_path = "#{attachment_dir}/#{path}"

unless File.exist?(attachment_path)
raise "Attachment at location '#{attachment_path}' doesn't exist. Attachments should be located under #{attachment_dir}"
end

File.open(attachment_path)
end
end
end
end
end
71 changes: 71 additions & 0 deletions lib/connectors/example/with_errors/connector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License;
# you may not use this file except in compliance with the Elastic License.
#

# frozen_string_literal: true

require 'connectors/base/connector'
require 'core/filtering/validation_status'
require 'utility'
require 'faker'

module Connectors
module Example
module WithErrors
class Connector < Connectors::Base::Connector
def self.service_type
'example-with-errors'
end

def self.display_name
'Example Connector that produces transient errors'
end

# Field 'Foo' won't have a default value. Field 'Bar' will have the default value 'Value'.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think that comment can be removed, right?

def self.configurable_fields
{
'chance_to_raise' => {
'label' => 'Chance to raise an error when extracting a document (0..100)',
'value' => 1
},
'generated_document_count' => {
'label' => 'Number of documents to generate',
'value' => 10_000
}
}
end

def initialize(configuration: {}, job_description: {})
super

@chance_to_raise = configuration.dig('chance_to_raise', 'value').to_i
@generated_document_count = configuration.dig('generated_document_count', 'value').to_i

raise 'Invalid chance to raise: should be between 0 and 100' if @chance_to_raise < 0 || @chance_to_raise > 100

Faker::Config.random = Random.new(1337) # we want to have a seed to consistently generate same text over and over
end

def do_health_check; end

def self.validate_filtering(_filtering = {})
{ :state => Core::Filtering::ValidationStatus::VALID, :errors => [] }
end

def yield_documents
@generated_document_count.times.map do |i|
yield_with_handling_tolerable_errors do
raise 'that is a random exception' if rand(1..100) > (100 - @chance_to_raise)

document = { 'id' => i, 'name' => Faker::Name.name, 'text' => Faker::Lorem.sentence }

yield document
end
end
end
end
end
end
end
7 changes: 5 additions & 2 deletions lib/connectors/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ def registered_connectors

REGISTRY = Factory.new

require_relative './example/connector'
REGISTRY.register(Connectors::Example::Connector.service_type, Connectors::Example::Connector)
require_relative './example/simple/connector'
REGISTRY.register(Connectors::Example::Simple::Connector.service_type, Connectors::Example::Simple::Connector)

require_relative './example/with_errors/connector'
REGISTRY.register(Connectors::Example::WithErrors::Connector.service_type, Connectors::Example::WithErrors::Connector)

# loading plugins (might replace this with a directory scan and conventions on names)
require_relative './gitlab/connector'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# frozen_string_literal: true

require 'connectors/example/connector'
require 'connectors/example/simple/connector'
require 'spec_helper'

describe Connectors::Example::Connector do
describe Connectors::Example::Simple::Connector do
subject { described_class.new(configuration: configuration) }
let(:configuration) do
{
Expand Down