From 3b8aa350c1280f8d00c979f2c353c8fafb30256f Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 18 Jul 2023 19:44:50 -0300 Subject: [PATCH 01/10] Azure Event Grid API implementation --- dotnet/DotNetStandardClasses.sln | 14 + .../GxClasses/Properties/AssemblyInfo.cs | 1 + .../GXAzureEventGrid/AzureEventGrid.cs | 305 ++++++++++++++++++ .../EventGridRouterProvider.cs | 23 ++ .../GXAzureEventGrid/GXAzureEventGrid.csproj | 17 + .../GXAzureQueue/GXAzureQueue.csproj | 2 +- .../GXAzureServiceBus.csproj | 2 +- .../Messaging/GXEventRouter/EventRouter.cs | 25 ++ .../GXEventRouter/EventRouterBase.cs | 33 ++ .../GXEventRouter/EventRouterProvider.cs | 115 +++++++ .../GXEventRouter/EventRouterProviderBase.cs | 234 ++++++++++++++ .../GXEventRouter/GXEventRouter.csproj | 17 + .../GXEventRouter/PropertyConstants.cs | 17 + .../Messaging/GXQueue/GXQueue.csproj | 4 + .../Messaging/GXQueue/ServiceSettings.cs | 101 ------ .../GxClasses/Services/Storage/GXServices.cs | 1 + 16 files changed, 808 insertions(+), 103 deletions(-) create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterBase.cs create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/GXEventRouter.csproj create mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/PropertyConstants.cs delete mode 100644 dotnet/src/dotnetcore/Providers/Messaging/GXQueue/ServiceSettings.cs diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 8650b334f..4822f78c0 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -243,6 +243,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GxOffice", "src\dotnetcore\ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "excel", "excel", "{B521FF6D-E081-4DE6-AC00-A9BE3B6439D1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GXEventRouter", "src\dotnetcore\Providers\Messaging\GXEventRouter\GXEventRouter.csproj", "{5BBC75F0-E51A-4EBD-A628-92498D319B1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GXAzureEventGrid", "src\dotnetcore\Providers\Messaging\GXAzureEventGrid\GXAzureEventGrid.csproj", "{7250CDB1-95C4-4822-B01B-3CBD73324CC9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -585,6 +589,14 @@ Global {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Debug|Any CPU.Build.0 = Debug|Any CPU {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Release|Any CPU.Build.0 = Release|Any CPU + {5BBC75F0-E51A-4EBD-A628-92498D319B1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5BBC75F0-E51A-4EBD-A628-92498D319B1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5BBC75F0-E51A-4EBD-A628-92498D319B1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5BBC75F0-E51A-4EBD-A628-92498D319B1D}.Release|Any CPU.Build.0 = Release|Any CPU + {7250CDB1-95C4-4822-B01B-3CBD73324CC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7250CDB1-95C4-4822-B01B-3CBD73324CC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7250CDB1-95C4-4822-B01B-3CBD73324CC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7250CDB1-95C4-4822-B01B-3CBD73324CC9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -701,6 +713,8 @@ Global {BE108BE8-805D-4FCF-86BA-B2EAF581FFB2} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82} = {B521FF6D-E081-4DE6-AC00-A9BE3B6439D1} {B521FF6D-E081-4DE6-AC00-A9BE3B6439D1} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} + {5BBC75F0-E51A-4EBD-A628-92498D319B1D} = {4C43F2DA-59E5-46F5-B691-195449498555} + {7250CDB1-95C4-4822-B01B-3CBD73324CC9} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs b/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs index 2109ab09c..80e2eff77 100644 --- a/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs +++ b/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs @@ -7,6 +7,7 @@ [assembly: InternalsVisibleTo("AzureFunctionsTest")] [assembly: InternalsVisibleTo("GXQueue")] [assembly: InternalsVisibleTo("GXMessageBroker")] +[assembly: InternalsVisibleTo("GXEventRouter")] [assembly: InternalsVisibleTo("DotNetCoreUnitTest")] [assembly: InternalsVisibleTo("DotNetCoreWebUnitTest")] [assembly: InternalsVisibleTo("GeneXus.Deploy.AzureFunctions.Handlers")] diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs new file mode 100644 index 000000000..694a691fe --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs @@ -0,0 +1,305 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.Messaging; +using Azure.Messaging.EventGrid; +using GeneXus.Messaging.Common; +using GeneXus.Services; +using GeneXus.Utils; + +namespace GeneXus.Messaging.GXAzureEventGrid +{ + public class AzureEventGrid : EventRouterBase, IEventRouter + { + public static string Name = "AZUREEVENTGRID"; + private EventGridPublisherClient _client; + private string _endpoint; + private string _accessKey; + public AzureEventGrid() : this(null) + { + } + public AzureEventGrid(GXService providerService) : base(providerService) + { + Initialize(providerService); + } + private void Initialize(GXService providerService) + { + ServiceSettings serviceSettings = new(PropertyConstants.EVENT_ROUTER, Name, providerService); + _endpoint = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.URI_ENDPOINT); + _accessKey = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.ACCESS_KEY); + _client = new EventGridPublisherClient( + new Uri(_endpoint), + new AzureKeyCredential(_accessKey)); + } + public override string GetName() + { + return Name; + } + + public bool SendEvent(GXCloudEvent gxCloudEvent, bool binaryData) + { + CloudEvent evt = ToCloudEvent(gxCloudEvent, binaryData); + bool success = false; + try + { + Task task; + if (_client != null) + { + task = Task.Run(async () => await sendEvtAsync(evt).ConfigureAwait(false)); + success = task.Result; + } + else + { + throw new Exception("SendEvent: There was an error at the Event Grid initialization."); + } + } + catch (AggregateException ae) + { + throw ae; + } + return success; + } + public bool SendEvents(IList gxCloudEvents, bool binaryData) + { + List evts = new List(); + foreach (GXCloudEvent e in gxCloudEvents) + evts.Add(ToCloudEvent(e, binaryData)); + + bool success = false; + try + { + Task task; + if (_client != null) + { + task = Task.Run(async () => await sendEvtsAsync(evts).ConfigureAwait(false)); + success = task.Result; + } + else + { + throw new Exception("SendEvents: There was an error at the Event Grid initialization."); + } + } + catch (AggregateException ae) + { + throw ae; + } + return success; + } + public bool SendCustomEvents(string jsonString, bool isBinary) + { + if (string.IsNullOrEmpty(jsonString)) + { + throw new Exception("Events cannot be empty."); + } + try + { + List evts = JsonSerializer.Deserialize>(jsonString); + + IList eventGridEvents = new List(); + foreach (GXEventGridSchema e in evts) + eventGridEvents.Add(ToEventGridSchema(e,isBinary)); + + bool success = false; + try + { + Task task; + if (_client != null) + { + task = Task.Run(async () => await sendEventGridSchemaEventsAsync(eventGridEvents).ConfigureAwait(false)); + success = task.Result; + } + else + { + throw new Exception("There was an error at the Event Grid initialization."); + } + } + catch (AggregateException ae) + { + throw ae; + } + return success; + } + catch (JsonException) + { + try + { + GXEventGridSchema evt = JsonSerializer.Deserialize(jsonString); + bool success = false; + try + { + Task task; + if (_client != null) + { + task = Task.Run(async () => await sendEventGridSchemaEventAsync(ToEventGridSchema(evt, isBinary)).ConfigureAwait(false)); + success = task.Result; + } + else + { + throw new Exception("There was an error at the Event Grid initialization."); + } + } + catch (AggregateException ae) + { + throw ae; + } + return success; + } + catch (JsonException) + { + throw new Exception("jsonEvents parameter format is no correct. Valid format is AzureEventGrid.EventGridSchema SDT."); + } + } + } + + #region Async methods + /// + /// Send asynchronously an event formatted as Azure EventGrid Schema. + /// + /// + /// + private async Task sendEventGridSchemaEventAsync(EventGridEvent evt) + { + try + { + await _client.SendEventAsync(evt).ConfigureAwait(false); + return true; + } + catch (Exception ex) + { + throw ex; + } + } + /// + /// Send asynchronously a list of events formatted as Azure EventGrid Schema. + /// + /// + /// + private async Task sendEventGridSchemaEventsAsync(IEnumerable evts) + { + try + { + await _client.SendEventsAsync(evts).ConfigureAwait(false); + return true; + } + catch (Exception ex) + { + throw ex; + } + } + /// + /// Send asynchronously an event formatted as CloudEvent Schema. + /// + /// + /// + private async Task sendEvtAsync(CloudEvent cloudEvent) + { + try + { + await _client.SendEventAsync(cloudEvent).ConfigureAwait(false); + return true; + } + catch (Exception ex) + { + throw ex; + } + } + /// + /// Send asynchronously a list of CloudEvent Schema formatted events. + /// + /// + /// + private async Task sendEvtsAsync(IEnumerable cloudEvents) + { + try + { + await _client.SendEventsAsync(cloudEvents).ConfigureAwait(false); + return true; + } + catch (Exception ex) + { + throw ex; + } + } + + #endregion + + #region TransformMethods + public bool GetMessageFromException(Exception ex, SdtMessages_Message msg) + { + try + { + HttpListenerException az_ex = (HttpListenerException)ex; + msg.gxTpr_Id = az_ex.ErrorCode.ToString(); + msg.gxTpr_Description = az_ex.Message; + return true; + } + catch (Exception) + { + return false; + } + } + private EventGridEvent ToEventGridSchema(GXEventGridSchema gxEventGridSchema, bool isBinary) + { + EventGridEvent evt; + if (isBinary && !string.IsNullOrEmpty(gxEventGridSchema.data)) + { + BinaryData binaryData = new BinaryData(gxEventGridSchema.data); + evt = new EventGridEvent(gxEventGridSchema.subject, gxEventGridSchema.eventtype, gxEventGridSchema.dataversion, binaryData);} + else + evt = new EventGridEvent(gxEventGridSchema.subject, gxEventGridSchema.eventtype, gxEventGridSchema.dataversion, gxEventGridSchema.data, null); + if (!string.IsNullOrEmpty(gxEventGridSchema.id)) + evt.Id = gxEventGridSchema.id; + if (!string.IsNullOrEmpty(gxEventGridSchema.topic)) + evt.Topic = gxEventGridSchema.topic; + + return evt; + } + private CloudEvent ToCloudEvent(GXCloudEvent gxCloudEvent, bool isBinaryData) + { + CloudEvent evt; + if (string.IsNullOrEmpty(gxCloudEvent.data)) + evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, null); + else + { + if (!isBinaryData) + evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, gxCloudEvent.data); + else + { + if (string.IsNullOrEmpty(gxCloudEvent.datacontenttype)) + gxCloudEvent.datacontenttype = "application/octet-stream"; + evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, BinaryData.FromString(gxCloudEvent.data), gxCloudEvent.datacontenttype,CloudEventDataFormat.Binary); + } + } + if (!string.IsNullOrEmpty(gxCloudEvent.id)) + evt.Id = gxCloudEvent.id; + if (!string.IsNullOrEmpty(gxCloudEvent.dataschema)) + evt.DataSchema = gxCloudEvent.dataschema; + if (!string.IsNullOrEmpty(gxCloudEvent.subject)) + evt.Subject = gxCloudEvent.subject; + return evt; + } + #endregion + } + + [DataContract] + public class GXEventGridSchema + { + [DataMember] + public string topic { get; set; } + [DataMember] + public string eventtype { get; set; } + [DataMember] + public string id { get; set; } + [DataMember] + public string subject { get; set; } + [DataMember] + public string data { get; set; } + [DataMember] + public string dataversion { get; set; } + + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs new file mode 100644 index 000000000..1cbba3e37 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs @@ -0,0 +1,23 @@ +using GeneXus.Messaging.Common; +using GeneXus.Utils; + +namespace GeneXus.Messaging.GXAzureEventGrid +{ + public class EventGridRouterProvider + { + public EventRouterProviderBase Connect(string endpoint, string accesskey, out GXBaseCollection errorMessages, out bool success) + { + EventRouterProvider eventRouterProvider = new EventRouterProvider(); + GXProperties properties = new GXProperties + { + { PropertyConstants.EVENTROUTER_AZUREEG_ENDPOINT, endpoint }, + { PropertyConstants.EVENTROUTER_AZUREEG_ACCESS_KEY, accesskey } + }; + + EventRouterProviderBase evtRouterProvider = eventRouterProvider.Connect(PropertyConstants.AZUREEVENTGRID, properties, out GXBaseCollection errorMessagesConnect, out bool successConnect); + errorMessages = errorMessagesConnect; + success = successConnect; + return evtRouterProvider; + } + } +} diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj new file mode 100644 index 000000000..0dd71f20c --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + GeneXus.Azure.EventGrid + Azure EventGrid Messaging + + + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj index a9fc132d3..491be781c 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj @@ -7,7 +7,7 @@ - + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj index ac8137a4a..2de414bc5 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj @@ -7,7 +7,7 @@ - + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs new file mode 100644 index 000000000..4c1584efe --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs @@ -0,0 +1,25 @@ +using GeneXus.Utils; +using System.Collections.Generic; +using System; + +namespace GeneXus.Messaging.Common +{ + public interface IEventRouter + { + bool SendEvent(GXCloudEvent gxCloudEvent, bool binaryData); + bool SendEvents(IList gxCloudEvents, bool binaryData); + bool SendCustomEvents(string jsonString, bool isBinary); + bool GetMessageFromException(Exception ex, SdtMessages_Message msg); + } + public class GXCloudEvent : GxUserType + { + public string type { get; set; } + public string source { get; set; } + public string data { get; set; } + public string datacontenttype { get; set; } + public string id { get; set; } + public string dataschema { get; set; } + public string subject { get; set; } + } + +} \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterBase.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterBase.cs new file mode 100644 index 000000000..d8db3aeb0 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterBase.cs @@ -0,0 +1,33 @@ +using System; +using GeneXus.Services; +using log4net; + +namespace GeneXus.Messaging.Common +{ + public abstract class EventRouterBase + { + static readonly ILog logger = LogManager.GetLogger(typeof(EventRouterBase)); + internal GXService service; + public EventRouterBase() + { + } + + public EventRouterBase(GXService s) + { + if (s == null) + { + try + { + s = ServiceFactory.GetGXServices()?.Get(GXServices.EVENTROUTER_SERVICE); + } + catch (Exception) + { + GXLogging.Warn(logger, "EVENTROUTER_SERVICE is not activated"); + } + } + + service = s; + } + public abstract string GetName(); + } +} diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs new file mode 100644 index 000000000..bc959dfae --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs @@ -0,0 +1,115 @@ +using System; +using GeneXus.Attributes; +using GeneXus.Encryption; +using GeneXus.Services; +using GeneXus.Utils; +using GxClasses.Helpers; +using log4net; + +namespace GeneXus.Messaging.Common +{ + [GXApi] + public class EventRouterProvider : EventRouterProviderBase + { + static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static GXService providerService; + public EventRouterProvider() + { + + } + public EventRouterProviderBase Connect(string providerTypeName, GXProperties properties, out GXBaseCollection errorMessages, out bool success) + { + errorMessages = new GXBaseCollection(); + EventRouterProviderBase eventRouter = new EventRouterProviderBase(); + if (string.IsNullOrEmpty(providerTypeName)) + { + GXUtil.ErrorToMessages("GXEventRouter", "Event Router provider cannot be empty", errorMessages); + GXLogging.Error(logger, "(GXEventRouter)Failed to Connect to a Event Router : Provider cannot be empty."); + success = false; + return eventRouter; + } + try + { + if (providerService == null || !string.Equals(providerService.Name, providerTypeName, StringComparison.OrdinalIgnoreCase)) + { + providerService = new GXService(); + providerService.Type = GXServices.EVENTROUTER_SERVICE; + providerService.Name = providerTypeName; + providerService.AllowMultiple = false; + providerService.Properties = new GXProperties(); + } + Preprocess(providerTypeName, properties); + + GxKeyValuePair prop = properties.GetFirst(); + while (!properties.Eof()) + { + providerService.Properties.Set(prop.Key, prop.Value); + prop = properties.GetNext(); + } + + string typeFullName = providerService.ClassName; + GXLogging.Debug(logger, "Loading Event Router provider: " + typeFullName); + Type type = AssemblyLoader.GetType(typeFullName); + eventRouter.eventRouter = (IEventRouter)Activator.CreateInstance(type, new object[] { providerService }); + + } + catch (Exception ex) + { + GXLogging.Error(logger, "(GXEventRouter)Couldn't connect to Event Router provider: " + ExceptionExtensions.GetInnermostException(ex)); + GXUtil.ErrorToMessages("GXEventRouter", ex, errorMessages); + success = false; + return eventRouter; + } + success = true; + return (eventRouter); + } + private static void Preprocess(string name, GXProperties properties) + { + string className; + + switch (name) + { + case Providers.AzureEventGrid: + className = PropertyConstants.AZURE_EG_CLASSNAME; + SetEncryptedProperty(properties, PropertyConstants.EVENTROUTER_AZUREEG_ENDPOINT); + SetEncryptedProperty(properties, PropertyConstants.EVENTROUTER_AZUREEG_ACCESS_KEY); + if (string.IsNullOrEmpty(providerService.ClassName) || !providerService.ClassName.Contains(className)) + { + providerService.ClassName = PropertyConstants.AZURE_EG_PROVIDER_CLASSNAME; + } + break; + default: + throw new SystemException(string.Format("Provider {0} is not supported.", name)); + } + } + private static void SetEncryptedProperty(GXProperties properties, string prop) + { + string value = properties.Get(prop); + if (string.IsNullOrEmpty(value)) + value = string.Empty; + value = CryptoImpl.Encrypt(value); + properties.Set(prop, value); + } + + } + public static class ExceptionExtensions + { + public static string GetInnermostException(Exception e) + { + Exception ex = e; + if (ex != null) + { + while (ex.InnerException != null) + { + ex = ex.InnerException; + } + + } + return ex.Message; + } + } + static class Providers + { + public const string AzureEventGrid = "AZUREEVENTGRID"; + } +} diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs new file mode 100644 index 000000000..90f9b914c --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using GeneXus.Services; +using GeneXus.Utils; +using GxClasses.Helpers; +using log4net; + +namespace GeneXus.Messaging.Common +{ + public class EventRouterProviderBase + { + internal IEventRouter eventRouter = null; + public static Assembly assembly; + static readonly ILog logger = LogManager.GetLogger(typeof(EventRouterProviderBase)); + private const string MODULE_DLL = @"GeneXusEventMessaging"; + + public EventRouterProviderBase() + { + } + public EventRouterProviderBase(EventRouterProviderBase other) + { + eventRouter = other.eventRouter; + } + void ValidQueue() + { + if (eventRouter == null) + { + GXLogging.Error(logger, "Event Router was not instantiated."); + throw new Exception("Event Router was not instantiated."); + } + } + private static Assembly LoadAssembly(string fileName) + { + if (File.Exists(fileName)) + { + Assembly assemblyLoaded = Assembly.LoadFrom(fileName); + return assemblyLoaded; + } + else + return null; + } + + private static void LoadAssemblyIfRequired() + { + if (assembly == null) + { + assembly = AssemblyLoader.LoadAssembly(new AssemblyName(MODULE_DLL)); + } + } + + public bool SendEvent(GxUserType evt, bool binaryData, out GXBaseCollection errorMessages) + { + bool success = false; + errorMessages = new GXBaseCollection(); + try + { + GXCloudEvent gxCloudEvent = ToGXCloudEvent(evt); + LoadAssemblyIfRequired(); + try + { + ValidQueue(); + if (eventRouter != null) + return(eventRouter.SendEvent(gxCloudEvent, binaryData)); + } + catch (Exception ex) + { + EventRouterErrorMessagesSetup(ex, out errorMessages); + success = false; + GXLogging.Error(logger, ex); + } + } + catch (Exception ex) + { + success = false; + GXLogging.Error(logger,ex); + throw ex; + } + return success; + } + + public bool SendCustomEvents(string evts, bool isBinary, out GXBaseCollection errorMessages) + { + errorMessages = new GXBaseCollection(); + bool success; + try + { + ValidQueue(); + success = eventRouter.SendCustomEvents(evts, isBinary); + } + catch (Exception ex) + { + EventRouterErrorMessagesSetup(ex, out errorMessages); + success = false; + GXLogging.Error(logger, ex); + } + return success; + } + + public bool SendEvents(IList evts, bool binaryData, out GXBaseCollection errorMessages) + { + errorMessages = new GXBaseCollection(); + bool success = false; + LoadAssemblyIfRequired(); + try + { + IList gxCloudEvents = new List(); + foreach (GxUserType e in evts) + { + if (ToGXCloudEvent(e) is GXCloudEvent gxCloudEvent) + gxCloudEvents.Add(gxCloudEvent); + } + try + { + ValidQueue(); + success = eventRouter.SendEvents(gxCloudEvents, binaryData); + } + catch (Exception ex) + { + EventRouterErrorMessagesSetup(ex, out errorMessages); + success = false; + GXLogging.Error(logger, ex); + } + } + catch (Exception ex) + { + GXLogging.Error(logger, ex); + throw ex; + } + return success; + } + + #region Transform operations + protected void EventRouterErrorMessagesSetup(Exception ex, out GXBaseCollection errorMessages) + { + errorMessages = new GXBaseCollection(); + bool foundGeneralException = false; + if (errorMessages != null && ex != null) + { + SdtMessages_Message msg = new SdtMessages_Message(); + if (eventRouter != null) + { + while (ex.InnerException != null) + { + if (eventRouter.GetMessageFromException(ex.InnerException, msg)) + { + msg.gxTpr_Type = 1; + errorMessages.Add(msg); + } + else + { + foundGeneralException = true; + break; + } + ex = ex.InnerException; + } + if (foundGeneralException) + GXUtil.ErrorToMessages("GXEventRouter1002", ex, errorMessages); + } + else + { + GXUtil.ErrorToMessages("GXEventRouter1002", ex, errorMessages); + } + } + } + private GXCloudEvent ToGXCloudEvent(GxUserType evt) + { + if (evt != null) + { + GXCloudEvent gxCloudEvent = new GXCloudEvent(); + gxCloudEvent.type = evt.GetPropertyValue("Type"); + gxCloudEvent.source = evt.GetPropertyValue("Source"); + gxCloudEvent.data = evt.GetPropertyValue("Data"); + gxCloudEvent.datacontenttype = evt.GetPropertyValue("Datacontenttype"); + gxCloudEvent.id = evt.GetPropertyValue("Id"); + gxCloudEvent.subject = evt.GetPropertyValue("Subject"); + gxCloudEvent.dataschema = evt.GetPropertyValue("Dataschema"); + return gxCloudEvent; + } + return null; + } + #endregion + + } + internal class ServiceFactory + { + private static IEventRouter eventRouter; + private static readonly ILog log = log4net.LogManager.GetLogger(typeof(GeneXus.Services.ServiceFactory)); + + public static GXServices GetGXServices() + { + return GXServices.Instance; + } + + public static IEventRouter GetEventRouter() + { + if (eventRouter == null) + { + eventRouter = GetRouterImpl(GXServices.EVENTROUTER_SERVICE); + } + return eventRouter; + } + + public static IEventRouter GetRouterImpl(string service) + { + IEventRouter eventRouterImpl = null; + if (GetGXServices() != null) + { + GXService providerService = GetGXServices()?.Get(service); + if (providerService != null) + { + try + { + string typeFullName = providerService.ClassName; + GXLogging.Debug(log, "Loading Event Router settings:", typeFullName); + Type type = AssemblyLoader.GetType(typeFullName); + eventRouterImpl = (IEventRouter)Activator.CreateInstance(type); + } + catch (Exception e) + { + GXLogging.Error(log, "Couldn't connect to the Event Router.", e.Message, e); + throw e; + } + } + } + return eventRouterImpl; + } + } +} + + + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/GXEventRouter.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/GXEventRouter.csproj new file mode 100644 index 000000000..d1e59a220 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/GXEventRouter.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + GeneXus.Message.EventRouter + Event Bus Messaging Router + TRACE;DEBUG;NETCORE + + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/PropertyConstants.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/PropertyConstants.cs new file mode 100644 index 000000000..2aed7d804 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/PropertyConstants.cs @@ -0,0 +1,17 @@ +namespace GeneXus.Messaging.Common +{ + public static class PropertyConstants + { + //Azure Event Grid + + internal const string AZURE_EG_CLASSNAME = "GeneXus.Messaging.GXAzureEventGrid.AzureEventGrid"; + internal const string AZURE_EG_PROVIDER_CLASSNAME = "GeneXus.Messaging.GXAzureEventGrid.AzureEventGrid, GXAzureEventGrid, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"; + public const string EVENT_ROUTER = "EVENTROUTER"; + public const string URI_ENDPOINT = "ENDPOINT"; + public const string ACCESS_KEY = "ACCESS_KEY"; + public const string AZUREEVENTGRID = "AZUREEVENTGRID"; + public const string EVENTROUTER_AZUREEG_ENDPOINT = "EVENTROUTER_AZUREEVENTGRID_ENDPOINT"; + public const string EVENTROUTER_AZUREEG_ACCESS_KEY = "EVENTROUTER_AZUREEVENTGRID_ACCESS_KEY"; + + } +} diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj index b41e066ac..771581f34 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj @@ -6,6 +6,10 @@ GeneXus.Message.Queue + + + + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/ServiceSettings.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/ServiceSettings.cs deleted file mode 100644 index 443f5223e..000000000 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/ServiceSettings.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using GeneXus.Encryption; -using GeneXus.Messaging.Common; -using GeneXus.Services; -using log4net; - -namespace GeneXus.Messaging.Queue -{ - public class ServiceSettings - { - static readonly ILog logger = log4net.LogManager.GetLogger(typeof(ServiceSettings)); - - internal GXService service; - public string serviceNameResolver { get; } - public string name { get; } - - public ServiceSettings(string serviceNameResolver, string name, GXService gXService) - { - this.serviceNameResolver = serviceNameResolver; - this.name = name; - this.service = gXService; - } - - public string GetEncryptedPropertyValue(string propertyName, string alternativePropertyName = null) - { - String value = GetEncryptedPropertyValue(propertyName, alternativePropertyName, null); - if (value == null) - { - String errorMessage = String.Format($"Service configuration error - Property name {ResolvePropertyName(propertyName)} must be defined"); - logger.Fatal(errorMessage); - throw new Exception(errorMessage); - } - return value; - } - public string GetEncryptedPropertyValue(string propertyName, string alternativePropertyName, string defaultValue) - { - String value = GetPropertyValue(propertyName, alternativePropertyName, defaultValue); - if (!String.IsNullOrEmpty(value)) - { - try - { - string ret = String.Empty; - if (CryptoImpl.Decrypt(ref ret, value)) - { - value = ret; - } - } - catch (Exception) - { - logger.Warn($"Could not decrypt property name: {ResolvePropertyName(propertyName)}"); - } - } - return value; - } - - internal string GetPropertyValue(string propertyName, string alternativePropertyName = null) - { - String value = GetPropertyValue(propertyName, alternativePropertyName, null); - if (value == null) - { - String errorMessage = String.Format($"Service configuration error - Property name {ResolvePropertyName(propertyName)} must be defined"); - logger.Fatal(errorMessage); - throw new Exception(errorMessage); - } - return value; - } - - internal string GetPropertyValue(string propertyName, string alternativePropertyName, string defaultValue) - { - String value = null; - value = string.IsNullOrEmpty(value) ? GetPropertyValueImpl(ResolvePropertyName(propertyName)) : value; - value = string.IsNullOrEmpty(value) ? GetPropertyValueImpl(propertyName) : value; - value = string.IsNullOrEmpty(value) ? GetPropertyValueImpl(alternativePropertyName) : value; - value = string.IsNullOrEmpty(value) ? defaultValue : value; - return value; - } - - internal string GetPropertyValueImpl(string propertyName) - { - String value = null; - if (!string.IsNullOrEmpty(propertyName)) - { - value = Environment.GetEnvironmentVariable(propertyName); - if (service != null && value == null) - { - value = service.Properties.Get(propertyName); - } - } - return value; - } - - internal string ResolvePropertyName(string propertyName) - { - return $"{serviceNameResolver}_{name}_{propertyName}"; - } - } -} diff --git a/dotnet/src/dotnetframework/GxClasses/Services/Storage/GXServices.cs b/dotnet/src/dotnetframework/GxClasses/Services/Storage/GXServices.cs index 5d0879298..0c652ecf7 100644 --- a/dotnet/src/dotnetframework/GxClasses/Services/Storage/GXServices.cs +++ b/dotnet/src/dotnetframework/GxClasses/Services/Storage/GXServices.cs @@ -24,6 +24,7 @@ public class GXServices public static string WEBNOTIFICATIONS_SERVICE = "WebNotifications"; public static string QUEUE_SERVICE = "QueueService"; public static string MESSAGEBROKER_SERVICE = "MessageBrokerService"; + public static string EVENTROUTER_SERVICE = "EventRouterService"; private static string[] SERVICES_FILE = new string[] { "CloudServices.dev.config", "CloudServices.config" }; [System.Diagnostics.CodeAnalysis.SuppressMessage("GxFxCopRules", "CR1000:EnforceThreadSafeType")] private Dictionary services = new Dictionary(); From 74ceb512d4c6f3395abd11cd7938f73aefc06fed Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Thu, 20 Jul 2023 12:02:16 -0300 Subject: [PATCH 02/10] Complete fields of Event representation. Add AD Authentication. --- .../GXAzureEventGrid/AzureEventGrid.cs | 49 +++++++++++++++---- .../EventGridRouterProvider.cs | 16 ++++++ .../GXAzureEventGrid/GXAzureEventGrid.csproj | 1 + .../Messaging/GXEventRouter/EventRouter.cs | 6 ++- .../GXEventRouter/EventRouterProviderBase.cs | 4 +- 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs index 694a691fe..69464a326 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; -using System.Net; using System.Runtime.Serialization; using System.Text.Json; using System.Threading.Tasks; using Azure; +using Azure.Identity; using Azure.Messaging; using Azure.Messaging.EventGrid; using GeneXus.Messaging.Common; @@ -31,9 +31,23 @@ private void Initialize(GXService providerService) ServiceSettings serviceSettings = new(PropertyConstants.EVENT_ROUTER, Name, providerService); _endpoint = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.URI_ENDPOINT); _accessKey = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.ACCESS_KEY); - _client = new EventGridPublisherClient( - new Uri(_endpoint), - new AzureKeyCredential(_accessKey)); + + if (!string.IsNullOrEmpty(_endpoint)) { + if (string.IsNullOrEmpty(_accessKey)) + + //Try using Active Directory authentication + _client = new EventGridPublisherClient( + new Uri(_endpoint), + new DefaultAzureCredential()); + + else + + _client = new EventGridPublisherClient( + new Uri(_endpoint), + new AzureKeyCredential(_accessKey)); + } + else + throw new Exception("Endpoint URI must be set."); } public override string GetName() { @@ -54,7 +68,7 @@ public bool SendEvent(GXCloudEvent gxCloudEvent, bool binaryData) } else { - throw new Exception("SendEvent: There was an error at the Event Grid initialization."); + throw new Exception("There was an error at the Event Grid initialization."); } } catch (AggregateException ae) @@ -80,7 +94,7 @@ public bool SendEvents(IList gxCloudEvents, bool binaryData) } else { - throw new Exception("SendEvents: There was an error at the Event Grid initialization."); + throw new Exception("There was an error at the Event Grid initialization."); } } catch (AggregateException ae) @@ -232,7 +246,7 @@ public bool GetMessageFromException(Exception ex, SdtMessages_Message msg) { try { - HttpListenerException az_ex = (HttpListenerException)ex; + RequestFailedException az_ex = (RequestFailedException)ex; msg.gxTpr_Id = az_ex.ErrorCode.ToString(); msg.gxTpr_Description = az_ex.Message; return true; @@ -255,7 +269,9 @@ private EventGridEvent ToEventGridSchema(GXEventGridSchema gxEventGridSchema, bo evt.Id = gxEventGridSchema.id; if (!string.IsNullOrEmpty(gxEventGridSchema.topic)) evt.Topic = gxEventGridSchema.topic; - + if (gxEventGridSchema.eventtime != DateTime.MinValue) + evt.EventTime = gxEventGridSchema.eventtime; + return evt; } private CloudEvent ToCloudEvent(GXCloudEvent gxCloudEvent, bool isBinaryData) @@ -264,9 +280,13 @@ private CloudEvent ToCloudEvent(GXCloudEvent gxCloudEvent, bool isBinaryData) if (string.IsNullOrEmpty(gxCloudEvent.data)) evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, null); else - { + { if (!isBinaryData) - evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, gxCloudEvent.data); + { + if (string.IsNullOrEmpty(gxCloudEvent.datacontenttype)) + gxCloudEvent.datacontenttype = "application/json"; + evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, BinaryData.FromString(gxCloudEvent.data),gxCloudEvent.datacontenttype,CloudEventDataFormat.Json); + } else { if (string.IsNullOrEmpty(gxCloudEvent.datacontenttype)) @@ -280,6 +300,8 @@ private CloudEvent ToCloudEvent(GXCloudEvent gxCloudEvent, bool isBinaryData) evt.DataSchema = gxCloudEvent.dataschema; if (!string.IsNullOrEmpty(gxCloudEvent.subject)) evt.Subject = gxCloudEvent.subject; + if (gxCloudEvent.time != DateTime.MinValue) + evt.Time = gxCloudEvent.time; return evt; } #endregion @@ -301,5 +323,12 @@ public class GXEventGridSchema [DataMember] public string dataversion { get; set; } + [DataMember] + public DateTime eventtime { get; set; } + + [DataMember] + public string metadataversion { get; set; } + + } } \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs index 1cbba3e37..cd4cce6ee 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs @@ -3,6 +3,9 @@ namespace GeneXus.Messaging.GXAzureEventGrid { + /// + /// Implementation of EventGridRouterProvider External Object. + /// public class EventGridRouterProvider { public EventRouterProviderBase Connect(string endpoint, string accesskey, out GXBaseCollection errorMessages, out bool success) @@ -14,6 +17,19 @@ public EventRouterProviderBase Connect(string endpoint, string accesskey, out GX { PropertyConstants.EVENTROUTER_AZUREEG_ACCESS_KEY, accesskey } }; + EventRouterProviderBase evtRouterProvider = eventRouterProvider.Connect(PropertyConstants.AZUREEVENTGRID, properties, out GXBaseCollection errorMessagesConnect, out bool successConnect); + errorMessages = errorMessagesConnect; + success = successConnect; + return evtRouterProvider; + } + public EventRouterProviderBase Connect(string endpoint, out GXBaseCollection errorMessages, out bool success) + { + EventRouterProvider eventRouterProvider = new EventRouterProvider(); + GXProperties properties = new GXProperties + { + { PropertyConstants.EVENTROUTER_AZUREEG_ENDPOINT, endpoint }, + }; + EventRouterProviderBase evtRouterProvider = eventRouterProvider.Connect(PropertyConstants.AZUREEVENTGRID, properties, out GXBaseCollection errorMessagesConnect, out bool successConnect); errorMessages = errorMessagesConnect; success = successConnect; diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj index 0dd71f20c..e50e530ad 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj @@ -7,6 +7,7 @@ + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs index 4c1584efe..56fa53a2a 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouter.cs @@ -1,6 +1,6 @@ -using GeneXus.Utils; -using System.Collections.Generic; using System; +using System.Collections.Generic; +using GeneXus.Utils; namespace GeneXus.Messaging.Common { @@ -20,6 +20,8 @@ public class GXCloudEvent : GxUserType public string id { get; set; } public string dataschema { get; set; } public string subject { get; set; } + public string data_base64 { get; set; } + public DateTime time { get; set; } } } \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs index 90f9b914c..7197b0dc0 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs @@ -177,6 +177,8 @@ private GXCloudEvent ToGXCloudEvent(GxUserType evt) gxCloudEvent.id = evt.GetPropertyValue("Id"); gxCloudEvent.subject = evt.GetPropertyValue("Subject"); gxCloudEvent.dataschema = evt.GetPropertyValue("Dataschema"); + gxCloudEvent.data_base64 = evt.GetPropertyValue("Data_base64"); + gxCloudEvent.time = evt.GetPropertyValue("Time"); return gxCloudEvent; } return null; @@ -187,7 +189,7 @@ private GXCloudEvent ToGXCloudEvent(GxUserType evt) internal class ServiceFactory { private static IEventRouter eventRouter; - private static readonly ILog log = log4net.LogManager.GetLogger(typeof(GeneXus.Services.ServiceFactory)); + private static readonly ILog log = LogManager.GetLogger(typeof(Services.ServiceFactory)); public static GXServices GetGXServices() { From 44b75a6180d85bba45e4f28bbe8d97582d33d6e7 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Thu, 20 Jul 2023 13:12:10 -0300 Subject: [PATCH 03/10] Remove AD authentication because the package reference conflicts with other projects. --- .../GXAzureEventGrid/AzureEventGrid.cs | 20 ++++++++++--------- .../EventGridRouterProvider.cs | 4 ++-- .../GXAzureEventGrid/GXAzureEventGrid.csproj | 1 - 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs index 69464a326..cbec1840e 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs @@ -4,7 +4,6 @@ using System.Text.Json; using System.Threading.Tasks; using Azure; -using Azure.Identity; using Azure.Messaging; using Azure.Messaging.EventGrid; using GeneXus.Messaging.Common; @@ -32,15 +31,18 @@ private void Initialize(GXService providerService) _endpoint = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.URI_ENDPOINT); _accessKey = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.ACCESS_KEY); + //Package Azure.Identity cannot be referenced because it conflicts with Microsoft.Identity.Client pack version + //used transitively by gxmail and dynamoDB projects. + + /*if (string.IsNullOrEmpty(_accessKey)) + + //Try using Active Directory authentication + _client = new EventGridPublisherClient( + new Uri(_endpoint), + new DefaultAzureCredential());*/ + + if (!string.IsNullOrEmpty(_endpoint)) { - if (string.IsNullOrEmpty(_accessKey)) - - //Try using Active Directory authentication - _client = new EventGridPublisherClient( - new Uri(_endpoint), - new DefaultAzureCredential()); - - else _client = new EventGridPublisherClient( new Uri(_endpoint), diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs index cd4cce6ee..4140be485 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs @@ -22,7 +22,7 @@ public EventRouterProviderBase Connect(string endpoint, string accesskey, out GX success = successConnect; return evtRouterProvider; } - public EventRouterProviderBase Connect(string endpoint, out GXBaseCollection errorMessages, out bool success) + /*public EventRouterProviderBase Connect(string endpoint, out GXBaseCollection errorMessages, out bool success) { EventRouterProvider eventRouterProvider = new EventRouterProvider(); GXProperties properties = new GXProperties @@ -34,6 +34,6 @@ public EventRouterProviderBase Connect(string endpoint, out GXBaseCollection - From 306017d877125d1ed6fff10541c1a10ac8e1b88f Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Thu, 20 Jul 2023 17:32:32 -0300 Subject: [PATCH 04/10] Allow to send events with no data. --- .../Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs index cbec1840e..1ef49b287 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; using System.Text.Json; @@ -279,8 +280,9 @@ private EventGridEvent ToEventGridSchema(GXEventGridSchema gxEventGridSchema, bo private CloudEvent ToCloudEvent(GXCloudEvent gxCloudEvent, bool isBinaryData) { CloudEvent evt; + Dictionary emptyData = new Dictionary(); if (string.IsNullOrEmpty(gxCloudEvent.data)) - evt = new CloudEvent(gxCloudEvent.source, gxCloudEvent.type, null); + evt = new CloudEvent(source:gxCloudEvent.source, type:gxCloudEvent.type, emptyData); else { if (!isBinaryData) From 556506d5f882da738e11bac22b48e7dda65fd241 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Mon, 24 Jul 2023 22:39:25 -0300 Subject: [PATCH 05/10] fix method that process error messages. --- .../Messaging/GXEventRouter/EventRouterProviderBase.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs index 7197b0dc0..b011cec12 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs @@ -137,12 +137,12 @@ protected void EventRouterErrorMessagesSetup(Exception ex, out GXBaseCollection< { errorMessages = new GXBaseCollection(); bool foundGeneralException = false; - if (errorMessages != null && ex != null) + if (ex != null) { SdtMessages_Message msg = new SdtMessages_Message(); - if (eventRouter != null) - { - while (ex.InnerException != null) + if (eventRouter != null && ex.InnerException != null) + { + do { if (eventRouter.GetMessageFromException(ex.InnerException, msg)) { @@ -156,6 +156,7 @@ protected void EventRouterErrorMessagesSetup(Exception ex, out GXBaseCollection< } ex = ex.InnerException; } + while (ex.InnerException != null); if (foundGeneralException) GXUtil.ErrorToMessages("GXEventRouter1002", ex, errorMessages); } From 93cc78834cae3ca0946be91d80e11bfc9ec9fd77 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 25 Jul 2023 12:46:29 -0300 Subject: [PATCH 06/10] remove commented code. --- .../Messaging/GXAzureEventGrid/AzureEventGrid.cs | 11 ----------- .../GXAzureEventGrid/EventGridRouterProvider.cs | 13 ------------- 2 files changed, 24 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs index 1ef49b287..8d84b8687 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs @@ -32,17 +32,6 @@ private void Initialize(GXService providerService) _endpoint = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.URI_ENDPOINT); _accessKey = serviceSettings.GetEncryptedPropertyValue(PropertyConstants.ACCESS_KEY); - //Package Azure.Identity cannot be referenced because it conflicts with Microsoft.Identity.Client pack version - //used transitively by gxmail and dynamoDB projects. - - /*if (string.IsNullOrEmpty(_accessKey)) - - //Try using Active Directory authentication - _client = new EventGridPublisherClient( - new Uri(_endpoint), - new DefaultAzureCredential());*/ - - if (!string.IsNullOrEmpty(_endpoint)) { _client = new EventGridPublisherClient( diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs index 4140be485..f8c9e20ae 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/EventGridRouterProvider.cs @@ -22,18 +22,5 @@ public EventRouterProviderBase Connect(string endpoint, string accesskey, out GX success = successConnect; return evtRouterProvider; } - /*public EventRouterProviderBase Connect(string endpoint, out GXBaseCollection errorMessages, out bool success) - { - EventRouterProvider eventRouterProvider = new EventRouterProvider(); - GXProperties properties = new GXProperties - { - { PropertyConstants.EVENTROUTER_AZUREEG_ENDPOINT, endpoint }, - }; - - EventRouterProviderBase evtRouterProvider = eventRouterProvider.Connect(PropertyConstants.AZUREEVENTGRID, properties, out GXBaseCollection errorMessagesConnect, out bool successConnect); - errorMessages = errorMessagesConnect; - success = successConnect; - return evtRouterProvider; - }*/ } } From 15a06bbea9da98013edad905f1b8047d810b0e84 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 25 Jul 2023 13:36:22 -0300 Subject: [PATCH 07/10] dummy commit because of fortify FP result, to force re build. --- .../Providers/Messaging/GXEventRouter/EventRouterProvider.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs index bc959dfae..410543865 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProvider.cs @@ -13,9 +13,7 @@ public class EventRouterProvider : EventRouterProviderBase { static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static GXService providerService; - public EventRouterProvider() - { - + public EventRouterProvider() { } public EventRouterProviderBase Connect(string providerTypeName, GXProperties properties, out GXBaseCollection errorMessages, out bool success) { From 1f40343b7c999414a9cfa011ec03487df2975fa2 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 25 Jul 2023 13:58:05 -0300 Subject: [PATCH 08/10] remove unnecesary try-catch blocks --- .../GXAzureEventGrid/AzureEventGrid.cs | 76 ++++++------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs index 8d84b8687..584464ee4 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/AzureEventGrid.cs @@ -52,11 +52,11 @@ public bool SendEvent(GXCloudEvent gxCloudEvent, bool binaryData) bool success = false; try { - Task task; + Task task; if (_client != null) { - task = Task.Run(async () => await sendEvtAsync(evt).ConfigureAwait(false)); - success = task.Result; + task = Task.Run(async () => await sendEvtAsync(evt).ConfigureAwait(false)); + success = true; } else { @@ -78,11 +78,11 @@ public bool SendEvents(IList gxCloudEvents, bool binaryData) bool success = false; try { - Task task; + Task task; if (_client != null) { - task = Task.Run(async () => await sendEvtsAsync(evts).ConfigureAwait(false)); - success = task.Result; + task = Task.Run(async () => await sendEvtsAsync(evts).ConfigureAwait(false)); + success = true; } else { @@ -112,11 +112,11 @@ public bool SendCustomEvents(string jsonString, bool isBinary) bool success = false; try { - Task task; + Task task; if (_client != null) { - task = Task.Run(async () => await sendEventGridSchemaEventsAsync(eventGridEvents).ConfigureAwait(false)); - success = task.Result; + task = Task.Run(async () => await sendEventGridSchemaEventsAsync(eventGridEvents).ConfigureAwait(false)); + success = true; } else { @@ -137,11 +137,11 @@ public bool SendCustomEvents(string jsonString, bool isBinary) bool success = false; try { - Task task; + Task task; if (_client != null) { - task = Task.Run(async () => await sendEventGridSchemaEventAsync(ToEventGridSchema(evt, isBinary)).ConfigureAwait(false)); - success = task.Result; + task = Task.Run(async () => await sendEventGridSchemaEventAsync(ToEventGridSchema(evt, isBinary)).ConfigureAwait(false)); + success = true; } else { @@ -167,68 +167,38 @@ public bool SendCustomEvents(string jsonString, bool isBinary) /// /// /// - private async Task sendEventGridSchemaEventAsync(EventGridEvent evt) + private async Task sendEventGridSchemaEventAsync(EventGridEvent evt) { - try - { - await _client.SendEventAsync(evt).ConfigureAwait(false); - return true; - } - catch (Exception ex) - { - throw ex; - } + await _client.SendEventAsync(evt).ConfigureAwait(false); + } /// /// Send asynchronously a list of events formatted as Azure EventGrid Schema. /// /// /// - private async Task sendEventGridSchemaEventsAsync(IEnumerable evts) - { - try - { - await _client.SendEventsAsync(evts).ConfigureAwait(false); - return true; - } - catch (Exception ex) - { - throw ex; - } + private async Task sendEventGridSchemaEventsAsync(IEnumerable evts) + { + await _client.SendEventsAsync(evts).ConfigureAwait(false); } /// /// Send asynchronously an event formatted as CloudEvent Schema. /// /// /// - private async Task sendEvtAsync(CloudEvent cloudEvent) + private async Task sendEvtAsync(CloudEvent cloudEvent) { - try - { - await _client.SendEventAsync(cloudEvent).ConfigureAwait(false); - return true; - } - catch (Exception ex) - { - throw ex; - } + await _client.SendEventAsync(cloudEvent).ConfigureAwait(false); + } /// /// Send asynchronously a list of CloudEvent Schema formatted events. /// /// /// - private async Task sendEvtsAsync(IEnumerable cloudEvents) + private async Task sendEvtsAsync(IEnumerable cloudEvents) { - try - { - await _client.SendEventsAsync(cloudEvents).ConfigureAwait(false); - return true; - } - catch (Exception ex) - { - throw ex; - } + await _client.SendEventsAsync(cloudEvents).ConfigureAwait(false); } #endregion From c8e9e9b0d2dd83d9a3417da30b35741a8805d2a1 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 25 Jul 2023 14:29:41 -0300 Subject: [PATCH 09/10] fix code message --- .../Messaging/GXEventRouter/EventRouterProviderBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs index b011cec12..23844e3d2 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs @@ -158,11 +158,11 @@ protected void EventRouterErrorMessagesSetup(Exception ex, out GXBaseCollection< } while (ex.InnerException != null); if (foundGeneralException) - GXUtil.ErrorToMessages("GXEventRouter1002", ex, errorMessages); + GXUtil.ErrorToMessages("GXEventRouter", ex, errorMessages); } else { - GXUtil.ErrorToMessages("GXEventRouter1002", ex, errorMessages); + GXUtil.ErrorToMessages("GXEventRouter", ex, errorMessages); } } } From 4683481576f8312ac8e3cacb3beee29523212371 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 25 Jul 2023 19:39:14 -0300 Subject: [PATCH 10/10] Remove unused method. --- .../GXEventRouter/EventRouterProviderBase.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs index 23844e3d2..2ab0a67c8 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXEventRouter/EventRouterProviderBase.cs @@ -32,17 +32,6 @@ void ValidQueue() throw new Exception("Event Router was not instantiated."); } } - private static Assembly LoadAssembly(string fileName) - { - if (File.Exists(fileName)) - { - Assembly assemblyLoaded = Assembly.LoadFrom(fileName); - return assemblyLoaded; - } - else - return null; - } - private static void LoadAssemblyIfRequired() { if (assembly == null)