diff --git a/Directory.Build.props b/Directory.Build.props
index f6f2b08..5e366d6 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -9,7 +9,7 @@
false
CS0105;CS0108;CS0109;CS0114;CS0162;CS0168;CS0169;CS0219;CS0252;CS0414;CS0472;CS0649;CS0652;CS1717;CS1998;CS4014;xUnit1013;MSB3245;MSB3270,NU1602
$(NoWarn);NU5105
prompt
@@ -19,7 +19,7 @@
$([System.Text.RegularExpressions.Regex]::Match($(Version), '\d+\.\d+').Value)
$([System.Text.RegularExpressions.Regex]::Match($(Version), '\d+\.\d+.\d+').Value)
CluedIn ApS
- Copyright (c) 2020 $(Company). All rights reserved.
+ Copyright (c) 2021 $(Company). All rights reserved.
CluedIn
$(MSBuildProjectName)
$(Product).$(AssemblyTitle)
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 1b26f1b..8773bf2 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -18,4 +18,4 @@
-
+
\ No newline at end of file
diff --git a/ExternalSearch.Providers.VatLayer.sln b/ExternalSearch.Providers.VatLayer.sln
index d3ae654..4df3e39 100644
--- a/ExternalSearch.Providers.VatLayer.sln
+++ b/ExternalSearch.Providers.VatLayer.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29503.13
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B2A52533-7FBF-41FE-A0AF-874FC54300B2}"
EndProject
@@ -46,22 +46,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Git", "Git", "{17EE3C8D-BAE
.gitignore = .gitignore
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalSearch.Providers.VatLayer", "src\ExternalSearch.Providers.VatLayer.csproj", "{BD49FBC7-7E7B-410C-BBB4-F3B0E3293541}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalSearch.VatLayer.Integration.Tests", "test\integration\ExternalSearch.VatLayer.Integration.Tests\ExternalSearch.VatLayer.Integration.Tests.csproj", "{DD79FB4E-FB22-41D7-8544-E2947EE6E99C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalSearch.VatLayer.Unit.Tests", "test\unit\ExternalSearch.VatLayer.Unit.Tests\ExternalSearch.VatLayer.Unit.Tests.csproj", "{195D0932-EA29-40BF-BBCE-26F7906504B9}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalSearch.Providers.VatLayer", "src\ExternalSearch.Providers.VatLayer\ExternalSearch.Providers.VatLayer.csproj", "{9FD65D12-0D5B-46B7-AE96-1502E4A45E30}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Provider.ExternalSearch.Providers.VatLayer", "src\ExternalSearch.Providers.VatLayer.Provider\Provider.ExternalSearch.Providers.VatLayer.csproj", "{D2B36432-79F7-41AD-90A8-CF34F2E07A33}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {BD49FBC7-7E7B-410C-BBB4-F3B0E3293541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BD49FBC7-7E7B-410C-BBB4-F3B0E3293541}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BD49FBC7-7E7B-410C-BBB4-F3B0E3293541}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BD49FBC7-7E7B-410C-BBB4-F3B0E3293541}.Release|Any CPU.Build.0 = Release|Any CPU
{DD79FB4E-FB22-41D7-8544-E2947EE6E99C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD79FB4E-FB22-41D7-8544-E2947EE6E99C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD79FB4E-FB22-41D7-8544-E2947EE6E99C}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -70,6 +68,14 @@ Global
{195D0932-EA29-40BF-BBCE-26F7906504B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{195D0932-EA29-40BF-BBCE-26F7906504B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{195D0932-EA29-40BF-BBCE-26F7906504B9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9FD65D12-0D5B-46B7-AE96-1502E4A45E30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9FD65D12-0D5B-46B7-AE96-1502E4A45E30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9FD65D12-0D5B-46B7-AE96-1502E4A45E30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9FD65D12-0D5B-46B7-AE96-1502E4A45E30}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D2B36432-79F7-41AD-90A8-CF34F2E07A33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D2B36432-79F7-41AD-90A8-CF34F2E07A33}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D2B36432-79F7-41AD-90A8-CF34F2E07A33}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D2B36432-79F7-41AD-90A8-CF34F2E07A33}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -82,9 +88,10 @@ Global
{02641789-0D38-4DBB-9288-23592CF55D25} = {9BD54E81-D9C8-4419-82B8-8EE6CC7E2647}
{2C3AECCF-DCB5-4ED7-8B7B-8F373EDE3A5E} = {9BD54E81-D9C8-4419-82B8-8EE6CC7E2647}
{17EE3C8D-BAE4-481A-B9CC-1BE878E86124} = {9BD54E81-D9C8-4419-82B8-8EE6CC7E2647}
- {BD49FBC7-7E7B-410C-BBB4-F3B0E3293541} = {B2A52533-7FBF-41FE-A0AF-874FC54300B2}
{DD79FB4E-FB22-41D7-8544-E2947EE6E99C} = {DBD1964B-DBD9-4C70-96CA-391C34B3D75F}
{195D0932-EA29-40BF-BBCE-26F7906504B9} = {A32B6852-82C7-4107-8C68-AE9232289E09}
+ {9FD65D12-0D5B-46B7-AE96-1502E4A45E30} = {B2A52533-7FBF-41FE-A0AF-874FC54300B2}
+ {D2B36432-79F7-41AD-90A8-CF34F2E07A33} = {B2A52533-7FBF-41FE-A0AF-874FC54300B2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6A61CB42-80C5-4A83-AC3E-DA41FC875525}
diff --git a/GitVersion.yml b/GitVersion.yml
index fda7acc..c0938e8 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -1,10 +1,6 @@
-mode: ContinuousDeployment
-next-version: 3.2
-branches:
- master:
- mode: ContinuousDelivery
- pull-request:
- tag: pr
- increment: None
- develop:
- tag: alpha1
\ No newline at end of file
+# GitVersion.yml
+mode: ContinuousDelivery
+next-version: 3.3
+branches: {}
+ignore:
+ sha: []
\ No newline at end of file
diff --git a/Packages.props b/Packages.props
index 3947b4b..dcd45c5 100644
--- a/Packages.props
+++ b/Packages.props
@@ -1,9 +1,9 @@
+ <_ComponentHost>2.0.0
<_AutoFixture>4.11.0
- <_CluedIn>3.2.0-*
+ <_CluedIn>3.3.0-*
-
-
-
+
+
-
+
-
-
-
+
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index e5b3af5..1d675d8 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -38,14 +38,7 @@ variables:
steps:
- # Configure NuGet
-- pwsh: |
- @('develop','release','AzurePipelines') | ForEach-Object{
- dotnet nuget update source $_ -p $env:NUGET_KEY -u VssSessionToken --configfile nuget.config
- }
- condition: and(succeeded(), variables['nuget.key'])
- displayName: 'Add api token to access nuget artifacts'
- env:
- NUGET_KEY: $(nuget.key)
+- task: NuGetAuthenticate@0
+ displayName: 'Authenticate with nuget'
- template: crawler.build.yml@templates
diff --git a/docs/3.3.0-release-notes.md b/docs/3.3.0-release-notes.md
new file mode 100644
index 0000000..6231292
--- /dev/null
+++ b/docs/3.3.0-release-notes.md
@@ -0,0 +1,2 @@
+### Features
+- Implemented Provider Model
\ No newline at end of file
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
deleted file mode 100644
index ba1dd70..0000000
--- a/src/Directory.Build.props
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- false
-
-
-
-
-
- git
- true
-
-
- symbols.nupkg
- true
-
-
-
-
diff --git a/src/ExternalSearch.Providers.VatLayer.Provider/Provider.ExternalSearch.Providers.VatLayer.csproj b/src/ExternalSearch.Providers.VatLayer.Provider/Provider.ExternalSearch.Providers.VatLayer.csproj
new file mode 100644
index 0000000..b93e7e7
--- /dev/null
+++ b/src/ExternalSearch.Providers.VatLayer.Provider/Provider.ExternalSearch.Providers.VatLayer.csproj
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ExternalSearch.Providers.VatLayer.Provider/VatLayerProviderProviderComponent.cs b/src/ExternalSearch.Providers.VatLayer.Provider/VatLayerProviderProviderComponent.cs
new file mode 100644
index 0000000..6c01508
--- /dev/null
+++ b/src/ExternalSearch.Providers.VatLayer.Provider/VatLayerProviderProviderComponent.cs
@@ -0,0 +1,51 @@
+using System.Reflection;
+using Castle.MicroKernel.Registration;
+using CluedIn.Core;
+using CluedIn.Core.Providers;
+using CluedIn.Core.Server;
+using ComponentHost;
+using Constants = CluedIn.ExternalSearch.Providers.VatLayer.Constants;
+
+namespace CluedIn.Provider.VatLayer
+{
+ [Component(Constants.ComponentName, "Providers", ComponentType.Service, ServerComponents.ProviderWebApi, Components.Server, Components.DataStores, Isolation = ComponentIsolation.NotIsolated)]
+ public sealed class VatLayerProviderProviderComponent : ServiceApplicationComponent
+ {
+ /**********************************************************************************************************
+ * CONSTRUCTOR
+ **********************************************************************************************************/
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The component information.
+ public VatLayerProviderProviderComponent(ComponentInfo componentInfo) : base(componentInfo)
+ {
+ // Dev. Note: Potential for compiler warning here ... CA2214: Do not call overridable methods in constructors
+ // this class has been sealed to prevent the CA2214 waring being raised by the compiler
+ Container.Register(Component.For().Instance(this));
+ }
+
+ /**********************************************************************************************************
+ * METHODS
+ **********************************************************************************************************/
+
+ /// Starts this instance.
+ public override void Start()
+ {
+ var asm = Assembly.GetAssembly(typeof(VatLayerProviderProviderComponent));
+ Container.Register(Types.FromAssembly(asm).BasedOn().WithServiceFromInterface().If(t => !t.IsAbstract).LifestyleSingleton());
+
+ State = ServiceState.Started;
+ }
+
+ /// Stops this instance.
+ public override void Stop()
+ {
+ if (State == ServiceState.Stopped)
+ return;
+
+ State = ServiceState.Stopped;
+ }
+ }
+}
diff --git a/src/ExternalSearch.Providers.VatLayer.Provider/VatLayerSearchProviderProvider.cs b/src/ExternalSearch.Providers.VatLayer.Provider/VatLayerSearchProviderProvider.cs
new file mode 100644
index 0000000..c6d1cdf
--- /dev/null
+++ b/src/ExternalSearch.Providers.VatLayer.Provider/VatLayerSearchProviderProvider.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CluedIn.Core;
+using CluedIn.Core.Crawling;
+using CluedIn.Core.Data.Relational;
+using CluedIn.Core.ExternalSearch;
+using CluedIn.Core.Providers;
+using CluedIn.Core.Webhooks;
+using CluedIn.ExternalSearch;
+using CluedIn.ExternalSearch.Providers.VatLayer;
+using CluedIn.Providers.Models;
+using Constants = CluedIn.ExternalSearch.Providers.VatLayer.Constants;
+
+namespace CluedIn.Provider.VatLayer
+{
+ public class VatLayerSearchProviderProvider : ProviderBase, IExtendedProviderMetadata, IExternalSearchProviderProvider
+ {
+ public IExternalSearchProvider ExternalSearchProvider { get; }
+
+ public VatLayerSearchProviderProvider([System.Diagnostics.CodeAnalysis.NotNull] ApplicationContext appContext) : base(appContext, GetMetaData())
+ {
+ ExternalSearchProvider = appContext.Container.ResolveAll().Single(n => n.Id == Constants.ProviderId);
+ }
+
+ private static IProviderMetadata GetMetaData()
+ {
+ return new ProviderMetadata
+ {
+ Id = Constants.ProviderId,
+ Name = Constants.ProviderName,
+ ComponentName = Constants.ComponentName,
+ AuthTypes = new List(),
+ SupportsConfiguration = true,
+ SupportsAutomaticWebhookCreation = false,
+ SupportsWebHooks = false,
+ Type = "Enricher"
+ };
+ }
+
+ public override async Task GetCrawlJobData(ProviderUpdateContext context, IDictionary configuration, Guid organizationId, Guid userId, Guid providerDefinitionId)
+ {
+ if (configuration == null)
+ throw new ArgumentNullException(nameof(configuration));
+
+ var result = new VatLayerExternalSearchJobData(configuration);
+
+ return await Task.FromResult(result);
+ }
+
+ public override Task TestAuthentication(ProviderUpdateContext context, IDictionary configuration, Guid organizationId, Guid userId, Guid providerDefinitionId)
+ {
+ return Task.FromResult(true);
+ }
+
+ public override Task FetchUnSyncedEntityStatistics(Core.ExecutionContext context, IDictionary configuration, Guid organizationId, Guid userId, Guid providerDefinitionId)
+ {
+ throw new NotImplementedException();
+ }
+
+
+ public override async Task> GetHelperConfiguration(ProviderUpdateContext context, CrawlJobData jobData, Guid organizationId, Guid userId, Guid providerDefinitionId)
+ {
+ if (jobData is VatLayerExternalSearchJobData result)
+ {
+ return await Task.FromResult(result.ToDictionary());
+ }
+
+ throw new InvalidOperationException($"Unexpected data type for {nameof(VatLayerExternalSearchJobData)}, {jobData.GetType()}");
+ }
+
+ public override Task> GetHelperConfiguration(ProviderUpdateContext context, CrawlJobData jobData, Guid organizationId, Guid userId, Guid providerDefinitionId, string folderId)
+ {
+ return GetHelperConfiguration(context, jobData, organizationId, userId, providerDefinitionId);
+ }
+
+ public override Task GetAccountInformation(Core.ExecutionContext context, CrawlJobData jobData, Guid organizationId, Guid userId, Guid providerDefinitionId)
+ {
+ return Task.FromResult(new AccountInformation(providerDefinitionId.ToString(), providerDefinitionId.ToString()));
+ }
+
+ public override string Schedule(DateTimeOffset relativeDateTime, bool webHooksEnabled)
+ {
+ return $"{relativeDateTime.Minute} 0/23 * * *";
+ }
+
+ public override Task> CreateWebHook(Core.ExecutionContext context, CrawlJobData jobData, IWebhookDefinition webhookDefinition, IDictionary config)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override Task> GetWebHooks(Core.ExecutionContext context)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override Task DeleteWebHook(Core.ExecutionContext context, CrawlJobData jobData, IWebhookDefinition webhookDefinition)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override Task GetRemainingApiAllowance(Core.ExecutionContext context, CrawlJobData jobData, Guid organizationId, Guid userId, Guid providerDefinitionId)
+ {
+ if (jobData == null) throw new ArgumentNullException(nameof(jobData));
+ return Task.FromResult(new CrawlLimit(-1, TimeSpan.Zero));
+ }
+
+ public override IEnumerable WebhookManagementEndpoints(IEnumerable ids)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string Icon { get; } = Constants.Icon;
+ public string Domain { get; } = Constants.Domain;
+ public string About { get; } = Constants.About;
+ public AuthMethods AuthMethods { get; } = Constants.AuthMethods;
+ public IEnumerable Properties { get; } = Constants.Properties;
+ public Guide Guide { get; } = Constants.Guide;
+ public new IntegrationType Type { get; } = Constants.IntegrationType;
+ }
+}
\ No newline at end of file
diff --git a/src/ExternalSearch.Providers.VatLayer/Constants.cs b/src/ExternalSearch.Providers.VatLayer/Constants.cs
new file mode 100644
index 0000000..007d08a
--- /dev/null
+++ b/src/ExternalSearch.Providers.VatLayer/Constants.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using CluedIn.Core.Data.Relational;
+using CluedIn.Core.Providers;
+
+namespace CluedIn.ExternalSearch.Providers.VatLayer
+{
+ public static class Constants
+ {
+ public const string ComponentName = "VatLayer";
+ public const string ProviderName = "Vat Layer";
+ public static readonly Guid ProviderId = Core.Constants.ExternalSearchProviders.VatLayerId;
+
+ public struct KeyName
+ {
+ public const string ApiToken = "apiToken";
+
+ }
+
+ public static string About { get; set; } = "VatLayer is an enricher for validating and cleaning VAT numbers";
+ public static string Icon { get; set; } = "Resources.vatlayer.png";
+ public static string Domain { get; set; } = "https://vatlayer.com/";
+
+ public static AuthMethods AuthMethods { get; set; } = new AuthMethods
+ {
+ token = new List()
+ {
+ new Control()
+ {
+ displayName = "Api Key",
+ type = "input",
+ isRequired = true,
+ name = KeyName.ApiToken
+ }
+ }
+ };
+
+ public static IEnumerable Properties { get; set; } = new List()
+ {
+ // NOTE: Leaving this commented as an example - BF
+ //new()
+ //{
+ // displayName = "Some Data",
+ // type = "input",
+ // isRequired = true,
+ // name = "someData"
+ //}
+ };
+
+ public static Guide Guide { get; set; } = null;
+ public static IntegrationType IntegrationType { get; set; } = IntegrationType.Enrichment;
+ }
+}
diff --git a/src/ExternalSearch.Providers.VatLayer/Directory.Build.props b/src/ExternalSearch.Providers.VatLayer/Directory.Build.props
new file mode 100644
index 0000000..2ed4d77
--- /dev/null
+++ b/src/ExternalSearch.Providers.VatLayer/Directory.Build.props
@@ -0,0 +1,35 @@
+
+
+ netcoreapp3.1
+
+
+
+
+ 4
+ false
+ CS0105;CS0108;CS0109;CS0114;CS0162;CS0168;CS0169;CS0219;CS0252;CS0414;CS0472;CS0649;CS0652;CS1717;CS1998;CS4014;xUnit1013;MSB3245;MSB3270,NU1602
+
+ $(NoWarn);NU5105
+ prompt
+
+
+
+ $([System.Text.RegularExpressions.Regex]::Match($(Version), '\d+\.\d+').Value)
+ $([System.Text.RegularExpressions.Regex]::Match($(Version), '\d+\.\d+.\d+').Value)
+ CluedIn ApS
+ Copyright (c) 2020 $(Company). All rights reserved.
+ CluedIn
+ $(MSBuildProjectName)
+ $(Product).$(AssemblyTitle)
+ $(AssemblyName)
+
+
+
+ $(RootNamespace)
+ $(Company)
+ http://cluedin.com
+
+
+
\ No newline at end of file
diff --git a/src/ExternalSearch.Providers.VatLayer.csproj b/src/ExternalSearch.Providers.VatLayer/ExternalSearch.Providers.VatLayer.csproj
similarity index 99%
rename from src/ExternalSearch.Providers.VatLayer.csproj
rename to src/ExternalSearch.Providers.VatLayer/ExternalSearch.Providers.VatLayer.csproj
index a6f99c6..8ec2992 100644
--- a/src/ExternalSearch.Providers.VatLayer.csproj
+++ b/src/ExternalSearch.Providers.VatLayer/ExternalSearch.Providers.VatLayer.csproj
@@ -5,6 +5,7 @@
+
diff --git a/src/Models/VatLayerResponse.cs b/src/ExternalSearch.Providers.VatLayer/Models/VatLayerResponse.cs
similarity index 100%
rename from src/Models/VatLayerResponse.cs
rename to src/ExternalSearch.Providers.VatLayer/Models/VatLayerResponse.cs
diff --git a/src/Properties/AssemblyInfo.cs b/src/ExternalSearch.Providers.VatLayer/Properties/AssemblyInfo.cs
similarity index 100%
rename from src/Properties/AssemblyInfo.cs
rename to src/ExternalSearch.Providers.VatLayer/Properties/AssemblyInfo.cs
diff --git a/src/Resources/cluedin.png b/src/ExternalSearch.Providers.VatLayer/Resources/cluedin.png
similarity index 100%
rename from src/Resources/cluedin.png
rename to src/ExternalSearch.Providers.VatLayer/Resources/cluedin.png
diff --git a/src/Resources/vatlayer.png b/src/ExternalSearch.Providers.VatLayer/Resources/vatlayer.png
similarity index 100%
rename from src/Resources/vatlayer.png
rename to src/ExternalSearch.Providers.VatLayer/Resources/vatlayer.png
diff --git a/src/Utility/VatNumberCleaner.cs b/src/ExternalSearch.Providers.VatLayer/Utility/VatNumberCleaner.cs
similarity index 100%
rename from src/Utility/VatNumberCleaner.cs
rename to src/ExternalSearch.Providers.VatLayer/Utility/VatNumberCleaner.cs
diff --git a/src/ExternalSearch.Providers.VatLayer/VatLayerExternalSearchJobData.cs b/src/ExternalSearch.Providers.VatLayer/VatLayerExternalSearchJobData.cs
new file mode 100644
index 0000000..da5922e
--- /dev/null
+++ b/src/ExternalSearch.Providers.VatLayer/VatLayerExternalSearchJobData.cs
@@ -0,0 +1,22 @@
+using System.Collections.Generic;
+using CluedIn.Core.Crawling;
+
+namespace CluedIn.ExternalSearch.Providers.VatLayer
+{
+ public class VatLayerExternalSearchJobData : CrawlJobData
+ {
+ public VatLayerExternalSearchJobData(IDictionary configuration)
+ {
+ ApiToken = GetValue(configuration, Constants.KeyName.ApiToken);
+ }
+
+ public IDictionary ToDictionary()
+ {
+ return new Dictionary {
+ { Constants.KeyName.ApiToken, ApiToken }
+ };
+ }
+
+ public string ApiToken { get; set; }
+ }
+}
diff --git a/src/VatLayerExternalSearchProvider.cs b/src/ExternalSearch.Providers.VatLayer/VatLayerExternalSearchProvider.cs
similarity index 75%
rename from src/VatLayerExternalSearchProvider.cs
rename to src/ExternalSearch.Providers.VatLayer/VatLayerExternalSearchProvider.cs
index dc62cd3..01bcf12 100644
--- a/src/VatLayerExternalSearchProvider.cs
+++ b/src/ExternalSearch.Providers.VatLayer/VatLayerExternalSearchProvider.cs
@@ -21,16 +21,18 @@
namespace CluedIn.ExternalSearch.Providers.VatLayer
{
+
/// The VatLayer graph external search provider.
///
- public class VatLayerExternalSearchProvider : ExternalSearchProviderBase, IExtendedEnricherMetadata
+ public class VatLayerExternalSearchProvider : ExternalSearchProviderBase, IExtendedEnricherMetadata, IConfigurableExternalSearchProvider
{
+ private static readonly EntityType[] AcceptedEntityTypes = { EntityType.Organization };
/**********************************************************************************************************
* CONSTRUCTORS
**********************************************************************************************************/
public VatLayerExternalSearchProvider()
- : base(Constants.ExternalSearchProviders.VatLayerId, EntityType.Organization)
+ : base(Constants.ProviderId, AcceptedEntityTypes)
{
var nameBasedTokenProvider = new NameBasedTokenProvider("VatLayer");
@@ -68,6 +70,16 @@ private VatLayerExternalSearchProvider(bool tokenProviderIsRequired)
/// The request.
/// The search queries.
public override IEnumerable BuildQueries(ExecutionContext context, IExternalSearchRequest request)
+ {
+ var apiToken = TokenProvider?.ApiToken;
+
+ foreach (var externalSearchQuery in InternalBuildQueries(context, request, apiToken))
+ {
+ yield return externalSearchQuery;
+ }
+ }
+
+ private IEnumerable InternalBuildQueries(ExecutionContext context, IExternalSearchRequest request, string apiToken)
{
if (context == null)
{
@@ -81,7 +93,7 @@ public override IEnumerable BuildQueries(ExecutionContext
using (context.Log.BeginScope($"{GetType().Name} BuildQueries: request {request}"))
{
- if (string.IsNullOrEmpty(TokenProvider?.ApiToken))
+ if (string.IsNullOrEmpty(apiToken))
{
context.Log.LogError("ApiToken for VatLayer must be provided.");
yield break;
@@ -89,12 +101,12 @@ public override IEnumerable BuildQueries(ExecutionContext
if (!Accepts(request.EntityMetaData.EntityType))
{
- context.Log.LogTrace("Unacceptable entity type from '{EntityName}', entity code '{EntityCode}'",request.EntityMetaData.DisplayName, request.EntityMetaData.EntityType.Code);
+ context.Log.LogTrace("Unacceptable entity type from '{EntityName}', entity code '{EntityCode}'", request.EntityMetaData.DisplayName, request.EntityMetaData.EntityType.Code);
yield break;
}
- context.Log.LogTrace("Starting to build queries for {EntityName}",request.EntityMetaData.DisplayName);
+ context.Log.LogTrace("Starting to build queries for {EntityName}", request.EntityMetaData.DisplayName);
var existingResults = request.GetQueryResults(this).ToList();
@@ -104,7 +116,7 @@ public override IEnumerable BuildQueries(ExecutionContext
var vatNumber = request.QueryParameters.GetValue(Core.Data.Vocabularies.Vocabularies.CluedInOrganization.VatNumber, new HashSet());
if (!vatNumber.Any())
{
- context.Log.LogTrace("No query parameter for '{VatNumber}' in request, skipping build queries",Core.Data.Vocabularies.Vocabularies.CluedInOrganization.VatNumber);
+ context.Log.LogTrace("No query parameter for '{VatNumber}' in request, skipping build queries", Core.Data.Vocabularies.Vocabularies.CluedInOrganization.VatNumber);
}
else
{
@@ -124,16 +136,16 @@ public override IEnumerable BuildQueries(ExecutionContext
if (value != sanitizedValue)
{
- context.Log.LogTrace("Sanitized VAT number. Original '{OriginalValue}', Updated '{SanitizedValue}'",value,sanitizedValue);
+ context.Log.LogTrace("Sanitized VAT number. Original '{OriginalValue}', Updated '{SanitizedValue}'", value, sanitizedValue);
}
- context.Log.LogInformation("External search query produced, ExternalSearchQueryParameter: '{Identifier}' EntityType: '{EntityCode}' Value: '{SanitizedValue}'",ExternalSearchQueryParameter.Identifier,entityType.Code,sanitizedValue);
+ context.Log.LogInformation("External search query produced, ExternalSearchQueryParameter: '{Identifier}' EntityType: '{EntityCode}' Value: '{SanitizedValue}'", ExternalSearchQueryParameter.Identifier, entityType.Code, sanitizedValue);
yield return new ExternalSearchQuery(this, entityType, ExternalSearchQueryParameter.Identifier, sanitizedValue);
}
}
- context.Log.LogTrace("Finished building queries for '{Name}'",request.EntityMetaData.Name);
+ context.Log.LogTrace("Finished building queries for '{Name}'", request.EntityMetaData.Name);
}
}
}
@@ -144,6 +156,21 @@ public override IEnumerable BuildQueries(ExecutionContext
/// The results.
public override IEnumerable ExecuteSearch(ExecutionContext context, IExternalSearchQuery query)
{
+ var apiToken = TokenProvider?.ApiToken;
+
+ foreach (var externalSearchQueryResult in InternalExecuteSearch(context, query, apiToken))
+ {
+ yield return externalSearchQueryResult;
+ }
+ }
+
+ private IEnumerable InternalExecuteSearch(ExecutionContext context, IExternalSearchQuery query, string apiToken)
+ {
+ if (string.IsNullOrEmpty(apiToken))
+ {
+ throw new InvalidOperationException("ApiToken for VatLayer must be provided.");
+ }
+
if (context == null)
{
throw new ArgumentNullException(nameof(context));
@@ -156,18 +183,13 @@ public override IEnumerable ExecuteSearch(ExecutionC
using (context.Log.BeginScope("{0} {1}: query {2}", GetType().Name, "ExecuteSearch", query))
{
- if (string.IsNullOrEmpty(TokenProvider?.ApiToken))
- {
- throw new InvalidOperationException("ApiToken for VatLayer must be provided.");
- }
-
- context.Log.LogTrace("Starting external search for Id: '{Id}' QueryKey: '{QueryKey}'",query.Id,query.QueryKey);
+ context.Log.LogTrace("Starting external search for Id: '{Id}' QueryKey: '{QueryKey}'", query.Id, query.QueryKey);
var vat = query.QueryParameters[ExternalSearchQueryParameter.Identifier].FirstOrDefault();
if (string.IsNullOrEmpty(vat))
{
- context.Log.LogTrace("No parameter for '{Identifier}' in query, skipping execute search",ExternalSearchQueryParameter.Identifier);
+ context.Log.LogTrace("No parameter for '{Identifier}' in query, skipping execute search", ExternalSearchQueryParameter.Identifier);
}
else
{
@@ -175,7 +197,7 @@ public override IEnumerable ExecuteSearch(ExecutionC
vat = WebUtility.UrlEncode(vat);
var client = new RestClient("http://www.apilayer.net/api");
- var request = new RestRequest($"validate?access_key={TokenProvider.ApiToken}&vat_number={vat}&format=1",
+ var request = new RestRequest($"validate?access_key={apiToken}&vat_number={vat}&format=1",
Method.GET);
var response = client.ExecuteAsync(request).Result;
@@ -236,7 +258,7 @@ public override IEnumerable ExecuteSearch(ExecutionC
throw new ApplicationException(diagnostic);
}
- context.Log.LogTrace("Finished external search for Id: '{Id}' QueryKey: '{QueryKey}'",query.Id,query.QueryKey);
+ context.Log.LogTrace("Finished external search for Id: '{Id}' QueryKey: '{QueryKey}'", query.Id, query.QueryKey);
}
}
}
@@ -282,9 +304,9 @@ public override IEnumerable BuildClues(ExecutionContext context,
clue.Data.EntityData.Codes.Add(new EntityCode(EntityType.Organization, CodeOrigin.CluedIn.CreateSpecific("vatlayer"), dirtyClue));
PopulateMetadata(clue.Data.EntityData, resultItem);
- context.Log.LogInformation("Clue produced, Id: '{Id}' OriginEntityCode: '{OriginEntityCode}' RawText: '{RawText}'",clue.Id,clue.OriginEntityCode,clue.RawText);
+ context.Log.LogInformation("Clue produced, Id: '{Id}' OriginEntityCode: '{OriginEntityCode}' RawText: '{RawText}'", clue.Id, clue.OriginEntityCode, clue.RawText);
- return new[] {clue};
+ return new[] { clue };
}
}
@@ -314,9 +336,9 @@ public override IEntityMetadata GetPrimaryEntityMetadata(ExecutionContext contex
using (context.Log.BeginScope("{0} {1}: request {2}, result {3}", GetType().Name, "GetPrimaryEntityMetadata", request, result))
{
- var metadata = CreateMetadata(result.As());
+ var metadata = CreateMetadata(result.As());
- context.Log.LogInformation("Primary entity meta data created, Name: '{Name}' OriginEntityCode: '{OriginEntityCode}'",metadata.Name,metadata.OriginEntityCode.Origin.Code);
+ context.Log.LogInformation("Primary entity meta data created, Name: '{Name}' OriginEntityCode: '{OriginEntityCode}'", metadata.Name, metadata.OriginEntityCode.Origin.Code);
return metadata;
}
@@ -370,28 +392,71 @@ private static void PopulateMetadata(IEntityMetadata metadata, IExternalSearchQu
{
var code = GetOriginEntityCode(resultItem);
- metadata.EntityType = EntityType.Organization;
- metadata.Name = resultItem.Data.CompanyName;
- metadata.OriginEntityCode = code;
+ metadata.EntityType = EntityType.Organization;
+ metadata.Name = resultItem.Data.CompanyName;
+ metadata.OriginEntityCode = code;
metadata.Codes.Add(code);
- metadata.Properties[VatLayerVocabulary.Organization.Name] = resultItem.Data.CompanyName;
+ metadata.Properties[VatLayerVocabulary.Organization.Name] = resultItem.Data.CompanyName;
- metadata.Properties[VatLayerVocabulary.Organization.CountryCode] = resultItem.Data.CountryCode;
+ metadata.Properties[VatLayerVocabulary.Organization.CountryCode] = resultItem.Data.CountryCode;
- metadata.Properties[VatLayerVocabulary.Organization.CvrNumber] = resultItem.Data.VatNumber;
+ metadata.Properties[VatLayerVocabulary.Organization.CvrNumber] = resultItem.Data.VatNumber;
- metadata.Properties[VatLayerVocabulary.Organization.FullVAT] = resultItem.Data.Query;
+ metadata.Properties[VatLayerVocabulary.Organization.FullVAT] = resultItem.Data.Query;
- metadata.Properties[VatLayerVocabulary.Organization.Address] = resultItem.Data.CompanyAddress;
+ metadata.Properties[VatLayerVocabulary.Organization.Address] = resultItem.Data.CompanyAddress;
}
- public string Icon { get; } = "Resources.vatlayer.png";
- public string Domain { get; } = "https://vatlayer.com/";
- public string About { get; } = "VatLayer is an enricher for validating and cleaning VAT numbers";
- public AuthMethods AuthMethods { get; } = null;
- public IEnumerable Properties { get; } = null;
- public Guide Guide { get; } = null;
- public IntegrationType Type { get; } = IntegrationType.Cloud;
+ public IEnumerable Accepts(IDictionary config, IProvider provider)
+ {
+ return AcceptedEntityTypes;
+ }
+
+ public IEnumerable BuildQueries(ExecutionContext context, IExternalSearchRequest request, IDictionary config, IProvider provider)
+ {
+ var jobData = new VatLayerExternalSearchJobData(config);
+
+ foreach (var externalSearchQuery in InternalBuildQueries(context, request, jobData.ApiToken))
+ {
+ yield return externalSearchQuery;
+ }
+ }
+
+ public IEnumerable ExecuteSearch(ExecutionContext context, IExternalSearchQuery query, IDictionary config, IProvider provider)
+ {
+ var jobData = new VatLayerExternalSearchJobData(config);
+
+ foreach (var externalSearchQueryResult in InternalExecuteSearch(context, query, jobData.ApiToken))
+ {
+ yield return externalSearchQueryResult;
+ }
+ }
+
+ public IEnumerable BuildClues(ExecutionContext context, IExternalSearchQuery query, IExternalSearchQueryResult result, IExternalSearchRequest request, IDictionary config, IProvider provider)
+ {
+ return BuildClues(context, query, result, request);
+ }
+
+ public IEntityMetadata GetPrimaryEntityMetadata(ExecutionContext context, IExternalSearchQueryResult result, IExternalSearchRequest request, IDictionary config, IProvider provider)
+ {
+ return GetPrimaryEntityMetadata(context, result, request);
+ }
+
+ public IPreviewImage GetPrimaryEntityPreviewImage(ExecutionContext context, IExternalSearchQueryResult result, IExternalSearchRequest request, IDictionary config, IProvider provider)
+ {
+ return GetPrimaryEntityPreviewImage(context, result, request);
+ }
+
+ public string Icon { get; } = Constants.Icon;
+ public string Domain { get; } = Constants.Domain;
+ public string About { get; } = Constants.About;
+
+ public AuthMethods AuthMethods { get; } = Constants.AuthMethods;
+ public IEnumerable Properties { get; } = Constants.Properties;
+ public Guide Guide { get; } = Constants.Guide;
+ public IntegrationType Type { get; } = Constants.IntegrationType;
+
+
}
}
diff --git a/src/Vocabularies/VatLayerOrganizationVocabulary.cs b/src/ExternalSearch.Providers.VatLayer/Vocabularies/VatLayerOrganizationVocabulary.cs
similarity index 100%
rename from src/Vocabularies/VatLayerOrganizationVocabulary.cs
rename to src/ExternalSearch.Providers.VatLayer/Vocabularies/VatLayerOrganizationVocabulary.cs
diff --git a/src/Vocabularies/VatLayerVocabulary.cs b/src/ExternalSearch.Providers.VatLayer/Vocabularies/VatLayerVocabulary.cs
similarity index 100%
rename from src/Vocabularies/VatLayerVocabulary.cs
rename to src/ExternalSearch.Providers.VatLayer/Vocabularies/VatLayerVocabulary.cs
diff --git a/test/integration/ExternalSearch.VatLayer.Integration.Tests/ExternalSearch.VatLayer.Integration.Tests.csproj b/test/integration/ExternalSearch.VatLayer.Integration.Tests/ExternalSearch.VatLayer.Integration.Tests.csproj
index a0c9b8c..f0faed2 100644
--- a/test/integration/ExternalSearch.VatLayer.Integration.Tests/ExternalSearch.VatLayer.Integration.Tests.csproj
+++ b/test/integration/ExternalSearch.VatLayer.Integration.Tests/ExternalSearch.VatLayer.Integration.Tests.csproj
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file
diff --git a/test/unit/ExternalSearch.VatLayer.Unit.Tests/ExternalSearch.VatLayer.Unit.Tests.csproj b/test/unit/ExternalSearch.VatLayer.Unit.Tests/ExternalSearch.VatLayer.Unit.Tests.csproj
index dbb460c..3384491 100644
--- a/test/unit/ExternalSearch.VatLayer.Unit.Tests/ExternalSearch.VatLayer.Unit.Tests.csproj
+++ b/test/unit/ExternalSearch.VatLayer.Unit.Tests/ExternalSearch.VatLayer.Unit.Tests.csproj
@@ -1,7 +1,8 @@
-
-
+
+
+
+
-