diff --git a/Activities/Activities.Credentials.sln b/Activities/Activities.Credentials.sln index 2abd54d88..0afbf478b 100644 --- a/Activities/Activities.Credentials.sln +++ b/Activities/Activities.Credentials.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.12.35527.113 d17.12 +VisualStudioVersion = 17.12.35527.113 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.Credentials.Activities", "Credentials\UiPath.Credentials.Activities\UiPath.Credentials.Activities.csproj", "{ACB02213-A7C2-4BCA-ACE2-2BFAD6E0E54C}" EndProject @@ -46,4 +46,11 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AC55779-EA32-41AD-BAAD-1808F8A412CB} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared\UiPath.Shared.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + EndGlobalSection EndGlobal diff --git a/Activities/Activities.Cryptography.sln b/Activities/Activities.Cryptography.sln index 6591acb9a..2644f05ba 100644 --- a/Activities/Activities.Cryptography.sln +++ b/Activities/Activities.Cryptography.sln @@ -65,6 +65,9 @@ Global Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{4e20c041-2f59-408e-adb3-0bcfab48de61}*SharedItemsImports = 13 Shared\UiPath.Shared\UiPath.Shared.projitems*{92e8345e-2ca1-439d-926d-d979893840f5}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 EndGlobalSection EndGlobal diff --git a/Activities/Activities.Database.sln b/Activities/Activities.Database.sln index 38e88ba06..dab7a9c2e 100644 --- a/Activities/Activities.Database.sln +++ b/Activities/Activities.Database.sln @@ -32,6 +32,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Database", "Database", "{02 Database\Directory.build.targets = Database\Directory.build.targets EndProjectSection EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UiPath.Shared.Telemetry", "Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.shproj", "{58B0D9DA-673E-4E61-9497-FEA04E51A90E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -126,6 +128,8 @@ Global SolutionGuid = {5AC55779-EA32-41AD-BAAD-1808F8A412CB} EndGlobalSection GlobalSection(SharedMSBuildProjectFiles) = preSolution + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{58b0d9da-673e-4e61-9497-fea04e51a90e}*SharedItemsImports = 13 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{e6d45fa7-57a7-4136-99c6-6ee89851f4cd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{e6d45fa7-57a7-4136-99c6-6ee89851f4cd}*SharedItemsImports = 5 EndGlobalSection EndGlobal diff --git a/Activities/Community.Activities.sln b/Activities/Community.Activities.sln index c35477eb0..a0f1fa7f8 100644 --- a/Activities/Community.Activities.sln +++ b/Activities/Community.Activities.sln @@ -131,6 +131,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UiPath.Python.Activities.Vi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UiPath.Data.ConnectionUI.Dialog", "Database\ConnectionDialog\UiPath.Data.ConnectionUI.Dialog\UiPath.Data.ConnectionUI.Dialog.csproj", "{01A7C492-E038-B938-852C-F1016628D82A}" EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UiPath.Shared.Telemetry", "Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.shproj", "{58B0D9DA-673E-4E61-9497-FEA04E51A90E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -464,6 +466,7 @@ Global {D35ADF63-DD01-476A-8D15-CD3FB412AE5D} = {099CA148-FA0A-44E4-8C8A-CAF7B106897E} {456DBA80-878D-5C9E-BB00-185E99A39E89} = {913E6ED1-5915-4C4C-85BE-94E8CEE315FF} {01A7C492-E038-B938-852C-F1016628D82A} = {ED3DF9E3-2366-483E-9124-3FA8766EEF77} + {58B0D9DA-673E-4E61-9497-FEA04E51A90E} = {4B6FEFA2-F51E-4577-858E-320B8A094289} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {80E44DEF-976F-46BF-9DD8-F07334768E20} @@ -476,24 +479,42 @@ Global Shared\UiPath.Shared\UiPath.Shared.projitems*{2629567d-4737-4a1b-9876-f00c948270e3}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{2e040804-8ed9-4fb8-bb8a-4a38479e2a9e}*SharedItemsImports = 13 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{4e20c041-2f59-408e-adb3-0bcfab48de61}*SharedItemsImports = 13 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{58b0d9da-673e-4e61-9497-fea04e51a90e}*SharedItemsImports = 13 Shared\UiPath.Shared.Activities.Design\UiPath.Shared.Activities.Design.projitems*{5e102b9e-dcef-4d8b-8a02-3fdf0fcc0d59}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{7421a593-343b-4d49-afbe-a1b8be179ce2}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{7747a478-8986-4a56-8342-093752fc07c3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{7747a478-8986-4a56-8342-093752fc07c3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{7747a478-8986-4a56-8342-093752fc07c3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{7747a478-8986-4a56-8342-093752fc07c3}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{7747a478-8986-4a56-8342-093752fc07c3}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities.Design\UiPath.Shared.Activities.Design.projitems*{7fe013fd-58bd-4d0d-a9d0-be7849ca4e65}*SharedItemsImports = 13 Shared\UiPath.Shared\UiPath.Shared.projitems*{92e8345e-2ca1-439d-926d-d979893840f5}*SharedItemsImports = 5 Shared\UiPath.Shared.Service\UiPath.Shared.Service.projitems*{a1783eab-5baf-49f1-8372-b467b57063cc}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{a1783eab-5baf-49f1-8372-b467b57063cc}*SharedItemsImports = 5 Shared\UiPath.Shared.Service\UiPath.Shared.Service.projitems*{a6a27646-4889-4f95-a0df-dd78d287388f}*SharedItemsImports = 13 + Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 + Shared\UiPath.Shared\UiPath.Shared.projitems*{acb02213-a7c2-4bca-ace2-2bfad6e0e54c}*SharedItemsImports = 5 Python\UiPath.Python.Host.Shared\UiPath.Python.Host.Shared.projitems*{bcba78df-1513-44d3-83b3-37655a7f3887}*SharedItemsImports = 5 Shared\UiPath.Shared.Service\UiPath.Shared.Service.projitems*{bcba78df-1513-44d3-83b3-37655a7f3887}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{bcba78df-1513-44d3-83b3-37655a7f3887}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{e270608b-ba9e-4972-a18e-34b93e6552b4}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{e270608b-ba9e-4972-a18e-34b93e6552b4}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{e6d45fa7-57a7-4136-99c6-6ee89851f4cd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{e6d45fa7-57a7-4136-99c6-6ee89851f4cd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{e6d45fa7-57a7-4136-99c6-6ee89851f4cd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{e6d45fa7-57a7-4136-99c6-6ee89851f4cd}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{f6a198c8-1940-4cae-a0d3-d4e707f3b0a3}*SharedItemsImports = 5 Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts.Private\UiPath.Shared.Contracts.Private.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Contracts\UiPath.Shared.Contracts.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 + Shared\UiPath.Shared.Telemetry\UiPath.Shared.Telemetry.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 Shared\UiPath.Shared\UiPath.Shared.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 EndGlobalSection EndGlobal diff --git a/Activities/Credentials/UiPath.Credentials.Activities/AddCredential.cs b/Activities/Credentials/UiPath.Credentials.Activities/AddCredential.cs index 4d2c47e5d..13e44321e 100644 --- a/Activities/Credentials/UiPath.Credentials.Activities/AddCredential.cs +++ b/Activities/Credentials/UiPath.Credentials.Activities/AddCredential.cs @@ -1,13 +1,15 @@ using CredentialManagement; using System.Activities; -using System.ComponentModel; using System; using System.Activities.Validation; -using System.Diagnostics; -using System.IO; using UiPath.Credentials.Activities.Properties; using System.Security; using System.Net; +using UiPath.Shared.Activities; + +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Credentials.Activities { @@ -60,20 +62,41 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override bool Execute(CodeActivityContext context) { + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + SecureString passwordSecureString = PasswordSecureString.Get(context); string password = Password.Get(context); - if (string.IsNullOrWhiteSpace(password) && passwordSecureString == null) + telemetryOperation?.SetCustomDataKey(nameof(Password) + " IsUsed", !string.IsNullOrWhiteSpace(password)); + telemetryOperation?.SetCustomDataKey(nameof(PasswordSecureString) + " IsUsed", passwordSecureString != null); + telemetryOperation?.SetCustomDataKey(nameof(CredentialType), CredentialType.ToString() ?? null); + telemetryOperation?.SetCustomDataKey(nameof(PersistanceType), PersistanceType.ToString() ?? null); + + try { - throw new ArgumentNullException(Resources.PasswordAndSecureStringNull); + if (string.IsNullOrWhiteSpace(password) && passwordSecureString == null) + { + throw new ArgumentNullException(Resources.PasswordAndSecureStringNull); + } + if (password != null && passwordSecureString != null) + { + throw new ArgumentException(Resources.PasswordAndSecureStringNotNull); + } + + Credential credential = new Credential { Target = Target.Get(context), Username = Username.Get(context), Password = password != null ? password : new NetworkCredential("", passwordSecureString).Password, Type = CredentialType, PersistanceType = PersistanceType }; + + telemetryOperation?.Send(); + + return credential.Save(); } - if (password != null && passwordSecureString != null) + catch (Exception ex) { - throw new ArgumentException(Resources.PasswordAndSecureStringNotNull); + telemetryOperation?.SendWithException(ex); + throw; } - - Credential credential = new Credential { Target = Target.Get(context), Username = Username.Get(context), Password = password != null ? password : new NetworkCredential("", passwordSecureString).Password, Type = CredentialType, PersistanceType = PersistanceType }; - return credential.Save(); } } } diff --git a/Activities/Credentials/UiPath.Credentials.Activities/DeleteCredential.cs b/Activities/Credentials/UiPath.Credentials.Activities/DeleteCredential.cs index 6fc7cf66d..6fb2e5b44 100644 --- a/Activities/Credentials/UiPath.Credentials.Activities/DeleteCredential.cs +++ b/Activities/Credentials/UiPath.Credentials.Activities/DeleteCredential.cs @@ -1,7 +1,12 @@ using CredentialManagement; +using System; using System.Activities; -using System.ComponentModel; using UiPath.Credentials.Activities.Properties; +using UiPath.Shared.Activities; + +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Credentials.Activities { @@ -15,8 +20,24 @@ public class DeleteCredential : CodeActivity protected override bool Execute(CodeActivityContext context) { - Credential credential = new Credential { Target = Target.Get(context) }; - return credential.Delete(); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + + try + { + Credential credential = new Credential { Target = Target.Get(context) }; + + telemetryOperation?.Send(); + + return credential.Delete(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/Credentials/UiPath.Credentials.Activities/GetCredential.cs b/Activities/Credentials/UiPath.Credentials.Activities/GetCredential.cs index 61fb40157..e9f6bd75e 100644 --- a/Activities/Credentials/UiPath.Credentials.Activities/GetCredential.cs +++ b/Activities/Credentials/UiPath.Credentials.Activities/GetCredential.cs @@ -1,7 +1,13 @@ using CredentialManagement; +using System; using System.Activities; using System.ComponentModel; using UiPath.Credentials.Activities.Properties; +using UiPath.Shared.Activities; + +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Credentials.Activities { @@ -42,12 +48,30 @@ public GetCredential() protected override bool Execute(CodeActivityContext context) { - Credential credential = new Credential { Target = Target.Get(context), Type = CredentialType, PersistanceType = PersistanceType }; - var result = credential.Load(); - if (!result) return false; - Username.Set(context, credential.Username); - Password.Set(context, credential.Password); - return true; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try + { + telemetryOperation?.SetCustomDataKey(nameof(CredentialType), CredentialType.ToString() ?? null); + telemetryOperation?.SetCustomDataKey(nameof(PersistanceType), PersistanceType.ToString() ?? null); + + Credential credential = new Credential { Target = Target.Get(context), Type = CredentialType, PersistanceType = PersistanceType }; + var result = credential.Load(); + if (!result) return false; + Username.Set(context, credential.Username); + Password.Set(context, credential.Password); + + telemetryOperation?.Send(); + + return true; + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/Credentials/UiPath.Credentials.Activities/GetSecureCredential.cs b/Activities/Credentials/UiPath.Credentials.Activities/GetSecureCredential.cs index 4abd27258..65d87d995 100644 --- a/Activities/Credentials/UiPath.Credentials.Activities/GetSecureCredential.cs +++ b/Activities/Credentials/UiPath.Credentials.Activities/GetSecureCredential.cs @@ -1,8 +1,13 @@ using CredentialManagement; +using System; using System.Activities; -using System.ComponentModel; using System.Security; using UiPath.Credentials.Activities.Properties; +using UiPath.Shared.Activities; + +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Credentials.Activities { @@ -42,12 +47,35 @@ public GetSecureCredential() protected override bool Execute(CodeActivityContext context) { - Credential credential = new Credential { Target = Target.Get(context), Type = CredentialType, PersistanceType = PersistanceType }; - var result = credential.Load(); - if (!result) return false; - Username.Set(context, credential.Username); - Password.Set(context, credential.SecurePassword); - return true; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + + try + { + telemetryOperation?.SetCustomDataKey(nameof(CredentialType), CredentialType.ToString() ?? null); + telemetryOperation?.SetCustomDataKey(nameof(PersistanceType), PersistanceType.ToString() ?? null); + + Credential credential = new Credential { Target = Target.Get(context), Type = CredentialType, PersistanceType = PersistanceType }; + var result = credential.Load(); + if (!result) + { + telemetryOperation?.Send(); + return false; + } + Username.Set(context, credential.Username); + Password.Set(context, credential.SecurePassword); + + telemetryOperation?.Send(); + + return true; + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } } } \ No newline at end of file diff --git a/Activities/Credentials/UiPath.Credentials.Activities/RequestCredential.cs b/Activities/Credentials/UiPath.Credentials.Activities/RequestCredential.cs index c5b85389d..5d2c2d9e1 100644 --- a/Activities/Credentials/UiPath.Credentials.Activities/RequestCredential.cs +++ b/Activities/Credentials/UiPath.Credentials.Activities/RequestCredential.cs @@ -1,9 +1,13 @@ using CredentialManagement; using System.Activities; -using System.ComponentModel; using System.Net; using System.Security; using UiPath.Credentials.Activities.Properties; +using UiPath.Shared.Activities; + +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Credentials.Activities { @@ -37,29 +41,50 @@ public class RequestCredential : CodeActivity protected override bool Execute(CodeActivityContext context) { - var credPrompt = new VistaPrompt - { - GenericCredentials = true - }; - var message = Message.Get(context); - if (message != null) - { - credPrompt.Message = message; - } + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif - var title = Title.Get(context); - if (title != null) + try { - credPrompt.Title = title; - } + var credPrompt = new VistaPrompt + { + GenericCredentials = true + }; + var message = Message.Get(context); + if (message != null) + { + credPrompt.Message = message; + } + + var title = Title.Get(context); + if (title != null) + { + credPrompt.Title = title; + } - var res = credPrompt.ShowDialog(); - if (res != DialogResult.OK) return false; + telemetryOperation?.SetCustomDataKey(nameof(Message) + " IsUsed", message != null); + telemetryOperation?.SetCustomDataKey(nameof(Message) + " Length", message != null ? message.Length : 0); + telemetryOperation?.SetCustomDataKey(nameof(Title) + " IsUsed", title != null); + telemetryOperation?.SetCustomDataKey(nameof(Title) + " Length", title != null ? title.Length : 0); - Username.Set(context, credPrompt.Username); - Password.Set(context, credPrompt.Password); - PasswordSecureString.Set(context, (new NetworkCredential("", credPrompt.Password).SecurePassword)); - return true; + var res = credPrompt.ShowDialog(); + if (res != DialogResult.OK) return false; + + Username.Set(context, credPrompt.Username); + Password.Set(context, credPrompt.Password); + PasswordSecureString.Set(context, (new NetworkCredential("", credPrompt.Password).SecurePassword)); + + telemetryOperation?.Send(); + + return true; + } + catch (System.Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/Credentials/UiPath.Credentials.Activities/UiPath.Credentials.Activities.csproj b/Activities/Credentials/UiPath.Credentials.Activities/UiPath.Credentials.Activities.csproj index 8068f8fef..b4ae54651 100644 --- a/Activities/Credentials/UiPath.Credentials.Activities/UiPath.Credentials.Activities.csproj +++ b/Activities/Credentials/UiPath.Credentials.Activities/UiPath.Credentials.Activities.csproj @@ -12,8 +12,12 @@ - + + + + + @@ -42,4 +46,16 @@ UiPath.Credentials.Activities.Designer.cs + + + + + + + + + + + + diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/DecryptFileTests.cs b/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/DecryptFileTests.cs index eaafbc911..103fc7100 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/DecryptFileTests.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/DecryptFileTests.cs @@ -3,6 +3,7 @@ using System.Activities; using System.Security; using Xunit; +using UiPath.Platform; namespace UiPath.Cryptography.Activities.Tests { diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/UiPath.Cryptography.Activities.Tests.csproj b/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/UiPath.Cryptography.Activities.Tests.csproj index c9fede53d..e42604aa7 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/UiPath.Cryptography.Activities.Tests.csproj +++ b/Activities/Cryptography/UiPath.Cryptography.Activities.Tests/UiPath.Cryptography.Activities.Tests.csproj @@ -13,6 +13,10 @@ + + + + diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptFile.cs b/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptFile.cs index 4a6ba6382..4d9c26b4e 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptFile.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptFile.cs @@ -13,6 +13,10 @@ using UiPath.Cryptography.Activities.Properties; using UiPath.Cryptography.Enums; using UiPath.Platform.ResourceHandling; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif #pragma warning disable CS0618 // obsolete encryption algorithm @@ -142,25 +146,31 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override void Execute(CodeActivityContext context) { + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - var inputFilePath = InputFilePath.Get(context); - var inputFile = InputFile.Get(context); - var outputFilePath = OutputFilePath.Get(context); - var outputFileName = OutputFileName.Get(context); - var key = Key.Get(context); - var keySecureString = KeySecureString.Get(context); - var keyEncoding = KeyEncoding.Get(context); - var keyEncodingString = KeyEncodingString.Get(context); -#if NET - if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) - { - throw new ArgumentNullException(Resources.Activity_DecryptFile_Property_Key_Name); - } - if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + try { - throw new ArgumentNullException(Resources.Activity_DecryptFile_Property_KeySecureString_Name); - } + var inputFilePath = InputFilePath.Get(context); + var inputFile = InputFile.Get(context); + var outputFilePath = OutputFilePath.Get(context); + var outputFileName = OutputFileName.Get(context); + var key = Key.Get(context); + var keySecureString = KeySecureString.Get(context); + var keyEncoding = KeyEncoding.Get(context); + var keyEncodingString = KeyEncodingString.Get(context); +#if NET + if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) + { + throw new ArgumentNullException(Resources.Activity_DecryptFile_Property_Key_Name); + } + if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + { + throw new ArgumentNullException(Resources.Activity_DecryptFile_Property_KeySecureString_Name); + } #endif #if NET461 @@ -169,68 +179,75 @@ protected override void Execute(CodeActivityContext context) throw new ArgumentNullException(Resources.KeyAndSecureStringNull); } #endif - if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) throw new ArgumentNullException(Resources.Encoding); + if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) throw new ArgumentNullException(Resources.Encoding); - if (!File.Exists(inputFilePath) && inputFile == null) - throw new ArgumentException(Resources.FileDoesNotExistsException, Resources.InputFilePathDisplayName); + if (!File.Exists(inputFilePath) && inputFile == null) + throw new ArgumentException(Resources.FileDoesNotExistsException, Resources.InputFilePathDisplayName); - // Because we use File.WriteAllText below, we don't need to delete the file now. - if (File.Exists(outputFilePath) && !Overwrite) - throw new ArgumentException(Resources.FileAlreadyExistsException, Resources.OutputFilePathDisplayName); + // Because we use File.WriteAllText below, we don't need to delete the file now. + if (File.Exists(outputFilePath) && !Overwrite) + throw new ArgumentException(Resources.FileAlreadyExistsException, Resources.OutputFilePathDisplayName); - if (inputFile != null && inputFile.IsFolder) - throw new ArgumentException(Resources.Exception_UseOnlyFilesNotFolders); + if (inputFile != null && inputFile.IsFolder) + throw new ArgumentException(Resources.Exception_UseOnlyFilesNotFolders); - var result = FilePathHelpers.GetDefaultFileNameAndLocation(inputFile, inputFilePath, outputFileName, Overwrite, outputFilePath, Decrypted); + var result = FilePathHelpers.GetDefaultFileNameAndLocation(inputFile, inputFilePath, outputFileName, Overwrite, outputFilePath, Decrypted); - keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); + keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); - var encrypted = File.ReadAllBytes(result.Item3); + var encrypted = File.ReadAllBytes(result.Item3); - byte[] decrypted = null; - try - { - decrypted = CryptographyHelper.DecryptData(Algorithm, encrypted, CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); - } - catch (CryptographicException ex) - { - throw new InvalidOperationException(Resources.GenericCryptographicException, ex); - } + byte[] decrypted = null; + try + { + decrypted = CryptographyHelper.DecryptData(Algorithm, encrypted, CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); + } + catch (CryptographicException ex) + { + throw new InvalidOperationException(Resources.GenericCryptographicException, ex); + } - if (string.IsNullOrEmpty(outputFilePath)) - { - var item = new CryptographyLocalItem(decrypted, result.Item1, result.Item2); + if (string.IsNullOrEmpty(outputFilePath)) + { + var item = new CryptographyLocalItem(decrypted, result.Item1, result.Item2); + + DecryptedFile.Set(context, item); + + outputFilePath = item.LocalPath; + } + else + { + var directory = Path.GetDirectoryName(outputFilePath); + + if (!string.IsNullOrEmpty(directory)) + { + Directory.CreateDirectory(directory); + } - DecryptedFile.Set(context, item); + var item = new CryptographyLocalItem(decrypted, Path.GetFileName(outputFilePath), outputFilePath); - outputFilePath = item.LocalPath; + DecryptedFile.Set(context, item); + } + + // This overwrites the file if it already exists. + File.WriteAllBytes(outputFilePath, decrypted); + telemetryOperation?.Send(); } - else + catch (Exception ex) { - var directory = Path.GetDirectoryName(outputFilePath); + telemetryOperation?.SendWithException(ex); + Trace.TraceError(ex.ToString()); - if (!string.IsNullOrEmpty(directory)) + if (!ContinueOnError.Get(context)) { - Directory.CreateDirectory(directory); + throw; } - - var item = new CryptographyLocalItem(decrypted, Path.GetFileName(outputFilePath), outputFilePath); - - DecryptedFile.Set(context, item); } - - // This overwrites the file if it already exists. - File.WriteAllBytes(outputFilePath, decrypted); - } catch (Exception ex) { - Trace.TraceError(ex.ToString()); - - if (!ContinueOnError.Get(context)) - { - throw; - } + telemetryOperation?.SendWithException(ex); + throw; } } } diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptText.cs b/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptText.cs index 9dd178cab..b696a8fc6 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptText.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/DecryptText.cs @@ -10,6 +10,10 @@ using UiPath.Cryptography.Activities.Helpers; using UiPath.Cryptography.Activities.Properties; using UiPath.Cryptography.Enums; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif #pragma warning disable CS0618 // obsolete encryption algorithm @@ -111,27 +115,33 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override string Execute(CodeActivityContext context) { - string result = null; - + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - var input = Input.Get(context); - var key = Key.Get(context); - var keySecureString = KeySecureString.Get(context); - var keyEncoding = Encoding.Get(context); - var keyEncodingString = KeyEncodingString.Get(context); - - if (string.IsNullOrWhiteSpace(input)) - throw new ArgumentNullException(Resources.InputStringDisplayName); -#if NET - if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) - { - throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_Key_Name); - } - if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + string result = null; + + try { - throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_KeySecureString_Name); - } + var input = Input.Get(context); + var key = Key.Get(context); + var keySecureString = KeySecureString.Get(context); + var keyEncoding = Encoding.Get(context); + var keyEncodingString = KeyEncodingString.Get(context); + + if (string.IsNullOrWhiteSpace(input)) + throw new ArgumentNullException(Resources.InputStringDisplayName); +#if NET + if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) + { + throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_Key_Name); + } + if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + { + throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_KeySecureString_Name); + } #endif #if NET461 @@ -140,34 +150,41 @@ protected override string Execute(CodeActivityContext context) throw new ArgumentNullException(Resources.KeyAndSecureStringNull); } #endif - if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) - throw new ArgumentNullException(Resources.Encoding); - - keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); - - byte[] decrypted = null; - try - { - decrypted = CryptographyHelper.DecryptData(Algorithm, Convert.FromBase64String(input), CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); + if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) + throw new ArgumentNullException(Resources.Encoding); + + keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); + + byte[] decrypted = null; + try + { + decrypted = CryptographyHelper.DecryptData(Algorithm, Convert.FromBase64String(input), CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); + } + catch (CryptographicException ex) + { + throw new InvalidOperationException(Resources.GenericCryptographicException, ex); + } + + result = keyEncoding.GetString(decrypted); + telemetryOperation?.Send(); } - catch (CryptographicException ex) + catch (Exception ex) { - throw new InvalidOperationException(Resources.GenericCryptographicException, ex); - } + telemetryOperation?.SendWithException(ex); + Trace.TraceError(ex.ToString()); - result = keyEncoding.GetString(decrypted); + if (!ContinueOnError.Get(context)) + { + throw; + } + } + return result; } catch (Exception ex) { - Trace.TraceError(ex.ToString()); - - if (!ContinueOnError.Get(context)) - { - throw; - } + telemetryOperation?.SendWithException(ex); + throw; } - - return result; } } } \ No newline at end of file diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptFile.cs b/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptFile.cs index 08935f5ac..1e7fea861 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptFile.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptFile.cs @@ -12,6 +12,10 @@ using UiPath.Cryptography.Activities.Properties; using UiPath.Cryptography.Enums; using UiPath.Platform.ResourceHandling; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif #pragma warning disable CS0618 // obsolete encryption algorithm @@ -142,25 +146,31 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override void Execute(CodeActivityContext context) { + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - var inputFilePath = InputFilePath.Get(context); - var inputFile = InputFile.Get(context); - var outputFilePath = OutputFilePath.Get(context); - var outputFileName = OutputFileName.Get(context); - var key = Key.Get(context); - var keySecureString = KeySecureString.Get(context); - var keyEncoding = KeyEncoding.Get(context); - var keyEncodingString = KeyEncodingString.Get(context); -#if NET - if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) + try { - throw new ArgumentNullException(Resources.Activity_EncryptFile_Property_Key_Name); - } - if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) - { - throw new ArgumentNullException(Resources.Activity_EncryptFile_Property_KeySecureString_Name); - } + var inputFilePath = InputFilePath.Get(context); + var inputFile = InputFile.Get(context); + var outputFilePath = OutputFilePath.Get(context); + var outputFileName = OutputFileName.Get(context); + var key = Key.Get(context); + var keySecureString = KeySecureString.Get(context); + var keyEncoding = KeyEncoding.Get(context); + var keyEncodingString = KeyEncodingString.Get(context); +#if NET + if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) + { + throw new ArgumentNullException(Resources.Activity_EncryptFile_Property_Key_Name); + } + if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + { + throw new ArgumentNullException(Resources.Activity_EncryptFile_Property_KeySecureString_Name); + } #endif #if NET461 @@ -169,57 +179,64 @@ protected override void Execute(CodeActivityContext context) throw new ArgumentNullException(Resources.KeyAndSecureStringNull); } #endif - if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) throw new ArgumentNullException(Resources.Encoding); - - if (!File.Exists(inputFilePath) && inputFile == null) - throw new ArgumentException(Resources.FileDoesNotExistsException, - Resources.InputFilePathDisplayName); + if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) throw new ArgumentNullException(Resources.Encoding); - // Because we use File.WriteAllText below, we don't need to delete the file now. - if (File.Exists(outputFilePath) && !Overwrite) - throw new ArgumentException(Resources.FileAlreadyExistsException, - Resources.OutputFilePathDisplayName); + if (!File.Exists(inputFilePath) && inputFile == null) + throw new ArgumentException(Resources.FileDoesNotExistsException, + Resources.InputFilePathDisplayName); - if (inputFile != null && inputFile.IsFolder) - throw new ArgumentException(Resources.Exception_UseOnlyFilesNotFolders); + // Because we use File.WriteAllText below, we don't need to delete the file now. + if (File.Exists(outputFilePath) && !Overwrite) + throw new ArgumentException(Resources.FileAlreadyExistsException, + Resources.OutputFilePathDisplayName); - var result = FilePathHelpers.GetDefaultFileNameAndLocation(inputFile, inputFilePath, outputFileName, Overwrite, outputFilePath, Encrypted); + if (inputFile != null && inputFile.IsFolder) + throw new ArgumentException(Resources.Exception_UseOnlyFilesNotFolders); - keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); + var result = FilePathHelpers.GetDefaultFileNameAndLocation(inputFile, inputFilePath, outputFileName, Overwrite, outputFilePath, Encrypted); - var encrypted = CryptographyHelper.EncryptData(Algorithm, File.ReadAllBytes(result.Item3), - CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); + keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); - if (string.IsNullOrEmpty(outputFilePath)) - { - var item = new CryptographyLocalItem(encrypted, result.Item1, result.Item2); + var encrypted = CryptographyHelper.EncryptData(Algorithm, File.ReadAllBytes(result.Item3), + CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); - EncryptedFile.Set(context, item); + if (string.IsNullOrEmpty(outputFilePath)) + { + var item = new CryptographyLocalItem(encrypted, result.Item1, result.Item2); - outputFilePath = item.LocalPath; - } - else - { - var directory = Path.GetDirectoryName(outputFilePath); + EncryptedFile.Set(context, item); - if (!string.IsNullOrEmpty(directory)) - { - Directory.CreateDirectory(directory); + outputFilePath = item.LocalPath; } + else + { + var directory = Path.GetDirectoryName(outputFilePath); - var item = new CryptographyLocalItem(encrypted, Path.GetFileName(outputFilePath), outputFilePath); + if (!string.IsNullOrEmpty(directory)) + { + Directory.CreateDirectory(directory); + } - EncryptedFile.Set(context, item); - } + var item = new CryptographyLocalItem(encrypted, Path.GetFileName(outputFilePath), outputFilePath); - // This overwrites the file if it already exists. - File.WriteAllBytes(outputFilePath, encrypted); + EncryptedFile.Set(context, item); + } + + // This overwrites the file if it already exists. + File.WriteAllBytes(outputFilePath, encrypted); + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + Trace.TraceError(ex.ToString()); + if (!ContinueOnError.Get(context)) throw; + } } catch (Exception ex) { - Trace.TraceError(ex.ToString()); - - if (!ContinueOnError.Get(context)) throw; + telemetryOperation?.SendWithException(ex); + throw; } } } diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptText.cs b/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptText.cs index a999a2ce2..f3bff65bf 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptText.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/EncryptText.cs @@ -9,6 +9,10 @@ using UiPath.Cryptography.Activities.Helpers; using UiPath.Cryptography.Activities.Properties; using UiPath.Cryptography.Enums; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif #pragma warning disable CS0618 // obsolete encryption algorithm @@ -111,27 +115,33 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override string Execute(CodeActivityContext context) { - string result = null; - + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - var input = Input.Get(context); - var key = Key.Get(context); - var keySecureString = KeySecureString.Get(context); - var keyEncoding = Encoding.Get(context); - var keyEncodingString = KeyEncodingString.Get(context); - - if (string.IsNullOrWhiteSpace(input)) - throw new ArgumentNullException(Resources.InputStringDisplayName); -#if NET - if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) - { - throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_Key_Name); - } - if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + string result = null; + + try { - throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_KeySecureString_Name); - } + var input = Input.Get(context); + var key = Key.Get(context); + var keySecureString = KeySecureString.Get(context); + var keyEncoding = Encoding.Get(context); + var keyEncodingString = KeyEncodingString.Get(context); + + if (string.IsNullOrWhiteSpace(input)) + throw new ArgumentNullException(Resources.InputStringDisplayName); +#if NET + if (string.IsNullOrWhiteSpace(key) && KeyInputModeSwitch == KeyInputMode.Key) + { + throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_Key_Name); + } + if ((keySecureString == null || keySecureString?.Length == 0) && KeyInputModeSwitch == KeyInputMode.SecureKey) + { + throw new ArgumentNullException(Resources.Activity_KeyedHashText_Property_KeySecureString_Name); + } #endif #if NET461 @@ -140,25 +150,31 @@ protected override string Execute(CodeActivityContext context) throw new ArgumentNullException(Resources.KeyAndSecureStringNull); } #endif - if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) throw new ArgumentNullException(Resources.Encoding); + if (keyEncoding == null && string.IsNullOrEmpty(keyEncodingString)) throw new ArgumentNullException(Resources.Encoding); - keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); + keyEncoding = EncodingHelpers.KeyEncodingOrString(keyEncoding, keyEncodingString); - var encrypted = CryptographyHelper.EncryptData(Algorithm, keyEncoding.GetBytes(input), CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); + var encrypted = CryptographyHelper.EncryptData(Algorithm, keyEncoding.GetBytes(input), CryptographyHelper.KeyEncoding(keyEncoding, key, keySecureString)); - result = Convert.ToBase64String(encrypted); + result = Convert.ToBase64String(encrypted); + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + Trace.TraceError(ex.ToString()); + if (!ContinueOnError.Get(context)) + { + throw; + } + } + return result; } catch (Exception ex) { - Trace.TraceError(ex.ToString()); - - if (!ContinueOnError.Get(context)) - { - throw; - } + telemetryOperation?.SendWithException(ex); + throw; } - - return result; } } } \ No newline at end of file diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/HashFile.cs b/Activities/Cryptography/UiPath.Cryptography.Activities/HashFile.cs index 1232b39a9..d81c0319b 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/HashFile.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/HashFile.cs @@ -5,6 +5,10 @@ using System.Diagnostics; using System.IO; using UiPath.Cryptography.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Cryptography.Activities { @@ -54,33 +58,46 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override string Execute(CodeActivityContext context) { - string result = null; - + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - var filePath = FilePath.Get(context); - - if (string.IsNullOrWhiteSpace(filePath)) - throw new ArgumentNullException(Resources.FilePathDisplayName); - - if (!File.Exists(filePath)) - throw new ArgumentException(Resources.FileDoesNotExistsException, Resources.FilePathDisplayName); - - var hashed = CryptographyHelper.HashData(Algorithm, File.ReadAllBytes(filePath)); - - result = BitConverter.ToString(hashed).Replace("-", string.Empty); - } - catch (Exception ex) - { - Trace.TraceError(ex.ToString()); + string result = null; - if (!ContinueOnError.Get(context)) + try + { + var filePath = FilePath.Get(context); + + if (string.IsNullOrWhiteSpace(filePath)) + throw new ArgumentNullException(Resources.FilePathDisplayName); + + if (!File.Exists(filePath)) + throw new ArgumentException(Resources.FileDoesNotExistsException, Resources.FilePathDisplayName); + + var hashed = CryptographyHelper.HashData(Algorithm, File.ReadAllBytes(filePath)); + + result = BitConverter.ToString(hashed).Replace("-", string.Empty); + telemetryOperation?.Send(); + } + catch (Exception ex) { - throw; + telemetryOperation?.SendWithException(ex); + Trace.TraceError(ex.ToString()); + + if (!ContinueOnError.Get(context)) + { + throw; + } } + return result; + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; } - - return result; } } #endif diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/HashText.cs b/Activities/Cryptography/UiPath.Cryptography.Activities/HashText.cs index b39b9cb5c..b5d9391e7 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/HashText.cs +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/HashText.cs @@ -6,6 +6,10 @@ using System.Diagnostics; using System.Text; using UiPath.Cryptography.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Cryptography.Activities { @@ -68,34 +72,47 @@ protected override void CacheMetadata(CodeActivityMetadata metadata) protected override string Execute(CodeActivityContext context) { - string result = null; - + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - var input = Input.Get(context); - var encoding = Encoding.Get(context); - - if (string.IsNullOrWhiteSpace(input)) - throw new ArgumentNullException(Resources.InputStringDisplayName); - - if (encoding == null) - throw new ArgumentNullException(Resources.Encoding); - - var hashed = CryptographyHelper.HashData(Algorithm, encoding.GetBytes(input)); + string result = null; - result = BitConverter.ToString(hashed).Replace("-", string.Empty); - } + try + { + var input = Input.Get(context); + var encoding = Encoding.Get(context); + + if (string.IsNullOrWhiteSpace(input)) + throw new ArgumentNullException(Resources.InputStringDisplayName); + + if (encoding == null) + throw new ArgumentNullException(Resources.Encoding); + + var hashed = CryptographyHelper.HashData(Algorithm, encoding.GetBytes(input)); + + result = BitConverter.ToString(hashed).Replace("-", string.Empty); + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + Trace.TraceError(ex.ToString()); + + if (!ContinueOnError.Get(context)) + { + throw; + } + } + return result; + } catch (Exception ex) { - Trace.TraceError(ex.ToString()); - - if (!ContinueOnError.Get(context)) - { - throw; - } + telemetryOperation?.SendWithException(ex); + throw; } - - return result; } } #endif diff --git a/Activities/Cryptography/UiPath.Cryptography.Activities/UiPath.Cryptography.Activities.csproj b/Activities/Cryptography/UiPath.Cryptography.Activities/UiPath.Cryptography.Activities.csproj index 73a3e9437..95dab6868 100644 --- a/Activities/Cryptography/UiPath.Cryptography.Activities/UiPath.Cryptography.Activities.csproj +++ b/Activities/Cryptography/UiPath.Cryptography.Activities/UiPath.Cryptography.Activities.csproj @@ -6,10 +6,14 @@ ..\..\Output\Activities\Cryptography\ + + + + @@ -57,4 +61,7 @@ + + + \ No newline at end of file diff --git a/Activities/Database/Directory.build.props b/Activities/Database/Directory.build.props index 32a23d29c..24f86f7c6 100644 --- a/Activities/Database/Directory.build.props +++ b/Activities/Database/Directory.build.props @@ -13,6 +13,7 @@ 2.1.$(VersionBuild)-dev.$(VersionRevision) 2.1.$(VersionBuild).$(VersionRevision) $(MSBuildThisFileDirectory) + $(DefineConstants);ENABLE_DEFAULT_TELEMETRY false diff --git a/Activities/Database/Directory.build.targets b/Activities/Database/Directory.build.targets index 35c258e7d..a448783f7 100644 --- a/Activities/Database/Directory.build.targets +++ b/Activities/Database/Directory.build.targets @@ -10,6 +10,12 @@ + + + + + + \ No newline at end of file diff --git a/Activities/Database/UiPath.Database.Activities/BulkInsert.cs b/Activities/Database/UiPath.Database.Activities/BulkInsert.cs index df4020446..0ec61af08 100644 --- a/Activities/Database/UiPath.Database.Activities/BulkInsert.cs +++ b/Activities/Database/UiPath.Database.Activities/BulkInsert.cs @@ -8,6 +8,10 @@ using System.Threading.Tasks; using UiPath.Database.Activities.Properties; using UiPath.Robot.Activities.Api; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -37,56 +41,70 @@ public partial class BulkInsert : DatabaseRowActivity protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - DataTable dataTable = null; - SecureString connSecureString = null; - string connString = null; - string provName = null; - string tableName = null; - DatabaseConnection existingConnection = null; - long affectedRecords = 0; - IExecutorRuntime executorRuntime = null; - var continueOnError = ContinueOnError.Get(context); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - existingConnection = DbConnection = ExistingDbConnection.Get(context); - connString = ConnectionString.Get(context); - provName = ProviderName.Get(context); - tableName = TableName.Get(context); - dataTable = DataTable.Get(context); - executorRuntime = context.GetExtension(); - connSecureString = ConnectionSecureString.Get(context); - ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); - // create the action for doing the actual work - affectedRecords = await Task.Run(() => - { - DbConnection = DbConnection ?? new DatabaseConnection().Initialize(connString ?? new NetworkCredential("", connSecureString).Password, provName); - if (DbConnection == null) + DataTable dataTable = null; + SecureString connSecureString = null; + string connString = null; + string provName = null; + string tableName = null; + DatabaseConnection existingConnection = null; + long affectedRecords = 0; + IExecutorRuntime executorRuntime = null; + var continueOnError = ContinueOnError.Get(context); + try { - return 0; - } - if (executorRuntime != null && executorRuntime.HasFeature(ExecutorFeatureKeys.LogMessage)) - return DbConnection.BulkInsertDataTable(tableName, dataTable, executorRuntime); - else - return DbConnection.BulkInsertDataTable(tableName, dataTable); - }); + existingConnection = DbConnection = ExistingDbConnection.Get(context); + connString = ConnectionString.Get(context); + provName = ProviderName.Get(context); + tableName = TableName.Get(context); + dataTable = DataTable.Get(context); + executorRuntime = context.GetExtension(); + connSecureString = ConnectionSecureString.Get(context); + ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); + // create the action for doing the actual work + affectedRecords = await Task.Run(() => + { + DbConnection = DbConnection ?? new DatabaseConnection().Initialize(connString ?? new NetworkCredential("", connSecureString).Password, provName); + if (DbConnection == null) + { + return 0; + } + if (executorRuntime != null && executorRuntime.HasFeature(ExecutorFeatureKeys.LogMessage)) + return DbConnection.BulkInsertDataTable(tableName, dataTable, executorRuntime); + else + return DbConnection.BulkInsertDataTable(tableName, dataTable); - } - catch (Exception ex) - { - HandleException(ex, continueOnError); - } - finally - { - if (existingConnection == null) + }); + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + HandleException(ex, continueOnError); + } + finally { - DbConnection?.Dispose(); + if (existingConnection == null) + { + DbConnection?.Dispose(); + } } + var result = new Action(asyncCodeActivityContext => + { + AffectedRecords.Set(asyncCodeActivityContext, affectedRecords); + }); + return result; } - - return asyncCodeActivityContext => + catch (Exception ex) { - AffectedRecords.Set(asyncCodeActivityContext, affectedRecords); - }; + telemetryOperation?.SendWithException(ex); + throw; + } } } } \ No newline at end of file diff --git a/Activities/Database/UiPath.Database.Activities/BulkUpdate.cs b/Activities/Database/UiPath.Database.Activities/BulkUpdate.cs index 4fea114a7..28ea1eebd 100644 --- a/Activities/Database/UiPath.Database.Activities/BulkUpdate.cs +++ b/Activities/Database/UiPath.Database.Activities/BulkUpdate.cs @@ -8,6 +8,10 @@ using System.Threading.Tasks; using UiPath.Database.Activities.Properties; using UiPath.Robot.Activities.Api; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -50,57 +54,72 @@ public partial class BulkUpdate : DatabaseRowActivity protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - DataTable dataTable = null; - string connString = null; - SecureString connSecureString = null; - string provName = null; - string tableName = null; - string[] columnNames = null; - DatabaseConnection existingConnection = null; - long affectedRecords = 0; - IExecutorRuntime executorRuntime = null; - var continueOnError = ContinueOnError.Get(context); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - existingConnection = DbConnection = ExistingDbConnection.Get(context); - connString = ConnectionString.Get(context); - provName = ProviderName.Get(context); - tableName = TableName.Get(context); - dataTable = DataTable.Get(context); - columnNames = ColumnNames.Get(context); - executorRuntime = context.GetExtension(); - connSecureString = ConnectionSecureString.Get(context); - ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); - affectedRecords = await Task.Run(() => + DataTable dataTable = null; + string connString = null; + SecureString connSecureString = null; + string provName = null; + string tableName = null; + string[] columnNames = null; + DatabaseConnection existingConnection = null; + long affectedRecords = 0; + IExecutorRuntime executorRuntime = null; + var continueOnError = ContinueOnError.Get(context); + try { - DbConnection = DbConnection ?? new DatabaseConnection().Initialize(connString != null ? connString : new NetworkCredential("", connSecureString).Password, provName); - if (DbConnection == null) + existingConnection = DbConnection = ExistingDbConnection.Get(context); + connString = ConnectionString.Get(context); + provName = ProviderName.Get(context); + tableName = TableName.Get(context); + dataTable = DataTable.Get(context); + columnNames = ColumnNames.Get(context); + executorRuntime = context.GetExtension(); + connSecureString = ConnectionSecureString.Get(context); + ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); + affectedRecords = await Task.Run(() => { - return 0; + DbConnection = DbConnection ?? new DatabaseConnection().Initialize(connString != null ? connString : new NetworkCredential("", connSecureString).Password, provName); + if (DbConnection == null) + { + return 0; + } + if (executorRuntime != null && executorRuntime.HasFeature(ExecutorFeatureKeys.LogMessage)) + return DbConnection.BulkUpdateDataTable(BulkUpdateFlag, tableName, dataTable, columnNames, executorRuntime); + else + return DbConnection.BulkUpdateDataTable(BulkUpdateFlag, tableName, dataTable, columnNames); + }); + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + HandleException(ex, continueOnError); + } + finally + { + if (existingConnection == null) + { + DbConnection?.Dispose(); } - if (executorRuntime != null && executorRuntime.HasFeature(ExecutorFeatureKeys.LogMessage)) - return DbConnection.BulkUpdateDataTable(BulkUpdateFlag, tableName, dataTable, columnNames, executorRuntime); - else - return DbConnection.BulkUpdateDataTable(BulkUpdateFlag, tableName, dataTable, columnNames); - }); + } + var result = new Action(asyncCodeActivityContext => + { + AffectedRecords.Set(asyncCodeActivityContext, affectedRecords); + }); + + return result; } catch (Exception ex) { - HandleException(ex, continueOnError); + telemetryOperation?.SendWithException(ex); + throw; } - finally - { - if (existingConnection == null) - { - DbConnection?.Dispose(); - } - } - - return asyncCodeActivityContext => - { - AffectedRecords.Set(asyncCodeActivityContext, affectedRecords); - }; } } } diff --git a/Activities/Database/UiPath.Database.Activities/DatabaseConnect.cs b/Activities/Database/UiPath.Database.Activities/DatabaseConnect.cs index 45a1e90cb..8e85e450a 100644 --- a/Activities/Database/UiPath.Database.Activities/DatabaseConnect.cs +++ b/Activities/Database/UiPath.Database.Activities/DatabaseConnect.cs @@ -1,5 +1,6 @@ using System; using System.Activities; +using System.Activities.Statements; using System.Activities.Validation; using System.ComponentModel; using System.Diagnostics; @@ -9,6 +10,11 @@ using System.Threading.Tasks; using System.Windows.Markup; using UiPath.Database.Activities.Properties; +using UiPath.Shared.Activities; + +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -60,39 +66,52 @@ internal DatabaseConnect(IDBConnectionFactory factory) protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - var connString = ConnectionString.Get(context); - var connSecureString = ConnectionSecureString.Get(context); - var connectionStringForFactory = string.Empty; - if (connString != null) - { - connectionStringForFactory = connString; - } - else if (connSecureString != null) - { - connectionStringForFactory = new NetworkCredential("", connSecureString).Password; - } - else - { - throw new ArgumentNullException(Resources.ValidationError_ConnectionStringMustNotBeNull); - } - var provName = ProviderName.Get(context); - DatabaseConnection dbConnection = null; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - dbConnection = await Task.Run(() => _connectionFactory.Create(connectionStringForFactory, provName)); + var connString = ConnectionString.Get(context); + var connSecureString = ConnectionSecureString.Get(context); + var connectionStringForFactory = string.Empty; + if (connString != null) + { + connectionStringForFactory = connString; + } + else if (connSecureString != null) + { + connectionStringForFactory = new NetworkCredential("", connSecureString).Password; + } + else + { + throw new ArgumentNullException(Resources.ValidationError_ConnectionStringMustNotBeNull); + } + var provName = ProviderName.Get(context); + DatabaseConnection dbConnection = null; + try + { + dbConnection = await Task.Run(() => _connectionFactory.Create(connectionStringForFactory, provName)); + } + catch (Exception e) + { + telemetryOperation?.SendWithException(e); + Trace.TraceError($"{e}"); + throw; + } + + var result = new Action(asyncCodeActivityContext => + { + DatabaseConnection.Set(asyncCodeActivityContext, dbConnection); + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"{e}"); + telemetryOperation?.SendWithException(ex); throw; } - - return asyncCodeActivityContext => - { - DatabaseConnection.Set(asyncCodeActivityContext, dbConnection); - }; - } - } } \ No newline at end of file diff --git a/Activities/Database/UiPath.Database.Activities/DatabaseDisconnect.cs b/Activities/Database/UiPath.Database.Activities/DatabaseDisconnect.cs index ac4f57e9c..c5fd4ea78 100644 --- a/Activities/Database/UiPath.Database.Activities/DatabaseDisconnect.cs +++ b/Activities/Database/UiPath.Database.Activities/DatabaseDisconnect.cs @@ -4,6 +4,10 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Database.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -18,21 +22,36 @@ public partial class DatabaseDisconnect : AsyncTaskCodeActivity protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - var dbConnection = DatabaseConnection.Get(context); - // create the action for doing the actual work + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - await Task.Run(() => dbConnection?.Dispose()); + var dbConnection = DatabaseConnection.Get(context); + // create the action for doing the actual work + try + { + await Task.Run(() => dbConnection?.Dispose()); + } + catch (Exception e) + { + telemetryOperation?.SendWithException(e); + Trace.TraceError($"{e}"); + } + + var result = new Action(asyncCodeActivityContext => + { + //no OutArgument + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"{e}"); + telemetryOperation?.SendWithException(ex); + throw; } - - return asyncCodeActivityContext => - { - //no OutArgument - }; } } } diff --git a/Activities/Database/UiPath.Database.Activities/DatabaseTransaction.cs b/Activities/Database/UiPath.Database.Activities/DatabaseTransaction.cs index 634cc9a72..854fd4faf 100644 --- a/Activities/Database/UiPath.Database.Activities/DatabaseTransaction.cs +++ b/Activities/Database/UiPath.Database.Activities/DatabaseTransaction.cs @@ -9,6 +9,9 @@ using System.Threading.Tasks; using UiPath.Database.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -76,32 +79,44 @@ private void HandleException(Exception ex, bool continueOnError) protected override async Task> ExecuteAsync(NativeActivityContext context, CancellationToken cancellationToken) { - var connString = ConnectionString.Get(context); - SecureString connSecureString = null; - var provName = ProviderName.Get(context); - connSecureString = ConnectionSecureString.Get(context); - DatabaseConnection existingConnection = null; - existingConnection = ExistingDbConnection.Get(context); - DatabaseConnection dbConnection = null; - - - ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); - dbConnection = await Task.Run(() => existingConnection ?? new DatabaseConnection().Initialize(connString ?? new NetworkCredential("", connSecureString).Password, provName)); - if (UseTransaction) - { - dbConnection.BeginTransaction(); - } - - return (nativeActivityContext) => + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - DatabaseConnection.Set(nativeActivityContext, dbConnection); - if (Body != null) + var connString = ConnectionString.Get(context); + SecureString connSecureString = null; + var provName = ProviderName.Get(context); + connSecureString = ConnectionSecureString.Get(context); + DatabaseConnection existingConnection = null; + existingConnection = ExistingDbConnection.Get(context); + DatabaseConnection dbConnection = null; + + + ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); + dbConnection = await Task.Run(() => existingConnection ?? new DatabaseConnection().Initialize(connString ?? new NetworkCredential("", connSecureString).Password, provName)); + if (UseTransaction) { - nativeActivityContext.ScheduleActivity(Body, OnCompletedCallback, OnFaultedCallback); + dbConnection.BeginTransaction(); } - }; - + var result = new Action(nativeActivityContext => + { + DatabaseConnection.Set(nativeActivityContext, dbConnection); + if (Body != null) + { + nativeActivityContext.ScheduleActivity(Body, OnCompletedCallback, OnFaultedCallback); + } + }); + telemetryOperation?.Send(); + return result; + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } private void OnCompletedCallback(NativeActivityContext context, ActivityInstance completedInstance) diff --git a/Activities/Database/UiPath.Database.Activities/ExecuteNonQuery.cs b/Activities/Database/UiPath.Database.Activities/ExecuteNonQuery.cs index 76624947d..77a0070b1 100644 --- a/Activities/Database/UiPath.Database.Activities/ExecuteNonQuery.cs +++ b/Activities/Database/UiPath.Database.Activities/ExecuteNonQuery.cs @@ -8,6 +8,10 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Database.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -38,78 +42,91 @@ private void HandleException(Exception ex, bool continueOnError) protected async override Task> ExecuteInternalAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - string connString = null; - SecureString connSecureString = null; - string provName = null; - string sql = string.Empty; - int commandTimeout = TimeoutMS.Get(context); - DatabaseConnection existingConnection = null; - DBExecuteCommandResult affectedRecords = null; - if (commandTimeout < 0) - { - throw new ArgumentException(Resources.TimeoutMSException, "TimeoutMS"); - } - Dictionary parameters = null; - var continueOnError = ContinueOnError.Get(context); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - sql = Sql.Get(context); - existingConnection = DbConnection = ExistingDbConnection.Get(context); - connString = ConnectionString.Get(context); - connSecureString = ConnectionSecureString.Get(context); - provName = ProviderName.Get(context); - - if (Parameters != null) + string connString = null; + SecureString connSecureString = null; + string provName = null; + string sql = string.Empty; + int commandTimeout = TimeoutMS.Get(context); + DatabaseConnection existingConnection = null; + DBExecuteCommandResult affectedRecords = null; + if (commandTimeout < 0) { - parameters = new Dictionary(); - foreach (var param in Parameters) - { - parameters.Add(param.Key, new ParameterInfo() { Value = param.Value.Get(context), Direction = param.Value.Direction, Type = param.Value.ArgumentType }); - } + throw new ArgumentException(Resources.TimeoutMSException, "TimeoutMS"); } - ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); - // create the action for doing the actual work - affectedRecords = await Task.Run(() => + Dictionary parameters = null; + var continueOnError = ContinueOnError.Get(context); + try { - DBExecuteCommandResult executeResult = new DBExecuteCommandResult(); - if (DbConnection == null) + sql = Sql.Get(context); + existingConnection = DbConnection = ExistingDbConnection.Get(context); + connString = ConnectionString.Get(context); + connSecureString = ConnectionSecureString.Get(context); + provName = ProviderName.Get(context); + + if (Parameters != null) { - DbConnection = new DatabaseConnection().Initialize(connString ?? new NetworkCredential("", connSecureString).Password, provName); + parameters = new Dictionary(); + foreach (var param in Parameters) + { + parameters.Add(param.Key, new ParameterInfo() { Value = param.Value.Get(context), Direction = param.Value.Direction, Type = param.Value.ArgumentType }); + } } - if (DbConnection == null) + ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); + // create the action for doing the actual work + affectedRecords = await Task.Run(() => { + DBExecuteCommandResult executeResult = new DBExecuteCommandResult(); + if (DbConnection == null) + { + DbConnection = new DatabaseConnection().Initialize(connString ?? new NetworkCredential("", connSecureString).Password, provName); + } + if (DbConnection == null) + { + return executeResult; + } + executeResult = new DBExecuteCommandResult(DbConnection.Execute(sql, parameters, commandTimeout, CommandType), parameters); return executeResult; - } - executeResult = new DBExecuteCommandResult(DbConnection.Execute(sql, parameters, commandTimeout, CommandType), parameters); - return executeResult; - }); + }); - } - catch (Exception ex) - { - HandleException(ex, continueOnError); - } - finally - { - if (existingConnection == null) + } + catch (Exception ex) { - DbConnection?.Dispose(); + telemetryOperation?.SendWithException(ex); + HandleException(ex, continueOnError); } - } - - return asyncCodeActivityContext => - { - AffectedRecords.Set(asyncCodeActivityContext, affectedRecords.Result); - foreach (var param in affectedRecords.ParametersBind) + finally { - var currentParam = Parameters[param.Key]; - if (currentParam.Direction == ArgumentDirection.Out || currentParam.Direction == ArgumentDirection.InOut) + if (existingConnection == null) { - currentParam.Set(asyncCodeActivityContext, param.Value.Value); + DbConnection?.Dispose(); } } - }; - + var result = new Action(asyncCodeActivityContext => + { + AffectedRecords.Set(asyncCodeActivityContext, affectedRecords.Result); + foreach (var param in affectedRecords.ParametersBind) + { + var currentParam = Parameters[param.Key]; + if (currentParam.Direction == ArgumentDirection.Out || currentParam.Direction == ArgumentDirection.InOut) + { + currentParam.Set(asyncCodeActivityContext, param.Value.Value); + } + } + }); + telemetryOperation?.Send(); + return result; + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } private class DBExecuteCommandResult diff --git a/Activities/Database/UiPath.Database.Activities/ExecuteQuery.cs b/Activities/Database/UiPath.Database.Activities/ExecuteQuery.cs index 71788efec..8f38197db 100644 --- a/Activities/Database/UiPath.Database.Activities/ExecuteQuery.cs +++ b/Activities/Database/UiPath.Database.Activities/ExecuteQuery.cs @@ -8,6 +8,10 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Database.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -38,82 +42,99 @@ private void HandleException(Exception ex, bool continueOnError) protected async override Task> ExecuteInternalAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - var dataTable = DataTable.Get(context); - string connString = null; - SecureString connSecureString = null; - string provName = null; - string sql = string.Empty; - DatabaseConnection existingConnection = null; - DBExecuteQueryResult affectedRecords = null; - int commandTimeout = TimeoutMS.Get(context); - if (commandTimeout < 0) - { - throw new ArgumentException(Resources.TimeoutMSException, "TimeoutMS"); - } - Dictionary parameters = null; - var continueOnError = ContinueOnError.Get(context); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - existingConnection = DbConnection = ExistingDbConnection.Get(context); - connString = ConnectionString.Get(context); - provName = ProviderName.Get(context); - sql = Sql.Get(context); - connSecureString = ConnectionSecureString.Get(context); - ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); - if (Parameters != null) + var dataTable = DataTable.Get(context); + string connString = null; + SecureString connSecureString = null; + string provName = null; + string sql = string.Empty; + DatabaseConnection existingConnection = null; + DBExecuteQueryResult affectedRecords = null; + int commandTimeout = TimeoutMS.Get(context); + if (commandTimeout < 0) + { + throw new ArgumentException(Resources.TimeoutMSException, "TimeoutMS"); + } + Dictionary parameters = null; + var continueOnError = ContinueOnError.Get(context); + try { - parameters = new Dictionary(); - foreach (var param in Parameters) + existingConnection = DbConnection = ExistingDbConnection.Get(context); + connString = ConnectionString.Get(context); + provName = ProviderName.Get(context); + sql = Sql.Get(context); + connSecureString = ConnectionSecureString.Get(context); + ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); + if (Parameters != null) { - parameters.Add(param.Key, new ParameterInfo() { - Value = param.Value.Get(context), - Direction = param.Value.Direction, - Type = param.Value.ArgumentType}); + parameters = new Dictionary(); + foreach (var param in Parameters) + { + parameters.Add(param.Key, new ParameterInfo() + { + Value = param.Value.Get(context), + Direction = param.Value.Direction, + Type = param.Value.ArgumentType + }); + } } - } - // create the action for doing the actual work - affectedRecords = await Task.Run(() => + // create the action for doing the actual work + affectedRecords = await Task.Run(() => + { + if (DbConnection == null) + { + DbConnection = new DatabaseConnection().Initialize(connString != null ? connString : new NetworkCredential("", connSecureString).Password, provName); + } + if (DbConnection == null) + { + return null; + } + return new DBExecuteQueryResult(DbConnection.ExecuteQuery(sql, parameters, commandTimeout, CommandType), parameters); + }); + + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + HandleException(ex, continueOnError); + } + finally { - if (DbConnection == null) + if (existingConnection == null) { - DbConnection = new DatabaseConnection().Initialize(connString != null ? connString : new NetworkCredential("", connSecureString).Password, provName); + DbConnection?.Dispose(); } - if (DbConnection == null) + } + + var result = new Action(asyncCodeActivityContext => + { + DataTable dt = affectedRecords?.Result; + if (dt == null) return; + + DataTable.Set(asyncCodeActivityContext, dt); + foreach (var param in affectedRecords.ParametersBind) { - return null; + var currentParam = Parameters[param.Key]; + if (currentParam.Direction == ArgumentDirection.Out || currentParam.Direction == ArgumentDirection.InOut) + { + currentParam.Set(asyncCodeActivityContext, param.Value.Value); + } } - return new DBExecuteQueryResult(DbConnection.ExecuteQuery(sql, parameters, commandTimeout, CommandType), parameters); }); - + telemetryOperation?.Send(); + return result; } catch (Exception ex) { - HandleException(ex, continueOnError); + telemetryOperation?.SendWithException(ex); + throw; } - finally - { - if (existingConnection == null) - { - DbConnection?.Dispose(); - } - } - - return asyncCodeActivityContext => - { - DataTable dt = affectedRecords?.Result; - if (dt == null) return; - - DataTable.Set(asyncCodeActivityContext, dt); - foreach (var param in affectedRecords.ParametersBind) - { - var currentParam = Parameters[param.Key]; - if (currentParam.Direction == ArgumentDirection.Out || currentParam.Direction == ArgumentDirection.InOut) - { - currentParam.Set(asyncCodeActivityContext, param.Value.Value); - } - } - }; } private class DBExecuteQueryResult diff --git a/Activities/Database/UiPath.Database.Activities/InsertDataTable.cs b/Activities/Database/UiPath.Database.Activities/InsertDataTable.cs index e472bee31..fc65a77ae 100644 --- a/Activities/Database/UiPath.Database.Activities/InsertDataTable.cs +++ b/Activities/Database/UiPath.Database.Activities/InsertDataTable.cs @@ -7,6 +7,10 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Database.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Database.Activities { @@ -36,52 +40,67 @@ public partial class InsertDataTable : DatabaseRowActivity protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - DataTable dataTable = null; - string connString = null; - SecureString connSecureString = null; - string provName = null; - string tableName = null; - DatabaseConnection existingConnection = null; - int affectedRecords = 0; - var continueOnError = ContinueOnError.Get(context); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - existingConnection = DbConnection = ExistingDbConnection.Get(context); - connString = ConnectionString.Get(context); - provName = ProviderName.Get(context); - tableName = TableName.Get(context); - dataTable = DataTable.Get(context); + DataTable dataTable = null; + string connString = null; + SecureString connSecureString = null; + string provName = null; + string tableName = null; + DatabaseConnection existingConnection = null; + int affectedRecords = 0; + var continueOnError = ContinueOnError.Get(context); + try + { + existingConnection = DbConnection = ExistingDbConnection.Get(context); + connString = ConnectionString.Get(context); + provName = ProviderName.Get(context); + tableName = TableName.Get(context); + dataTable = DataTable.Get(context); + + connSecureString = ConnectionSecureString.Get(context); + ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); + // create the action for doing the actual work + affectedRecords = await Task.Run(() => + { + DbConnection = DbConnection ?? new DatabaseConnection().Initialize(connString != null ? connString : new NetworkCredential("", connSecureString).Password, provName); + if (DbConnection == null) + { + return 0; + } + return DbConnection.InsertDataTable(tableName, dataTable); + }); - connSecureString = ConnectionSecureString.Get(context); - ConnectionHelper.ConnectionValidation(existingConnection, connSecureString, connString, provName); - // create the action for doing the actual work - affectedRecords = await Task.Run(() => + } + catch (Exception ex) { - DbConnection = DbConnection ?? new DatabaseConnection().Initialize(connString != null ? connString : new NetworkCredential("", connSecureString).Password, provName); - if (DbConnection == null) + telemetryOperation?.SendWithException(ex); + HandleException(ex, continueOnError); + } + finally + { + if (existingConnection == null) { - return 0; + DbConnection?.Dispose(); } - return DbConnection.InsertDataTable(tableName, dataTable); + } + var result = new Action(asyncCodeActivityContext => + { + AffectedRecords.Set(asyncCodeActivityContext, affectedRecords); }); + telemetryOperation?.Send(); + return result; } catch (Exception ex) { - HandleException(ex, continueOnError); + telemetryOperation?.SendWithException(ex); + throw; } - finally - { - if (existingConnection == null) - { - DbConnection?.Dispose(); - } - } - - return asyncCodeActivityContext => - { - AffectedRecords.Set(asyncCodeActivityContext, affectedRecords); - }; } } } diff --git a/Activities/Database/UiPath.Database.Activities/UiPath.Database.Activities.csproj b/Activities/Database/UiPath.Database.Activities/UiPath.Database.Activities.csproj index 9a284f897..06633e713 100644 --- a/Activities/Database/UiPath.Database.Activities/UiPath.Database.Activities.csproj +++ b/Activities/Database/UiPath.Database.Activities/UiPath.Database.Activities.csproj @@ -1,5 +1,4 @@  - .noconflict $(PortableFramework);$(WindowsFramework) @@ -12,10 +11,14 @@ + + + + @@ -23,8 +26,9 @@ - + + @@ -54,4 +58,8 @@ + + + + \ No newline at end of file diff --git a/Activities/Database/UiPath.Database.Tests/UiPath.Database.Tests.csproj b/Activities/Database/UiPath.Database.Tests/UiPath.Database.Tests.csproj index b9dcc2a93..590ec464d 100644 --- a/Activities/Database/UiPath.Database.Tests/UiPath.Database.Tests.csproj +++ b/Activities/Database/UiPath.Database.Tests/UiPath.Database.Tests.csproj @@ -20,6 +20,10 @@ + + + + diff --git a/Activities/Directory.build.props b/Activities/Directory.build.props index 2bb46cc53..9ba575f45 100644 --- a/Activities/Directory.build.props +++ b/Activities/Directory.build.props @@ -6,5 +6,6 @@ latest net6.0-windows net6.0 + $(DefineConstants);ENABLE_DEFAULT_TELEMETRY diff --git a/Activities/Directory.build.targets b/Activities/Directory.build.targets index f4bab13aa..9f65f0d7a 100644 --- a/Activities/Directory.build.targets +++ b/Activities/Directory.build.targets @@ -2,6 +2,8 @@ MSB3277 + + $(DefineConstants);ENABLE_DEFAULT_TELEMETRY @@ -26,7 +28,7 @@ - + @@ -34,6 +36,11 @@ + + + + + diff --git a/Activities/FTP/UiPath.FTP.Activities/Delete.cs b/Activities/FTP/UiPath.FTP.Activities/Delete.cs index 66cf79a7d..48687d9c2 100644 --- a/Activities/FTP/UiPath.FTP.Activities/Delete.cs +++ b/Activities/FTP/UiPath.FTP.Activities/Delete.cs @@ -5,6 +5,9 @@ using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -20,20 +23,34 @@ public partial class Delete : FtpAsyncActivity protected override async Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - - if (ftpSession == null) + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); - } + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - await ftpSession.DeleteAsync(RemotePath.Get(context), cancellationToken); + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } - return (asyncCodeActivityContext) => - { + await ftpSession.DeleteAsync(RemotePath.Get(context), cancellationToken); - }; + var result = new Action (asyncCodeActivityContext => + { + // No OutArgument + }); + telemetryOperation?.Send(); + return result; + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/DirectoryExists.cs b/Activities/FTP/UiPath.FTP.Activities/DirectoryExists.cs index 82b91c945..3d4b2f4fd 100644 --- a/Activities/FTP/UiPath.FTP.Activities/DirectoryExists.cs +++ b/Activities/FTP/UiPath.FTP.Activities/DirectoryExists.cs @@ -5,6 +5,9 @@ using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -25,20 +28,35 @@ public partial class DirectoryExists : FtpAsyncActivity protected override async Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif - if (ftpSession == null) + try { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); - } + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; + + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } - bool exists = await ftpSession.DirectoryExistsAsync(RemotePath.Get(context), cancellationToken); + bool exists = await ftpSession.DirectoryExistsAsync(RemotePath.Get(context), cancellationToken); - return (asyncCodeActivityContext) => + var result = new Action(asyncCodeActivityContext => + { + Exists.Set(asyncCodeActivityContext, exists); + }); + telemetryOperation?.Send(); + return result; + } + catch (Exception ex) { - Exists.Set(asyncCodeActivityContext, exists); - }; + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/DownloadFiles.cs b/Activities/FTP/UiPath.FTP.Activities/DownloadFiles.cs index fe8aa11f3..1cfbab942 100644 --- a/Activities/FTP/UiPath.FTP.Activities/DownloadFiles.cs +++ b/Activities/FTP/UiPath.FTP.Activities/DownloadFiles.cs @@ -6,7 +6,9 @@ using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; using UiPath.Shared.Activities; -using UiPath.FTP; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -43,74 +45,88 @@ public partial class DownloadFiles : FtpAsyncActivity protected override async Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - - if (ftpSession == null) + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); - } + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; + + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } - string remotePath = RemotePath.Get(context); - string localPath = LocalPath.Get(context); + string remotePath = RemotePath.Get(context); + string localPath = LocalPath.Get(context); - FtpObjectType objectType = await ftpSession.GetObjectTypeAsync(remotePath, cancellationToken); - if (objectType == FtpObjectType.Directory) - { - if (string.IsNullOrWhiteSpace(Path.GetExtension(localPath))) + FtpObjectType objectType = await ftpSession.GetObjectTypeAsync(remotePath, cancellationToken); + if (objectType == FtpObjectType.Directory) { - if (!Directory.Exists(localPath)) + if (string.IsNullOrWhiteSpace(Path.GetExtension(localPath))) { - if (Create) - { - Directory.CreateDirectory(localPath); - } - else + if (!Directory.Exists(localPath)) { - throw new ArgumentException(string.Format(Resources.PathNotFoundException, localPath)); + if (Create) + { + Directory.CreateDirectory(localPath); + } + else + { + throw new ArgumentException(string.Format(Resources.PathNotFoundException, localPath)); + } } } + else + { + throw new InvalidOperationException(Resources.IncompatiblePathsException); + } } else { - throw new InvalidOperationException(Resources.IncompatiblePathsException); - } - } - else - { - if (objectType == FtpObjectType.File) - { - if (string.IsNullOrWhiteSpace(Path.GetExtension(localPath))) + if (objectType == FtpObjectType.File) { - localPath = Path.Combine(localPath, Path.GetFileName(remotePath)); - } - - string directoryPath = Path.GetDirectoryName(localPath); - - if (!Directory.Exists(directoryPath)) - { - if (Create) + if (string.IsNullOrWhiteSpace(Path.GetExtension(localPath))) { - Directory.CreateDirectory(directoryPath); + localPath = Path.Combine(localPath, Path.GetFileName(remotePath)); } - else + + string directoryPath = Path.GetDirectoryName(localPath); + + if (!Directory.Exists(directoryPath)) { - throw new InvalidOperationException(string.Format(Resources.PathNotFoundException, directoryPath)); + if (Create) + { + Directory.CreateDirectory(directoryPath); + } + else + { + throw new InvalidOperationException(string.Format(Resources.PathNotFoundException, directoryPath)); + } } } + else + { + throw new NotImplementedException(Resources.UnsupportedObjectTypeException); + } } - else - { - throw new NotImplementedException(Resources.UnsupportedObjectTypeException); - } - } - await ftpSession.DownloadAsync(remotePath, localPath, Overwrite, Recursive, cancellationToken); + await ftpSession.DownloadAsync(remotePath, localPath, Overwrite, Recursive, cancellationToken); - return (asyncCodeActivityContext) => + var result = new Action(asyncCodeActivityContext => + { + // No OutArgument + }); + telemetryOperation?.Send(); + return result; + } + catch (Exception ex) { - - }; + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/EnumerateObjects.cs b/Activities/FTP/UiPath.FTP.Activities/EnumerateObjects.cs index b18788386..7112f05e2 100644 --- a/Activities/FTP/UiPath.FTP.Activities/EnumerateObjects.cs +++ b/Activities/FTP/UiPath.FTP.Activities/EnumerateObjects.cs @@ -6,6 +6,10 @@ using System.Threading; using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -37,46 +41,59 @@ public partial class EnumerateObjects : FtpAsyncActivity protected override async Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - - if (ftpSession == null) + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); - } + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - IEnumerable files = await ftpSession.EnumerateObjectsAsync(RemotePath.Get(context), Recursive, cancellationToken); + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } - //Filter the returned objects based on user's selection - //If none selected, clear all - if (Filter == FtpFilterObjectType.None) - { - files = Enumerable.Empty(); - } - //filter based on what the user selection - else if (Filter != (FtpFilterObjectType.Directory | FtpFilterObjectType.File | FtpFilterObjectType.Link | FtpFilterObjectType.Other)) - { - bool includeDirectories = (Filter & FtpFilterObjectType.Directory) != 0; - bool includeFiles = (Filter & FtpFilterObjectType.File) != 0; - bool includeLinks = (Filter & FtpFilterObjectType.Link) != 0; - bool includeOthers = (Filter & FtpFilterObjectType.Other) != 0; - files = files.Where(x => + IEnumerable files = await ftpSession.EnumerateObjectsAsync(RemotePath.Get(context), Recursive, cancellationToken); + + //Filter the returned objects based on user's selection + //If none selected, clear all + if (Filter == FtpFilterObjectType.None) + { + files = Enumerable.Empty(); + } + //filter based on what the user selection + else if (Filter != (FtpFilterObjectType.Directory | FtpFilterObjectType.File | FtpFilterObjectType.Link | FtpFilterObjectType.Other)) { - return x.Type switch + bool includeDirectories = (Filter & FtpFilterObjectType.Directory) != 0; + bool includeFiles = (Filter & FtpFilterObjectType.File) != 0; + bool includeLinks = (Filter & FtpFilterObjectType.Link) != 0; + bool includeOthers = (Filter & FtpFilterObjectType.Other) != 0; + files = files.Where(x => { - FtpObjectType.Directory => includeDirectories, - FtpObjectType.File => includeFiles, - FtpObjectType.Link => includeLinks, - FtpObjectType.Other => includeOthers, - _ => false, - }; + return x.Type switch + { + FtpObjectType.Directory => includeDirectories, + FtpObjectType.File => includeFiles, + FtpObjectType.Link => includeLinks, + FtpObjectType.Other => includeOthers, + _ => false, + }; + }); + } + var result = new Action(asyncCodeActivityContext => + { + Files.Set(asyncCodeActivityContext, files); }); + telemetryOperation?.Send(); + return result; } - - return (asyncCodeActivityContext) => + catch (Exception ex) { - Files.Set(asyncCodeActivityContext, files); - }; + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/FileExists.cs b/Activities/FTP/UiPath.FTP.Activities/FileExists.cs index 7f205af81..382f09aec 100644 --- a/Activities/FTP/UiPath.FTP.Activities/FileExists.cs +++ b/Activities/FTP/UiPath.FTP.Activities/FileExists.cs @@ -5,6 +5,9 @@ using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -25,20 +28,34 @@ public partial class FileExists : FtpAsyncActivity protected override async Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - - if (ftpSession == null) + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); - } + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; + + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } - bool exists = await ftpSession.FileExistsAsync(RemotePath.Get(context), cancellationToken); + bool exists = await ftpSession.FileExistsAsync(RemotePath.Get(context), cancellationToken); - return (asyncCodeActivityContext) => + var result = new Action (asyncCodeActivityContext => + { + Exists.Set(asyncCodeActivityContext, exists); + }); + telemetryOperation?.Send(); + return result; + } + catch (Exception ex) { - Exists.Set(asyncCodeActivityContext, exists); - }; + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/MoveItem.cs b/Activities/FTP/UiPath.FTP.Activities/MoveItem.cs index 281f000c3..69cd61932 100644 --- a/Activities/FTP/UiPath.FTP.Activities/MoveItem.cs +++ b/Activities/FTP/UiPath.FTP.Activities/MoveItem.cs @@ -2,10 +2,11 @@ using System.Activities; using System.ComponentModel; using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -37,26 +38,40 @@ public partial class MoveItem : FtpCodeActivity protected override void Execute(CodeActivityContext context) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - if (ftpSession == null) + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; + try { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } + ftpSession.Move(RemotePath.Get(context), NewPath.Get(context), Overwrite); } - ftpSession.Move(RemotePath.Get(context), NewPath.Get(context), Overwrite); - } - catch (Exception e) - { - if (ContinueOnError.Get(context)) - { - Trace.TraceError(e.ToString()); - } - else + catch (Exception e) { - throw; + telemetryOperation?.SendWithException(e); + if (ContinueOnError.Get(context)) + { + Trace.TraceError(e.ToString()); + } + else + { + throw; + } } + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj b/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj index f22ae9810..0afbb3517 100644 --- a/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj +++ b/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj @@ -6,8 +6,12 @@ + + + + @@ -44,4 +48,8 @@ + + + + \ No newline at end of file diff --git a/Activities/FTP/UiPath.FTP.Activities/UploadFiles.cs b/Activities/FTP/UiPath.FTP.Activities/UploadFiles.cs index 7867e04ea..4d9171cb2 100644 --- a/Activities/FTP/UiPath.FTP.Activities/UploadFiles.cs +++ b/Activities/FTP/UiPath.FTP.Activities/UploadFiles.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; using UiPath.FTP.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -42,73 +45,89 @@ public partial class UploadFiles : FtpAsyncActivity protected override async Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; - IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - - if (ftpSession == null) { - throw new InvalidOperationException(Resources.FTPSessionNotFoundException); - } + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try + { + PropertyDescriptor ftpSessionProperty = context.DataContext.GetProperties()[WithFtpSession.FtpSessionPropertyName]; + IFtpSession ftpSession = ftpSessionProperty?.GetValue(context.DataContext) as IFtpSession; - string localPath = LocalPath.Get(context); - string remotePath = RemotePath.Get(context); + if (ftpSession == null) + { + throw new InvalidOperationException(Resources.FTPSessionNotFoundException); + } - if (Directory.Exists(localPath)) - { - if (string.IsNullOrWhiteSpace(Path.GetExtension(remotePath))) - { - if (!(await ftpSession.DirectoryExistsAsync(remotePath, cancellationToken))) + string localPath = LocalPath.Get(context); + string remotePath = RemotePath.Get(context); + + if (Directory.Exists(localPath)) { - if (Create) + if (string.IsNullOrWhiteSpace(Path.GetExtension(remotePath))) { - await ftpSession.CreateDirectoryAsync(remotePath, cancellationToken); + if (!(await ftpSession.DirectoryExistsAsync(remotePath, cancellationToken))) + { + if (Create) + { + await ftpSession.CreateDirectoryAsync(remotePath, cancellationToken); + } + else + { + throw new ArgumentException(string.Format(Resources.PathNotFoundException, remotePath)); + } + } } else { - throw new ArgumentException(string.Format(Resources.PathNotFoundException, remotePath)); + throw new InvalidOperationException(Resources.IncompatiblePathsException); } } - } - else - { - throw new InvalidOperationException(Resources.IncompatiblePathsException); - } - } - else - { - if (File.Exists(localPath)) - { - if (string.IsNullOrWhiteSpace(Path.GetExtension(remotePath))) + else { - remotePath = FtpConfiguration.CombinePaths(remotePath, Path.GetFileName(localPath)); - } + if (File.Exists(localPath)) + { + if (string.IsNullOrWhiteSpace(Path.GetExtension(remotePath))) + { + remotePath = FtpConfiguration.CombinePaths(remotePath, Path.GetFileName(localPath)); + } - string directoryPath = FtpConfiguration.GetDirectoryPath(remotePath); + string directoryPath = FtpConfiguration.GetDirectoryPath(remotePath); - if (!(await ftpSession.DirectoryExistsAsync(directoryPath, cancellationToken))) - { - if (Create) - { - await ftpSession.CreateDirectoryAsync(directoryPath, cancellationToken); + if (!(await ftpSession.DirectoryExistsAsync(directoryPath, cancellationToken))) + { + if (Create) + { + await ftpSession.CreateDirectoryAsync(directoryPath, cancellationToken); + } + else + { + throw new InvalidOperationException(string.Format(Resources.PathNotFoundException, directoryPath)); + } + } } else { - throw new InvalidOperationException(string.Format(Resources.PathNotFoundException, directoryPath)); + throw new ArgumentException(string.Format(Resources.PathNotFoundException, localPath)); } } + + await ftpSession.UploadAsync(localPath, remotePath, Overwrite, Recursive, cancellationToken); + + var result = new Action(asyncCodeActivityContext => + { + // No arguments + }); + telemetryOperation?.Send(); + return result; } - else + catch (Exception ex) { - throw new ArgumentException(string.Format(Resources.PathNotFoundException, localPath)); + telemetryOperation?.SendWithException(ex); + throw; } } - - await ftpSession.UploadAsync(localPath, remotePath, Overwrite, Recursive, cancellationToken); - - return (asyncCodeActivityContext) => - { - - }; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs b/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs index afbd50691..4673004f4 100644 --- a/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs +++ b/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs @@ -10,6 +10,10 @@ using System.Security; using System.Net; using System.Activities.Validation; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.FTP.Activities { @@ -179,81 +183,96 @@ protected override void CacheMetadata(NativeActivityMetadata metadata) protected override async Task> ExecuteAsync(NativeActivityContext context, CancellationToken cancellationToken) { - string passwordValue = Password.Get(context); - SecureString securePasswordValue = SecurePassword.Get(context); - string clientCertificatePasswordValue = ClientCertificatePassword.Get(context); - SecureString clientCertificateSecurePasswordValue = ClientCertificateSecurePassword.Get(context); - - FtpConfiguration ftpConfiguration = new FtpConfiguration(Host.Get(context)); - ftpConfiguration.Port = Port.Expression == null ? null : (int?)Port.Get(context); - ftpConfiguration.UseAnonymousLogin = UseAnonymousLogin; - ftpConfiguration.SslProtocols = SslProtocols; - ftpConfiguration.ProxyType = ProxyType; - - if (PasswordInputModeSwitch == PasswordInputMode.Password) - { - ftpConfiguration.Password = passwordValue; - } - else - { - ftpConfiguration.Password = new NetworkCredential("", securePasswordValue).Password; - } - - if (ftpConfiguration.ProxyType != FtpProxyType.None) + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - ftpConfiguration.ProxyServer = ProxyServer.Get(context); - ftpConfiguration.ProxyPort = ProxyPort.Expression == null ? null : (int?)ProxyPort.Get(context); - ftpConfiguration.ProxyUsername = ProxyUser.Get(context); - - if (ProxyPasswordInputModeSwitch == PasswordInputMode.Password) - ftpConfiguration.ProxyPassword = ProxyPassword.Get(context); + string passwordValue = Password.Get(context); + SecureString securePasswordValue = SecurePassword.Get(context); + string clientCertificatePasswordValue = ClientCertificatePassword.Get(context); + SecureString clientCertificateSecurePasswordValue = ClientCertificateSecurePassword.Get(context); + + FtpConfiguration ftpConfiguration = new FtpConfiguration(Host.Get(context)); + ftpConfiguration.Port = Port.Expression == null ? null : (int?)Port.Get(context); + ftpConfiguration.UseAnonymousLogin = UseAnonymousLogin; + ftpConfiguration.SslProtocols = SslProtocols; + ftpConfiguration.ProxyType = ProxyType; + + if (PasswordInputModeSwitch == PasswordInputMode.Password) + { + ftpConfiguration.Password = passwordValue; + } else - ftpConfiguration.ProxyPassword = new NetworkCredential(string.Empty, ProxySecurePassword.Get(context)).Password; - } + { + ftpConfiguration.Password = new NetworkCredential("", securePasswordValue).Password; + } - ftpConfiguration.ClientCertificatePath = ClientCertificatePath.Get(context); - ftpConfiguration.ClientCertificatePassword = clientCertificatePasswordValue; - if (ftpConfiguration.ClientCertificatePassword == null) - { - ftpConfiguration.ClientCertificatePassword = new NetworkCredential("", clientCertificateSecurePasswordValue).Password; - } + if (ftpConfiguration.ProxyType != FtpProxyType.None) + { + ftpConfiguration.ProxyServer = ProxyServer.Get(context); + ftpConfiguration.ProxyPort = ProxyPort.Expression == null ? null : (int?)ProxyPort.Get(context); + ftpConfiguration.ProxyUsername = ProxyUser.Get(context); + + if (ProxyPasswordInputModeSwitch == PasswordInputMode.Password) + ftpConfiguration.ProxyPassword = ProxyPassword.Get(context); + else + ftpConfiguration.ProxyPassword = new NetworkCredential(string.Empty, ProxySecurePassword.Get(context)).Password; + } - ftpConfiguration.AcceptAllCertificates = AcceptAllCertificates; + ftpConfiguration.ClientCertificatePath = ClientCertificatePath.Get(context); + ftpConfiguration.ClientCertificatePassword = clientCertificatePasswordValue; + if (ftpConfiguration.ClientCertificatePassword == null) + { + ftpConfiguration.ClientCertificatePassword = new NetworkCredential("", clientCertificateSecurePasswordValue).Password; + } - if (ftpConfiguration.UseAnonymousLogin == false) - { - ftpConfiguration.Username = Username.Get(context); - if (string.IsNullOrWhiteSpace(ftpConfiguration.Username)) + ftpConfiguration.AcceptAllCertificates = AcceptAllCertificates; + + if (ftpConfiguration.UseAnonymousLogin == false) { - throw new ArgumentNullException(Resources.EmptyUsernameException); + ftpConfiguration.Username = Username.Get(context); + if (string.IsNullOrWhiteSpace(ftpConfiguration.Username)) + { + throw new ArgumentNullException(Resources.EmptyUsernameException); + } + + if (string.IsNullOrWhiteSpace(ftpConfiguration.Password) && string.IsNullOrWhiteSpace(ftpConfiguration.ClientCertificatePath)) + { + throw new ArgumentNullException(Resources.NoValidAuthenticationMethod); + } } - if (string.IsNullOrWhiteSpace(ftpConfiguration.Password) && string.IsNullOrWhiteSpace(ftpConfiguration.ClientCertificatePath)) + IFtpSession ftpSession = _setFtpSession; + if (UseSftp) { - throw new ArgumentNullException(Resources.NoValidAuthenticationMethod); + ftpSession ??= new SftpSession(ftpConfiguration); + } + else + { + ftpSession ??= new FtpSession(ftpConfiguration, FtpsMode); } - } - IFtpSession ftpSession = _setFtpSession; - if (UseSftp) - { - ftpSession ??= new SftpSession(ftpConfiguration); + await ftpSession.OpenAsync(cancellationToken); + + var result = new Action(nativeActivityContext => + { + if (Body != null) + { + _ftpSession = ftpSession; + nativeActivityContext.ScheduleAction(Body, ftpSession, OnCompleted, OnFaulted); + } + }); + telemetryOperation?.Send(); + return result; } - else + catch (Exception ex) { - ftpSession ??= new FtpSession(ftpConfiguration, FtpsMode); + telemetryOperation?.SendWithException(ex); + throw; } - await ftpSession.OpenAsync(cancellationToken); - - return (nativeActivityContext) => - { - if (Body != null) - { - _ftpSession = ftpSession; - nativeActivityContext.ScheduleAction(Body, ftpSession, OnCompleted, OnFaulted); - } - }; } private void OnCompleted(NativeActivityContext context, ActivityInstance completedInstance) diff --git a/Activities/FTP/UiPath.FTP.Tests/UiPath.FTP.Tests.csproj b/Activities/FTP/UiPath.FTP.Tests/UiPath.FTP.Tests.csproj index 6e0cc8139..aa69a6e00 100644 --- a/Activities/FTP/UiPath.FTP.Tests/UiPath.FTP.Tests.csproj +++ b/Activities/FTP/UiPath.FTP.Tests/UiPath.FTP.Tests.csproj @@ -21,6 +21,9 @@ + + + diff --git a/Activities/Java/UiPath.Java.Activities/ConvertJavaObject.cs b/Activities/Java/UiPath.Java.Activities/ConvertJavaObject.cs index de7d72ae9..dd398acbd 100644 --- a/Activities/Java/UiPath.Java.Activities/ConvertJavaObject.cs +++ b/Activities/Java/UiPath.Java.Activities/ConvertJavaObject.cs @@ -2,6 +2,11 @@ using System.Activities; using System.ComponentModel; using UiPath.Java.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif + namespace UiPath.Java.Activities { @@ -36,9 +41,22 @@ private set protected override void Execute(CodeActivityContext context) { - IInvoker invoker = JavaScope.GetJavaInvoker(context); - var javaObject = JavaObject.Get(context) ?? throw new ArgumentNullException(Resources.JavaObject); - Result.Set(context, javaObject.Convert()); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try + { + IInvoker invoker = JavaScope.GetJavaInvoker(context); + var javaObject = JavaObject.Get(context) ?? throw new ArgumentNullException(Resources.JavaObject); + Result.Set(context, javaObject.Convert()); + telemetryOperation?.Send(); + } + catch (Exception ex) + { + telemetryOperation?.SendWithException(ex); + throw; + } } } } diff --git a/Activities/Java/UiPath.Java.Activities/CreateJavaObject.cs b/Activities/Java/UiPath.Java.Activities/CreateJavaObject.cs index 2bdaf9d87..45273afae 100644 --- a/Activities/Java/UiPath.Java.Activities/CreateJavaObject.cs +++ b/Activities/Java/UiPath.Java.Activities/CreateJavaObject.cs @@ -6,6 +6,11 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Java.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif + namespace UiPath.Java.Activities { @@ -26,29 +31,43 @@ public class CreateJavaObject : JavaActivityWithParameters protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - IInvoker invoker = JavaScope.GetJavaInvoker(context); - var className = TargetType.Get(context); - if (string.IsNullOrWhiteSpace(className)) - { - throw new ArgumentNullException(nameof(TargetType)); - } - List parameters = GetParameters(context); - var types = GetParameterTypes(context, parameters); - JavaObject instance = null; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - instance = await invoker.InvokeConstructor(className, parameters, types, cancellationToken); + IInvoker invoker = JavaScope.GetJavaInvoker(context); + var className = TargetType.Get(context); + if (string.IsNullOrWhiteSpace(className)) + { + throw new ArgumentNullException(nameof(TargetType)); + } + List parameters = GetParameters(context); + var types = GetParameterTypes(context, parameters); + JavaObject instance = null; + try + { + instance = await invoker.InvokeConstructor(className, parameters, types, cancellationToken); + } + catch (Exception e) + { + Trace.TraceError($"Constrcutor could not be invoker: {e}"); + throw new InvalidOperationException(Resources.ConstructorException, e); + } + + var result = new Action(asyncCodeActivityContext => + { + Result.Set(asyncCodeActivityContext, instance); + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"Constrcutor could not be invoker: {e}"); - throw new InvalidOperationException(Resources.ConstructorException, e); + telemetryOperation?.SendWithException(ex); + throw; } - - return asyncCodeActivityContext => - { - Result.Set(asyncCodeActivityContext, instance); - }; } } } diff --git a/Activities/Java/UiPath.Java.Activities/GetJavaField.cs b/Activities/Java/UiPath.Java.Activities/GetJavaField.cs index c4d448aee..23030973b 100644 --- a/Activities/Java/UiPath.Java.Activities/GetJavaField.cs +++ b/Activities/Java/UiPath.Java.Activities/GetJavaField.cs @@ -4,6 +4,10 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Java.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif namespace UiPath.Java.Activities { @@ -37,31 +41,46 @@ public class GetJavaField : JavaActivity public OutArgument Result { get; set; } protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - IInvoker invoker = JavaScope.GetJavaInvoker(context); - var fieldName = FieldName.Get(context) ?? throw new ArgumentNullException(Resources.FieldName); - var javaObject = TargetObject.Get(context); - var className = TargetType.Get(context); - - if (javaObject == null && className == null) - { - throw new InvalidOperationException(Resources.InvokationObjectException); - } - - JavaObject instance; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - instance = await invoker.InvokeGetField(javaObject, fieldName, className, cancellationToken); + IInvoker invoker = JavaScope.GetJavaInvoker(context); + var fieldName = FieldName.Get(context) ?? throw new ArgumentNullException(Resources.FieldName); + var javaObject = TargetObject.Get(context); + var className = TargetType.Get(context); + + if (javaObject == null && className == null) + { + throw new InvalidOperationException(Resources.InvokationObjectException); + } + + JavaObject instance; + try + { + instance = await invoker.InvokeGetField(javaObject, fieldName, className, cancellationToken); + } + catch (Exception e) + { + telemetryOperation?.SendWithException(e); + Trace.TraceError($"Could not get java field: {e}"); + throw new InvalidOperationException(Resources.GetFieldException, e); + } + + var result = new Action(asyncCodeActivityContext => + { + Result.Set(asyncCodeActivityContext, instance); + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"Could not get java field: {e}"); - throw new InvalidOperationException(Resources.GetFieldException, e); + telemetryOperation?.SendWithException(ex); + throw; } - - return asyncCodeActivityContext => - { - Result.Set(asyncCodeActivityContext, instance); - }; } } } diff --git a/Activities/Java/UiPath.Java.Activities/InvokeJavaMethod.cs b/Activities/Java/UiPath.Java.Activities/InvokeJavaMethod.cs index 62b9c20ca..f4fc2e53b 100644 --- a/Activities/Java/UiPath.Java.Activities/InvokeJavaMethod.cs +++ b/Activities/Java/UiPath.Java.Activities/InvokeJavaMethod.cs @@ -6,6 +6,11 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Java.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif + namespace UiPath.Java.Activities { @@ -40,34 +45,48 @@ public class InvokeJavaMethod : JavaActivityWithParameters protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - IInvoker invoker = JavaScope.GetJavaInvoker(context); - var methodName = MethodName.Get(context) ?? throw new ArgumentNullException(Resources.MethodName); - JavaObject javaObject = TargetObject.Get(context); - string className = TargetType.Get(context); - - if (javaObject == null && string.IsNullOrWhiteSpace(className)) + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif + try { - throw new InvalidOperationException(Resources.InvokationObjectException); - } + IInvoker invoker = JavaScope.GetJavaInvoker(context); + var methodName = MethodName.Get(context) ?? throw new ArgumentNullException(Resources.MethodName); + JavaObject javaObject = TargetObject.Get(context); + string className = TargetType.Get(context); - List parameters = GetParameters(context); - var types = GetParameterTypes(context, parameters); - JavaObject instance = null; + if (javaObject == null && string.IsNullOrWhiteSpace(className)) + { + throw new InvalidOperationException(Resources.InvokationObjectException); + } - try - { - instance = await invoker.InvokeMethod(methodName, className, javaObject, parameters, types, cancellationToken); + List parameters = GetParameters(context); + var types = GetParameterTypes(context, parameters); + JavaObject instance = null; + + try + { + instance = await invoker.InvokeMethod(methodName, className, javaObject, parameters, types, cancellationToken); + } + catch (Exception e) + { + telemetryOperation?.SendWithException(e); + Trace.TraceError($"The method could not be invoked: {e}"); + throw new InvalidOperationException(Resources.InvokeMethodException, e); + } + var result = new Action (asyncCodeActivityContext => + { + Result.Set(asyncCodeActivityContext, instance); + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"The method could not be invoked: {e}"); - throw new InvalidOperationException(Resources.InvokeMethodException, e); + telemetryOperation?.SendWithException(ex); + throw; } - - return asyncCodeActivityContext => - { - Result.Set(asyncCodeActivityContext, instance); - }; } } } diff --git a/Activities/Java/UiPath.Java.Activities/JavaScope.cs b/Activities/Java/UiPath.Java.Activities/JavaScope.cs index 37a6e970e..0bf587764 100644 --- a/Activities/Java/UiPath.Java.Activities/JavaScope.cs +++ b/Activities/Java/UiPath.Java.Activities/JavaScope.cs @@ -9,6 +9,10 @@ using System.Threading.Tasks; using UiPath.Java.Activities.Properties; using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif + namespace UiPath.Java.Activities { @@ -60,42 +64,57 @@ public JavaScope() protected override async Task> ExecuteAsync(NativeActivityContext context, CancellationToken ct) { - string javaPath = JavaPath.Get(context); - var javaExec = _javaExeWindows; -#if NETCOREAPP - if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - javaExec = _javaExeLinux; + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); #endif - if (javaPath != null) + try { - javaPath = Path.Combine(javaPath, "bin", javaExec); - if (!File.Exists(javaPath)) + string javaPath = JavaPath.Get(context); + var javaExec = _javaExeWindows; +#if NETCOREAPP + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + javaExec = _javaExeLinux; +#endif + if (javaPath != null) { - throw new ArgumentException(Resources.InvalidJavaPath, Resources.JavaPathDisplayName); + javaPath = Path.Combine(javaPath, "bin", javaExec); + if (!File.Exists(javaPath)) + { + throw new ArgumentException(Resources.InvalidJavaPath, Resources.JavaPathDisplayName); + } } - } - _invoker = new JavaInvoker(javaPath); + _invoker = new JavaInvoker(javaPath); - int initTimeout = TimeoutMS.Get(context); - if (initTimeout < 0) - { - throw new ArgumentException(UiPath.Java.Activities.Properties.Resources.TimeoutMSException, "TimeoutMS"); - } + int initTimeout = TimeoutMS.Get(context); + if (initTimeout < 0) + { + throw new ArgumentException(UiPath.Java.Activities.Properties.Resources.TimeoutMSException, "TimeoutMS"); + } - try - { - await _invoker.StartJavaService(initTimeout); + try + { + await _invoker.StartJavaService(initTimeout); + } + catch (Exception e) + { + telemetryOperation?.SendWithException(e); + Trace.TraceError($"Error initializing Java Invoker: {e}"); + throw new InvalidOperationException(string.Format(Resources.JavaInitiazeException, e.ToString())); + } + ct.ThrowIfCancellationRequested(); + var result = new Action(ctx => + { + ctx.ScheduleAction(Body, _invoker, OnCompleted, OnFaulted); + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"Error initializing Java Invoker: {e}"); - throw new InvalidOperationException(string.Format(Resources.JavaInitiazeException, e.ToString())); + telemetryOperation?.SendWithException(ex); + throw; } - ct.ThrowIfCancellationRequested(); - return ctx => - { - ctx.ScheduleAction(Body, _invoker, OnCompleted, OnFaulted); - }; } private void OnFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom) diff --git a/Activities/Java/UiPath.Java.Activities/LoadJar.cs b/Activities/Java/UiPath.Java.Activities/LoadJar.cs index 8922edb1d..29f23ab60 100644 --- a/Activities/Java/UiPath.Java.Activities/LoadJar.cs +++ b/Activities/Java/UiPath.Java.Activities/LoadJar.cs @@ -4,6 +4,11 @@ using System.Threading; using System.Threading.Tasks; using UiPath.Java.Activities.Properties; +using UiPath.Shared.Activities; +#if ENABLE_DEFAULT_TELEMETRY +using UiPath.Shared.Telemetry.Services; +#endif + namespace UiPath.Java.Activities { @@ -19,23 +24,36 @@ public class LoadJar : JavaActivity protected async override Task> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { - IInvoker invoker = JavaScope.GetJavaInvoker(context); - var jarPath = JarPath.Get(context) ?? throw new ArgumentNullException(Resources.JarPathDisplayName); + ITelemetryOperationWrapper telemetryOperation = null; +#if ENABLE_DEFAULT_TELEMETRY + telemetryOperation = RuntimeTelemetryService.CreateExecutionOperation(this, context); +#endif try { - await invoker.LoadJar(jarPath, cancellationToken); + IInvoker invoker = JavaScope.GetJavaInvoker(context); + var jarPath = JarPath.Get(context) ?? throw new ArgumentNullException(Resources.JarPathDisplayName); + try + { + await invoker.LoadJar(jarPath, cancellationToken); + } + catch (Exception e) + { + telemetryOperation?.SendWithException(e); + Trace.TraceError($"Jar could not be loaded{e}"); + throw new InvalidOperationException(Resources.LoadJarException, e); + } + var result = new Action(asyncCodeActivityContext => + { + // No OutArgument + }); + telemetryOperation?.Send(); + return result; } - catch (Exception e) + catch (Exception ex) { - Trace.TraceError($"Jar could not be loaded{e}"); - throw new InvalidOperationException(Resources.LoadJarException, e); + telemetryOperation?.SendWithException(ex); + throw; } - - return asyncCodeActivityContext => - { - - }; - } } } diff --git a/Activities/Java/UiPath.Java.Activities/UiPath.Java.Activities.csproj b/Activities/Java/UiPath.Java.Activities/UiPath.Java.Activities.csproj index cbe6db1ae..be35e110d 100644 --- a/Activities/Java/UiPath.Java.Activities/UiPath.Java.Activities.csproj +++ b/Activities/Java/UiPath.Java.Activities/UiPath.Java.Activities.csproj @@ -7,6 +7,12 @@ + + + + + + @@ -15,4 +21,7 @@ + + + \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Activities/ITelemetryOperationWrapper.cs b/Activities/Shared/UiPath.Shared.Activities/ITelemetryOperationWrapper.cs index 8db79a331..f3b0c2ba6 100644 --- a/Activities/Shared/UiPath.Shared.Activities/ITelemetryOperationWrapper.cs +++ b/Activities/Shared/UiPath.Shared.Activities/ITelemetryOperationWrapper.cs @@ -1,18 +1,25 @@ -namespace UiPath.Shared.Activities +using System; + +namespace UiPath.Shared.Activities { - /// - /// Taken from System Activities - /// - internal interface ITelemetryOperationWrapper + public interface ITelemetryOperationWrapper { void SendWithException(Exception ex); void Send(); /// - /// Sets an object as the Data property of the current execution operation. Use this to track aditional data for the activity + /// Sets an object as the Data property of the current execution operation. Use this to track additional data for the activity /// /// void SetCustomData(object value); + + /// + /// Sets a custom "Dictionary{string, string}" key-value pair.
+ /// WARNING: it destroys any existing custom data, that is not already a "Dictionary{string, object}" + ///
+ /// + /// + void SetCustomDataKey(string key, object value); } } diff --git a/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems b/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems index c4421d491..ef1861ef1 100644 --- a/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems +++ b/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems @@ -16,6 +16,7 @@ + diff --git a/Activities/Shared/UiPath.Shared.Contracts.Private/LegacyDesignerContract.cs b/Activities/Shared/UiPath.Shared.Contracts.Private/LegacyDesignerContract.cs new file mode 100644 index 000000000..ad4fe7d77 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts.Private/LegacyDesignerContract.cs @@ -0,0 +1,46 @@ +using System; +using UiPath.Activities.Contracts; + +namespace UiPath.Shared.Contracts.Private +{ + internal class LegacyDesignerContract : RuntimeContractWrapper + { + private IWorkflowDesignerContract _contract; + + public LegacyDesignerContract() + : base() + { + } + + public LegacyDesignerContract(string featureName) + : base(featureName) + { + } + + public LegacyDesignerContract With(string featureName) + { + return new LegacyDesignerContract(featureName); + } + + protected override object GetContractInstance() + { + _contract = WorkflowDesignerContractRegistry.Instance; + return _contract; + } + + protected override Type GetContractType() + { + return typeof(IWorkflowDesignerContract); + } + + protected override bool HasFeature(string featureName) + { + return _contract.HasFeature(featureName); + } + + internal IWorkflowDesignerContract UnSafe() + { + return _contract; + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Contracts.Private/PrivateContractExtensions.cs b/Activities/Shared/UiPath.Shared.Contracts.Private/PrivateContractExtensions.cs new file mode 100644 index 000000000..765365685 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts.Private/PrivateContractExtensions.cs @@ -0,0 +1,12 @@ +using UiPath.Shared.Contracts.Private; + +namespace System.Activities +{ + internal static class PrivateContractExtensions + { + internal static PrivateRuntimeContract PrivateContract(this ActivityContext ctx, string featureName) + { + return new PrivateRuntimeContract(ctx, featureName); + } + } +} \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Contracts.Private/PrivateRuntimeContract.cs b/Activities/Shared/UiPath.Shared.Contracts.Private/PrivateRuntimeContract.cs new file mode 100644 index 000000000..843ffd262 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts.Private/PrivateRuntimeContract.cs @@ -0,0 +1,59 @@ +using System; +using System.Activities; +using UiPath.Activities.Contracts; + +namespace UiPath.Shared.Contracts.Private +{ + internal class PrivateRuntimeContract : RuntimeContractWrapper + { + private readonly ActivityContext _ctx; + private IWorkflowRuntime _contract; + private object _contractObj; + + public PrivateRuntimeContract(ActivityContext ctx) + : this(ctx, null) + { + } + + public PrivateRuntimeContract(ActivityContext ctx, string featureName) + : base(featureName) + { + _ctx = ctx; + } + + public PrivateRuntimeContract(object api) + : base(null) + { + _contractObj = api; + } + + public PrivateRuntimeContract With(string featureName) + { + return new PrivateRuntimeContract(_ctx, featureName) + { + _contractObj = _contractObj + }; + } + + protected override object GetContractInstance() + { + _contract = _ctx?.GetExtension() ?? _contractObj as IWorkflowRuntime; + return _contract; + } + + protected override Type GetContractType() + { + return typeof(IWorkflowRuntime); + } + + protected override bool HasFeature(string featureName) + { + return _contract.HasFeature(featureName); + } + + internal virtual IWorkflowRuntime UnSafe() + { + return _contract; + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Contracts.Private/RuntimeContractExtensions.cs b/Activities/Shared/UiPath.Shared.Contracts.Private/RuntimeContractExtensions.cs new file mode 100644 index 000000000..0b02365d2 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts.Private/RuntimeContractExtensions.cs @@ -0,0 +1,17 @@ +using UiPath.Shared.Contracts; + +namespace System.Activities +{ + internal static class RuntimeContractExtensions + { + internal static RuntimeContract RuntimeContract(this ActivityContext ctx) + { + return new RuntimeContract(ctx); + } + + internal static RuntimeContract RuntimeContract(this ActivityContext ctx, string featureName) + { + return new RuntimeContract(ctx, featureName); + } + } +} \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Contracts.Private/UiPath.Shared.Contracts.Private.projitems b/Activities/Shared/UiPath.Shared.Contracts.Private/UiPath.Shared.Contracts.Private.projitems new file mode 100644 index 000000000..7ec47b194 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts.Private/UiPath.Shared.Contracts.Private.projitems @@ -0,0 +1,17 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + bf6397b9-12c9-49a2-811e-4272a2f46c12 + + + UiPath.Shared.Contracts.Private + + + + + + + + \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Contracts.Private/UiPath.Shared.Contracts.Private.shproj b/Activities/Shared/UiPath.Shared.Contracts.Private/UiPath.Shared.Contracts.Private.shproj new file mode 100644 index 000000000..b80f91e5f --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts.Private/UiPath.Shared.Contracts.Private.shproj @@ -0,0 +1,13 @@ + + + + bf6397b9-12c9-49a2-811e-4272a2f46c12 + 14.0 + + + + + + + + diff --git a/Activities/Shared/UiPath.Shared.Contracts/DesignerContract.cs b/Activities/Shared/UiPath.Shared.Contracts/DesignerContract.cs new file mode 100644 index 000000000..d78f142c5 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts/DesignerContract.cs @@ -0,0 +1,67 @@ +using System; +#if NETFRAMEWORK +using System.Activities.Presentation; +#endif +using UiPath.Studio.Activities.Api; + +namespace UiPath.Shared.Contracts +{ + internal class DesignerContract : RuntimeContractWrapper + { + private IWorkflowDesignApi _contract; + private readonly object _contractObj; + +#if NETFRAMEWORK + private EditingContext _ctx; + + public DesignerContract(EditingContext ctx) + : this(ctx, null) + { + } + + public DesignerContract(EditingContext ctx, string featureName) + : base(featureName) + { + _ctx = ctx; + } +#endif + public DesignerContract(object api, string featureName) : base(featureName) + { + _contractObj = api; + } + + public DesignerContract With(string featureName) + { + var result = new DesignerContract(_contractObj, featureName); +#if NETFRAMEWORK + result._ctx = _ctx; +#endif + return result; + } + + protected override object GetContractInstance() + { +#if NETFRAMEWORK + _contract = _ctx?.Services.GetService(); +#endif + _contract = _contract ?? _contractObj as IWorkflowDesignApi; + + return _contract; + } + + protected override Type GetContractType() + { + return typeof(IWorkflowDesignApi); + } + + protected override bool HasFeature(string featureName) + { + return _contract.HasFeature(featureName); + } + + internal IWorkflowDesignApi UnSafe() + { + return _contract; + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Contracts/DesignerContractExtensions.cs b/Activities/Shared/UiPath.Shared.Contracts/DesignerContractExtensions.cs new file mode 100644 index 000000000..f3d001f22 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts/DesignerContractExtensions.cs @@ -0,0 +1,15 @@ +#if NETFRAMEWORK +using System.Activities.Presentation; +using UiPath.Shared.Contracts; + +namespace System.Activities +{ + internal static class DesignerContractExtensions + { + internal static DesignerContract DesignerContract(this EditingContext ctx, string featureName) + { + return new DesignerContract(ctx, featureName); + } + } +} +#endif \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Contracts/RuntimeContract.cs b/Activities/Shared/UiPath.Shared.Contracts/RuntimeContract.cs new file mode 100644 index 000000000..1370e53a0 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts/RuntimeContract.cs @@ -0,0 +1,62 @@ +using System; +using System.Activities; +using UiPath.Robot.Activities.Api; + +namespace UiPath.Shared.Contracts +{ + internal class RuntimeContract : RuntimeContractWrapper + { + private readonly ActivityContext _ctx; + private IExecutorRuntime _contract; + + public RuntimeContract(ActivityContext ctx) + : this(ctx, null) + { + } + + public RuntimeContract(ActivityContext ctx, string featureName) + : base(featureName) + { + _ctx = ctx; + } + + public RuntimeContract(IExecutorRuntime runtime, string featureName) + : base(featureName) + { + _contract = runtime; + } + + public RuntimeContract With(string featureName) + { + if (_contract != null) + { + return new RuntimeContract(_contract, featureName); + } + return new RuntimeContract(_ctx, featureName); + } + + protected override object GetContractInstance() + { + if (_contract == null) + { + _contract = _ctx?.GetExtension(); + } + return _contract; + } + + protected override Type GetContractType() + { + return typeof(IExecutorRuntime); + } + + protected override bool HasFeature(string featureName) + { + return _contract.HasFeature(featureName); + } + + internal virtual IExecutorRuntime UnSafe() + { + return _contract; + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Contracts/RuntimeContractWrapper.cs b/Activities/Shared/UiPath.Shared.Contracts/RuntimeContractWrapper.cs new file mode 100644 index 000000000..ad1b5363b --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts/RuntimeContractWrapper.cs @@ -0,0 +1,117 @@ +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace UiPath.Shared.Contracts +{ + internal abstract class RuntimeContractWrapper + where T : RuntimeContractWrapper + { + [SuppressMessage("SonarQube", "S2743: A static field in a generic type is not shared among instances of different close constructed types.", Justification = "By design")] + private static bool? _contractTypeExists; + + private readonly string _featureName; + private bool? _isSupported = null; + + protected RuntimeContractWrapper(string featureName) + { + _featureName = featureName; + } + + protected RuntimeContractWrapper() + : this(null) + { + } + + [SuppressMessage("SonarQube", "S2696: Make the enclosing instance method 'static' or remove this set on the 'static' field.", Justification = "By design")] + private object TryGetContractInstance() + { + if (_contractTypeExists == null) + { + _contractTypeExists = CheckContractType(); + } + return _contractTypeExists.Value ? GetContractInstance() : null; + } + + protected abstract object GetContractInstance(); + + [MethodImpl(MethodImplOptions.NoInlining)] + private bool CheckContractType() + { + try + { + var type = GetContractType(); + return type != null; + } + catch (Exception ex) + { + Trace.TraceInformation(ex.ToString()); + return false; + } + } + + protected abstract Type GetContractType(); + + public bool IsSupported() + { + if (_isSupported != null) + { + return _isSupported.Value; + } + var contract = TryGetContractInstance(); + if (contract == null) + { + _isSupported = false; + return _isSupported.Value; + } + if (string.IsNullOrEmpty(_featureName)) + { + _isSupported = true; + return _isSupported.Value; + } + + _isSupported = HasFeature(_featureName); + return _isSupported.Value; + } + + protected abstract bool HasFeature(string featureName); + + public TResult Invoke(Func func) + { + return Invoke(func, true); + } + + protected TResult Invoke(Func func, bool throwIfNotSupported) + { + if (!IsSupported()) + { + if (throwIfNotSupported) + { + throw new NotSupportedException(); + } + return default(TResult); + } + return func(GetInvokeInstance()); + } + + protected virtual T GetInvokeInstance() + { + return (T)this; + } + + public TResult TryInvoke(Func func) + { + return Invoke(func, false); + } + + public void TryInvoke(Action action) + { + Invoke(c => + { + action(c); + return true; + }, false); + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Contracts/UiPath.Shared.Contracts.projitems b/Activities/Shared/UiPath.Shared.Contracts/UiPath.Shared.Contracts.projitems new file mode 100644 index 000000000..bbca66c09 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts/UiPath.Shared.Contracts.projitems @@ -0,0 +1,17 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + ef796dfb-540b-402e-8993-1d1d29a6d1d6 + + + UiPath.Shared.Contracts + + + + + + + + \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Contracts/UiPath.Shared.Contracts.shproj b/Activities/Shared/UiPath.Shared.Contracts/UiPath.Shared.Contracts.shproj new file mode 100644 index 000000000..3dd80dd72 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Contracts/UiPath.Shared.Contracts.shproj @@ -0,0 +1,13 @@ + + + + ef796dfb-540b-402e-8993-1d1d29a6d1d6 + 14.0 + + + + + + + + diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ActivityExceptionData.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ActivityExceptionData.cs new file mode 100644 index 000000000..42acd8c72 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ActivityExceptionData.cs @@ -0,0 +1,44 @@ +using System; +using Newtonsoft.Json; + +namespace UiPath.Shared.Telemetry.Contracts +{ + internal class ActivityExceptionData : BasicEvent, IActivityTelemetryData + { + private const int TelemetryMaxEventLength = 7000; + + private ActivityExceptionData(string name) : base(name) + { } + + public string Error => Exception.GetType().FullName; + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public string StackTrace => Truncate(Exception.StackTrace, TelemetryMaxEventLength - (Message?.Length ?? 0)); + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public string Message { get; set; } + + public string ActivityType { get; private set; } + + [JsonIgnore] + public Exception Exception { get; private set; } + + public static ActivityExceptionData From(string eventName, IActivityTelemetryData activityData, Exception exception) => + new ActivityExceptionData(eventName) + { + Exception = exception, + Message = exception.Message, + ActivityType = activityData.ActivityType, + ActivityPackage = activityData.ActivityPackage, + ActivityPackageVersion = activityData.ActivityPackageVersion, + }; + + private static string Truncate(string input, int maxLength) + { + if (string.IsNullOrEmpty(input)) + return input; + + return input.Length < maxLength ? input : input.Substring(0, maxLength); + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/BasicEvent.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/BasicEvent.cs new file mode 100644 index 000000000..95cb491bc --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/BasicEvent.cs @@ -0,0 +1,33 @@ +using TelemetryClient.Contracts.Model; + +namespace UiPath.Shared.Telemetry +{ + internal class BasicEvent : TelemetryEvent + { + public BasicEvent(string name) : base(name, TelemetryCommon.Assembly) + { + ActivityPackage = TelemetryCommon.Assembly; + ActivityPackageVersion = TelemetryCommon.AssemblyVersion; + } + + /// + /// Activity package name. Defaults to + /// + public string ActivityPackage { get; set; } + + /// + /// Activity package version. Defaults to + /// + public string ActivityPackageVersion { get; set; } + } + + internal class BasicEvent : BasicEvent + { + public BasicEvent(string name, T data) : base(name) + { + Data = data; + } + + public T Data { get; set; } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/BasicOperation.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/BasicOperation.cs new file mode 100644 index 000000000..a4393ad79 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/BasicOperation.cs @@ -0,0 +1,35 @@ +using TelemetryClient.Contracts.Attributes; +using TelemetryClient.Contracts.Model; + +namespace UiPath.Shared.Telemetry +{ + internal class BasicOperation : TelemetryOperation + { + public BasicOperation(string name) : base(name, TelemetryCommon.Assembly) + { + ActivityPackage = TelemetryCommon.Assembly; + ActivityPackageVersion = TelemetryCommon.AssemblyVersion; + } + + /// + /// Activity package name. Defaults to + /// + public string ActivityPackage { get; set; } + + /// + /// Activity package version. Defaults to + /// + public string ActivityPackageVersion { get; set; } + } + + internal class BasicOperation : BasicOperation + { + public BasicOperation(string name, T data) : base(name) + { + Data = data; + } + + [TelemetryProperty] + public T Data { get; set; } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/IActivityTelemetryData.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/IActivityTelemetryData.cs new file mode 100644 index 000000000..5fb815600 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/IActivityTelemetryData.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace UiPath.Shared.Telemetry.Contracts +{ + internal interface IActivityTelemetryData + { + string ActivityType { get; } + + [JsonIgnore] + string ActivityPackage { get; } + + [JsonIgnore] + string ActivityPackageVersion { get; } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/IActivityTelemetryHandler.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/IActivityTelemetryHandler.cs new file mode 100644 index 000000000..cdff6d091 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/IActivityTelemetryHandler.cs @@ -0,0 +1,48 @@ +using System.Activities; + +namespace UiPath.Shared.Telemetry.Contracts +{ + internal interface IActivityTelemetryHandler + { + /// + /// Package name. + /// + string Package { get; } + + /// + /// Package version. + /// + string Version { get; } + + /// + /// Gets the event name to be used for the given activity. + ///
Method should return a value {Package_Name}.{Activity_Name}. + ///
+ /// + /// + string GetActivityEventName(Activity activity); + + /// + /// Creates a based on the given activity that is executing in the indicated context. + /// + /// + /// + /// Allows overriding the default eventName, which is the Activity Name. + /// + ExecutionOperation CreateExecutionOperation(Activity activity, ActivityContext context, string eventName = null); + + /// + /// Gets a to be used at runtime to send telemetry. + /// + /// + ITelemetryService GetRuntimeTelemetryService(); + + /// + /// Called before the given exception data is sent to telemetry. + ///
Allows activity handlers to pre-process the data to be sent. + ///
Usually, handlers should clear the property is the exception type is known with static content, or if it can contain PII (private/sensitive) data. + ///
+ /// + void PreProcessException(ActivityExceptionData exceptionData); + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ICustomTelemetryActivity.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ICustomTelemetryActivity.cs new file mode 100644 index 000000000..1c2a8657a --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ICustomTelemetryActivity.cs @@ -0,0 +1,16 @@ +using System; +using System.Activities; +using UiPath.Shared.Telemetry.Contracts; + +namespace UiPath.Shared.Telemetry +{ + internal interface ICustomTelemetryActivity + { + ExecutionOperation GetExecutionOperationData(IActivityTelemetryHandler handler, ActivityContext context); + } + + public interface ITelemetryAliasActivity + { + Type TelemetryActivityType { get; } + } +} \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ITelemetryService.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ITelemetryService.cs new file mode 100644 index 000000000..d1b01b5fc --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/ITelemetryService.cs @@ -0,0 +1,58 @@ +using TelemetryClient.Contracts; + +namespace UiPath.Shared.Telemetry.Contracts +{ + internal interface ITelemetryService + { + /// + /// Indicates whether telemetry is enabled. + /// + bool IsEnabled { get; } + + /// + /// Tracks a single telemetry event. + /// If an operation is open when the event is launched, it is added as the operation's child. + /// + /// Event to be sent. + void Track(BasicEvent basicEvent); + + /// + /// The data is sent when the returned is disposed. + /// The flag should be set before disposing the operation. + /// Duration is computed by registering timestamps when the operation is created and disposed, + /// so it should be created as soon as execution starts and disposed after it is completed. + /// Any other operation or event launched while this operation is open will be added as its child. + /// + /// + /// + IOperation Track(BasicOperation basicOperation); + + /// + /// Wraps the given event data into a with the given name and send a single telemetry event. + /// If an operation is open when the event is launched, it is added as the operation's child. + /// + /// Custom data to be reported. + /// The operation name, visible in Insights. + void TrackEvent(T data, string name = null); + + /// + /// The data is sent when the returned is disposed. + /// The flag should be set before disposing the operation. + /// Duration is computed by registering timestamps when the operation is created and disposed, + /// so it should be created as soon as execution starts and disposed after it is completed. + /// Any other operation or event launched while this operation is open will be added as its child. + /// + /// Custom data to be reported. + /// The operation name, visible in Insights. + /// A disposable operation handle. + IOperation TrackOperation(T data, string name = null); + + /// + /// Tracks mandatory data for an activity execution. + /// See for usage details. + /// + /// The telemetry data to be reported. + /// A disposable operation handle. + IOperation TrackExecutionOperation(ExecutionOperation data); + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Contracts/TelemetryCommon.cs b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/TelemetryCommon.cs new file mode 100644 index 000000000..8d59df0b3 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Contracts/TelemetryCommon.cs @@ -0,0 +1,18 @@ +namespace UiPath.Shared.Telemetry +{ + internal static class TelemetryCommon + { + internal const string DefaultContainer = "DefaultContainer"; + internal const string UiPathProxy = nameof(UiPathProxy); + + internal static readonly string Assembly; + internal static readonly string AssemblyVersion; + + static TelemetryCommon() + { + var assemblyName = typeof(TelemetryCommon).Assembly.GetName(); + Assembly = assemblyName.Name; + AssemblyVersion = assemblyName.Version.ToString(); + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/DefaultActivityTelemetryHandler.cs b/Activities/Shared/UiPath.Shared.Telemetry/DefaultActivityTelemetryHandler.cs new file mode 100644 index 000000000..996e3245c --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/DefaultActivityTelemetryHandler.cs @@ -0,0 +1,91 @@ +using System; +using System.Activities; +using UiPath.Shared.Telemetry.Contracts; +using UiPath.Shared.Telemetry.Services; + +namespace UiPath.Shared.Telemetry +{ + internal class DefaultActivityTelemetryHandler : IActivityTelemetryHandler + { + private ITelemetryService _runtimeTelemetryService; + private string _packageInferredFromActivity; + private string _packageVersionFromActivity; + + public virtual string Package => _packageInferredFromActivity; + + public virtual string Version => _packageVersionFromActivity; + + public virtual string GetActivityEventName(Activity activity) + { + var activityType = GetActivityType(activity); + + // initialize Package & Version if not set + if (Package == null || Version == null) + { + var assemblyName = activityType.Assembly.GetName(); + _packageInferredFromActivity = assemblyName.Name; + _packageVersionFromActivity = assemblyName.Version.ToString(); + } + + return $"{Package}.{RemoveGenericTypeCount(activityType.Name)}"; + } + + public virtual ExecutionOperation CreateExecutionOperation(Activity activity, ActivityContext context, string eventName = null) + { + // First, set the package and version in case it is null + var activityName = GetActivityEventName(activity); + if (activityName == null && eventName == null) + return null; + + if (activity is ICustomTelemetryActivity customTelemetryActivity) + { + return customTelemetryActivity.GetExecutionOperationData(this, context); + } + + return new ExecutionOperation(GetFullName(GetActivityType(activity)), Package, Version, eventName ?? activityName); + } + + public virtual ITelemetryService GetRuntimeTelemetryService() => + _runtimeTelemetryService ??= new RuntimeTelemetryService(); + + public virtual void PreProcessException(ActivityExceptionData exceptionData) + { + // Nothing to do + } + + /// + /// Similar to , without any generic details
+ /// Note: Using for generic types comes with undesired trailing generic details, eg. "[[System.Int32, System.Private.CoreLib, Version=6.0.0.0,Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]" + ///
+ /// + private static string GetFullName(Type type) => $"{type.Namespace}.{RemoveGenericTypeCount(type.Name)}"; + + /// + /// Remove ending generic parameter type count, if the type is generic. + ///
Input -> GenericActivity`2, output -> GenericActivity (removes ending `1, `2) + ///
+ /// + /// + private static string RemoveGenericTypeCount(string name) + { + if (name.Length > 3 && name[name.Length - 2] == '`') + return name.Substring(0, name.Length - 2); + + return name; + } + + /// + /// Gets the actual activity type, considering if implemented. + /// + /// + /// + private static Type GetActivityType(Activity activity) + { + Type type = null; + if (activity is ITelemetryAliasActivity asAliasActivity) + type = asAliasActivity.TelemetryActivityType; + + return type ?? activity.GetType(); + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/EventTracker.cs b/Activities/Shared/UiPath.Shared.Telemetry/EventTracker.cs new file mode 100644 index 000000000..ffcc974d2 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/EventTracker.cs @@ -0,0 +1,24 @@ +using System; +using System.Diagnostics; +using TelemetryClient.Contracts; +using TelemetryClient.Contracts.Model; + +namespace UiPath.Shared.Telemetry +{ + internal static class EventTracker + { + private static readonly ITelemetryClient s_telemetryClient = TelemetryProvider.GetTelemetryClient(); + + public static void Track(TelemetryEvent telemetryEvent) + { + try + { + s_telemetryClient.TrackEvent(telemetryEvent); + } + catch (Exception e) + { + Trace.TraceError(e.ToString()); + } + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/ExecutionOperation.cs b/Activities/Shared/UiPath.Shared.Telemetry/ExecutionOperation.cs new file mode 100644 index 000000000..7c79bfc28 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/ExecutionOperation.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json; +using System.Activities; +using System.Collections.Generic; +using UiPath.Shared.Telemetry.Contracts; + +namespace UiPath.Shared.Telemetry +{ + /// + /// Contains the basic telemetry properties that should be reported for activity executions. + /// In order to report additional information, derive from this class and add properties. + /// + internal class ExecutionOperation : BasicOperation, IActivityTelemetryData + { + /// + /// The operation name should be [PackageName].[ActivityName]. + /// Provide a name if the assembly name is different from the package name + /// or the activity class name is different from the activity name. + /// + public ExecutionOperation(Activity caller, ActivityContext context, string name = null) : base(name ?? caller.GetType().FullName) + { + var assemblyName = caller.GetType().Assembly.GetName(); + + ActivityType = Name; + ActivityPackage = assemblyName.Name; + ActivityPackageVersion = assemblyName.Version.ToString(); + + // To be added back after profiling support is implemented in Robot. + //ProfilingData = new ProfilingData() + //{ + // ActivityId = caller.Id, + // WorkflowInstanceId = context.WorkflowInstanceId.ToString(), + // WorkflowFilePath = context.GetExtension()?.WorkflowFilePath ?? string.Empty, + //}; + } + + public ExecutionOperation(string activityType, string activityPackage, string activityPackageVersion, string eventName = null) : base(eventName ?? activityType) + { + ActivityType = activityType; + ActivityPackage = activityPackage; + ActivityPackageVersion = activityPackageVersion; + } + + public string ActivityType { get; set; } + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public string Error { get; set; } + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public object Data { get; set; } + } + + internal class ProfilingData + { + public string ActivityId { get; set; } + + public string WorkflowInstanceId { get; set; } + + public string WorkflowFilePath { get; set; } + + public Dictionary Data { get; } = new Dictionary(); + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Properties/AssemblyInfo.cs b/Activities/Shared/UiPath.Shared.Telemetry/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..48bfa53a2 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Properties/AssemblyInfo.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +// Allow internal types to be accessed by activity assemblies for telemetry +[assembly: InternalsVisibleTo("UiPath.Database.Activities")] +[assembly: InternalsVisibleTo("UiPath.Java.Activities")] +[assembly: InternalsVisibleTo("UiPath.FTP.Activities")] +[assembly: InternalsVisibleTo("UiPath.Cryptography.Activities")] +[assembly: InternalsVisibleTo("UiPath.Python.Activities")] +[assembly: InternalsVisibleTo("UiPath.Credentials.Activities")] \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Services/DesignTimeTelemetryService.cs b/Activities/Shared/UiPath.Shared.Telemetry/Services/DesignTimeTelemetryService.cs new file mode 100644 index 000000000..1b0b22c02 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Services/DesignTimeTelemetryService.cs @@ -0,0 +1,127 @@ +//using System.Collections.Generic; +//using TelemetryClient.Contracts; +//using TelemetryClient.Contracts.Outlets; +//using TelemetryClient.Implementations.Configuration.Model; +//using TelemetryClient.Implementations.Serialization; + +//namespace UiPath.Shared.Telemetry.Services +//{ +// /// +// /// Used to capture telemetry events only at design time +// /// Does not need any reference to Platform or IWorkflowRuntime +// /// +// internal class DesignTimeTelemetryService : TelemetryServiceBase +// { +// private static ITelemetryClient s_client; + +// /// +// /// If true, telemetry is enabled +// /// +// internal static bool IsSupported { get; set; } + +// private static ITelemetryClient Client +// { +// get +// { +// if (!IsSupported) +// { +// return null; +// } + +// if (s_client == null) +// { +// s_client = CreateTelemetryClient(); +// } + +// return s_client; +// } +// } + +// protected override void TrackEventInternal(BasicEvent basicEvent) +// { +// try +// { +// Client?.TrackEvent(basicEvent); +// } +// catch +// { +// // do not trace +// } +// } + +// public override bool IsEnabled => IsSupported; + +// protected override IOperation TrackOperationInternal(BasicOperation basicOperation) +// { +// return Client?.StartOperation(basicOperation); +// } + +// protected override IOperation TrackExecutionOperationInternal(ExecutionOperation data) +// { +// // Used for activity execution, can't be used at design time. +// return null; +// } + +// private static ITelemetryClient CreateTelemetryClient() +// { +// var config = new TelemetryConfiguration +// { +// IsEnabled = true, +// ApplicationName = TelemetryCommon.Assembly, +// Outlets = new List +// { +// new DesignTimeTelemetryOutletConfiguration() +// { +// Name = TelemetryCommon.UiPathProxy, +// } +// } +// }; + +// var container = new TelemetryConfigurationContainer +// { +// Name = TelemetryCommon.DefaultContainer, +// DefaultEventOutlet = TelemetryCommon.UiPathProxy, +// DefaultOperationOutlet = TelemetryCommon.UiPathProxy, +// }; + +// config.Containers.Add(container); +// return new TelemetryClientBuilder() +// .WithConfig(config) +// .Build(); +// } +// } + +// [OutletType(typeof(DesignTimeTelemetryOutlet))] +// internal class DesignTimeTelemetryOutletConfiguration : OutletConfiguration +// { +// } + +// internal class DesignTimeTelemetryOutlet : IOutlet +// { +// private readonly TelemetrySerializer _telemetrySerializer = new TelemetrySerializer(); +// private readonly ITelemetryProxy _designTelemetryProxy; + +// public string Name => nameof(DesignTimeTelemetryOutlet); + +// public Outlet PushOperation => Export; + +// public Outlet PushEvent => Export; + +// public DesignTimeTelemetryOutlet() +// { +// _designTelemetryProxy = new LegacyDesignerContract().TryInvoke(c => c.UnSafe().TelemetryProxy); +// } + +// // All custom outlets must have a constructor with an OutletConfiguration. +// public DesignTimeTelemetryOutlet(DesignTimeTelemetryOutletConfiguration config) +// : this() +// { +// } + +// public void Export(ITelemetry telemetry) +// { +// var serializedTelemetry = _telemetrySerializer.Serialize(telemetry); +// _designTelemetryProxy?.Send(serializedTelemetry); +// } +// } +//} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Services/RuntimeTelemetryService.cs b/Activities/Shared/UiPath.Shared.Telemetry/Services/RuntimeTelemetryService.cs new file mode 100644 index 000000000..5ac558d06 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Services/RuntimeTelemetryService.cs @@ -0,0 +1,70 @@ +using System; +using System.Activities; +using System.Linq; +using System.Reflection; +using UiPath.Shared.Activities; +using UiPath.Shared.Telemetry.Contracts; + +namespace UiPath.Shared.Telemetry.Services +{ + internal class RuntimeTelemetryService : TelemetryService + { + private static IActivityTelemetryHandler s_activityTelemetryHandler; + + public static ITelemetryOperationWrapper CreateExecutionOperation(Activity activity, ActivityContext context, string eventName = null) + { + var telemetryHandler = GetActivityTelemetryHandler(); + var service = telemetryHandler?.GetRuntimeTelemetryService(); + if (service == null || !service.IsEnabled) + return null; + + var operation = telemetryHandler.CreateExecutionOperation(activity, context, eventName); + if (operation == null) + return null; + + var iOperation = service.TrackExecutionOperation(operation); + return new TelemetryOperationWrapper(telemetryHandler, operation, iOperation); + } + + internal static IActivityTelemetryHandler GetActivityTelemetryHandler() => + s_activityTelemetryHandler ?? (s_activityTelemetryHandler = CreateActivityTelemetryHandler()); + + private static IActivityTelemetryHandler CreateActivityTelemetryHandler() + { + // get a hold of our assembly + var assembly = typeof(RuntimeTelemetryService).Assembly; + + // search the type for our IActivityTelemetryHandler + var refType = GetActivityTelemetryHandlerTypeByAssemblyAttribute(assembly) ?? typeof(DefaultActivityTelemetryHandler); + + try + { + return Activator.CreateInstance(refType) as IActivityTelemetryHandler; + } + catch (Exception ex) + { + System.Diagnostics.Trace.TraceError(ex.ToString()); + return null; + } + } + + /// + /// Gets the Type to be used as ActivityTelemetryHandler by searching for an AssemblyMetadataAttribute with RuntimeActivityTelemetryHandler key. + /// + /// + /// + private static Type GetActivityTelemetryHandlerTypeByAssemblyAttribute(Assembly assembly) + { + try + { + var attribute = assembly.GetCustomAttributes().FirstOrDefault(a => a.Key == "RuntimeActivityTelemetryHandler"); + return attribute == null ? null : assembly.GetType(attribute.Value); + } + catch (Exception ex) + { + System.Diagnostics.Trace.TraceError(ex.ToString()); + return null; + } + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Services/TelemetryService.cs b/Activities/Shared/UiPath.Shared.Telemetry/Services/TelemetryService.cs new file mode 100644 index 000000000..402479d95 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Services/TelemetryService.cs @@ -0,0 +1,40 @@ +using TelemetryClient.Contracts; + +namespace UiPath.Shared.Telemetry.Services +{ + internal class TelemetryService : TelemetryServiceBase + { + public override bool IsEnabled => TelemetryProvider.IsSupported; + + protected override IOperation TrackOperationInternal(BasicOperation operation) + { + if (!TelemetryProvider.IsSupported) + return null; + + return TelemetryProvider.Client.StartOperation(operation); + } + + protected override IOperation TrackExecutionOperationInternal(ExecutionOperation data) + { + if (!TelemetryProvider.IsSupported) + return null; + + return TelemetryProvider.Client.StartOperation(data); + } + + protected override void TrackEventInternal(BasicEvent basicEvent) + { + if (!TelemetryProvider.IsSupported) + return; + + try + { + TelemetryProvider.Client.TrackEvent(basicEvent); + } + catch + { + // do not trace + } + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/Services/TelemetryServiceBase.cs b/Activities/Shared/UiPath.Shared.Telemetry/Services/TelemetryServiceBase.cs new file mode 100644 index 000000000..d916aac65 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/Services/TelemetryServiceBase.cs @@ -0,0 +1,43 @@ +using TelemetryClient.Contracts; + +namespace UiPath.Shared.Telemetry.Services +{ + internal abstract class TelemetryServiceBase : Contracts.ITelemetryService + { + private const string TagEvent = "Event"; + + public abstract bool IsEnabled { get; } + + public void Track(BasicEvent basicEvent) => TrackEventInternal(basicEvent); + + /// + /// Track event with name generated based on the type name, without ending "Event", eg. IndicateCardEvent => IndicateCard
+ ///
+ /// + /// + /// + public void TrackEvent(T data, string name = null) => TrackEventInternal(new BasicEvent(name ?? GetEventName(data), data)); + + public IOperation Track(BasicOperation basicOperation) => TrackOperationInternal(basicOperation); + + public IOperation TrackOperation(T data, string name = null) => TrackOperationInternal(new BasicOperation(name ?? GetOperationName(data), data)); + + public IOperation TrackExecutionOperation(ExecutionOperation data) => TrackExecutionOperationInternal(data); + + private string GetOperationName(T data) + { + return data.GetType().Name; + } + + private string GetEventName(T data) => GetEventName(data.GetType().Name); + + private string GetEventName(string typeName) => + typeName.EndsWith(TagEvent) ? typeName.Remove(typeName.Length - TagEvent.Length) : typeName; + + protected abstract IOperation TrackOperationInternal(BasicOperation operation); + + protected abstract IOperation TrackExecutionOperationInternal(ExecutionOperation data); + + protected abstract void TrackEventInternal(BasicEvent basicEvent); + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOperationWrapper.cs b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOperationWrapper.cs new file mode 100644 index 000000000..49091172a --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOperationWrapper.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using TelemetryClient.Contracts; +using UiPath.Shared.Activities; +using UiPath.Shared.Telemetry.Contracts; + +namespace UiPath.Shared.Telemetry +{ + internal class TelemetryOperationWrapper : ITelemetryOperationWrapper + { + private readonly IActivityTelemetryHandler _telemetryHandler; + private readonly IOperation _operation; + + private bool _isSent; + + public TelemetryOperationWrapper(IActivityTelemetryHandler telemetryHandler, ExecutionOperation executionOperation, IOperation operation) + { + _telemetryHandler = telemetryHandler; + _operation = operation; + ExecutionOperation = executionOperation; + } + + public ExecutionOperation ExecutionOperation { get; } + + public void SendWithException(Exception ex) + { + if (_isSent) + return; + + // create exception data to send + var exceptionData = ActivityExceptionData.From($"{ExecutionOperation.Name}Error", ExecutionOperation, ex); + + // get service & ensure we can send telemetry + var service = _telemetryHandler.GetRuntimeTelemetryService(); + if (service?.IsEnabled == true) + { + // allow handler to pre-process the exception + _telemetryHandler.PreProcessException(exceptionData); + + // send event exception + service.Track(exceptionData); + } + + // ensure we set the Error property accordingly + ExecutionOperation.Error = exceptionData.Error; + + Send(); + } + + public void Send() + { + if (_isSent) + return; + + _isSent = true; + + if (ExecutionOperation.Error != null) + _operation.Success = false; + + // dispose will auto-send it to the telemetry + _operation.Dispose(); + } + + public void SetCustomData(object value) + { + ExecutionOperation.Data = value; + } + + public void SetCustomDataKey(string key, object value) + { + if (ExecutionOperation.Data is not Dictionary dataDict) + { +#if DEBUG + if (ExecutionOperation.Data != null) + throw new NotSupportedException("Existing custom data will be lost. Using both SetCustomData and SetCustomDataKey is not supported"); +#endif + + dataDict = new Dictionary(); + ExecutionOperation.Data = dataDict; + } + + dataDict[key] = value; + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOutlet.cs b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOutlet.cs new file mode 100644 index 000000000..06ce6d950 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOutlet.cs @@ -0,0 +1,53 @@ +using System; +using System.Diagnostics; +using TelemetryClient.Contracts; +using TelemetryClient.Contracts.Outlets; +using TelemetryClient.Implementations.Serialization; +using UiPath.Activities.Contracts; +using UiPath.Activities.Contracts.Telemetry; +using UiPath.Shared.Contracts.Private; + + +//uipath.platform + +namespace UiPath.Shared.Telemetry +{ + internal class TelemetryOutlet : IOutlet + { + private readonly TelemetrySerializer _telemetrySerializer = new TelemetrySerializer(); + private readonly ITelemetryProxy _runtimeTelemetryProxy; + private readonly ITelemetryProxy _designTelemetryProxy; + + public TelemetryOutlet(TelemetryOutletConfiguration configuration) + { + _designTelemetryProxy = new LegacyDesignerContract().TryInvoke(c => c.UnSafe().TelemetryProxy); + + PrivateRuntimeContract contract; + try + { + var api = Platform.ServiceResolver.Default?.Resolve(); + contract = new PrivateRuntimeContract(api); + } + catch (Exception ex) + { + Trace.TraceError(ex.ToString()); + contract = new PrivateRuntimeContract(null); + } + _runtimeTelemetryProxy = contract.TryInvoke(c => c.UnSafe().TelemetryProxy); + } + + public string Name => nameof(TelemetryOutlet); + + public Outlet PushOperation => Export; + + public Outlet PushEvent => Export; + + public void Export(ITelemetry telemetry) + { + var serializedTelemetry = _telemetrySerializer.Serialize(telemetry); + + _designTelemetryProxy?.Send(serializedTelemetry); + _runtimeTelemetryProxy?.Send(serializedTelemetry); + } + } +} \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOutletConfiguration.cs b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOutletConfiguration.cs new file mode 100644 index 000000000..f67a070ad --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryOutletConfiguration.cs @@ -0,0 +1,10 @@ +using TelemetryClient.Contracts.Outlets; +using TelemetryClient.Implementations.Configuration.Model; + +namespace UiPath.Shared.Telemetry +{ + [OutletType(typeof(TelemetryOutlet))] + internal class TelemetryOutletConfiguration : OutletConfiguration + { + } +} \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Telemetry/TelemetryProvider.cs b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryProvider.cs new file mode 100644 index 000000000..26f06afbc --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/TelemetryProvider.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using TelemetryClient.Contracts; +using TelemetryClient.Implementations.Configuration.Model; +using UiPath.Shared.Telemetry.Contracts; + +namespace UiPath.Shared.Telemetry +{ + internal static class TelemetryProvider + { + private static ITelemetryClient s_client; + private static TelemetryOutletConfiguration s_telemetryOutletConfiguration; + + public static bool IsSupported { get; set; } + + static TelemetryProvider() + { + try + { + // check runtime, when started by the robot + IsSupported = true; + } + catch + { + // do not trace exception + IsSupported = false; + } + } + + internal static TelemetryOutletConfiguration TelemetryOutletConfiguration + { + get + { + if (s_telemetryOutletConfiguration == null) + { + s_telemetryOutletConfiguration = new TelemetryOutletConfiguration + { + Name = TelemetryCommon.UiPathProxy, + }; + } + + return s_telemetryOutletConfiguration; + } + } + + internal static ITelemetryClient Client + { + get + { + if (IsSupported && s_client == null) + { + s_client = GetTelemetryClient(); + } + + return s_client; + } + } + + internal static ITelemetryClient GetTelemetryClient() + { + var config = new TelemetryConfiguration + { + IsEnabled = true, + ApplicationName = TelemetryCommon.Assembly, + Outlets = new List + { + TelemetryOutletConfiguration + } + }; + + var container = new TelemetryConfigurationContainer + { + Name = TelemetryCommon.DefaultContainer, + DefaultEventOutlet = TelemetryCommon.UiPathProxy, + DefaultOperationOutlet = TelemetryCommon.UiPathProxy, + }; + + config.Containers.Add(container); + return new TelemetryClientBuilder() + .WithConfig(config) + .Build(); + } + } +} \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Telemetry/UiPath.Shared.Telemetry.projitems b/Activities/Shared/UiPath.Shared.Telemetry/UiPath.Shared.Telemetry.projitems new file mode 100644 index 000000000..27b9cc603 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/UiPath.Shared.Telemetry.projitems @@ -0,0 +1,33 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 58b0d9da-673e-4e61-9497-fea04e51a90e + + + UiPath.Shared.Telemetry + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Activities/Shared/UiPath.Shared.Telemetry/UiPath.Shared.Telemetry.shproj b/Activities/Shared/UiPath.Shared.Telemetry/UiPath.Shared.Telemetry.shproj new file mode 100644 index 000000000..e84a27497 --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Telemetry/UiPath.Shared.Telemetry.shproj @@ -0,0 +1,13 @@ + + + + 58b0d9da-673e-4e61-9497-fea04e51a90e + 14.0 + + + + + + + +