Skip to content

Commit

Permalink
Update KEDA transformation to match core-tools (#192)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmelsayed authored Mar 31, 2021
1 parent cae963b commit 64d80a7
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 14 deletions.
76 changes: 63 additions & 13 deletions Kudu.Core/Functions/KedaFunctionTriggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace Kudu.Core.Functions
{
/// <summary>
/// Returns "<see cref="IEnumerable<ScaleTrigger>"/> for KEDA scalers"
/// Returns "<see cref="IEnumerable<ScaleTrigger>"/> for KEDA scalers"
/// </summary>
public class KedaFunctionTriggerProvider
{
Expand Down Expand Up @@ -72,7 +72,7 @@ bool IsHostJson(string fullName)
return fullName.Equals(Constants.FunctionsHostConfigFile, StringComparison.OrdinalIgnoreCase);
}

bool IsDurable(FunctionTrigger function) =>
bool IsDurable(FunctionTrigger function) =>
function.Type.Equals("orchestrationTrigger", StringComparison.OrdinalIgnoreCase) ||
function.Type.Equals("activityTrigger", StringComparison.OrdinalIgnoreCase) ||
function.Type.Equals("entityTrigger", StringComparison.OrdinalIgnoreCase);
Expand Down Expand Up @@ -122,17 +122,8 @@ private static IEnumerable<ScaleTrigger> GetStandardScaleTriggers(IEnumerable<Fu
var scaleTrigger = new ScaleTrigger
{
Type = GetKedaTriggerType(function.Type),
Metadata = new Dictionary<string, string>()
Metadata = PopulateMetadataDictionary(function.Binding)
};
foreach (var property in function.Binding)
{
if (property.Value.Type == JTokenType.String)
{
scaleTrigger.Metadata.Add(property.Key, property.Value.ToString());
}
}

scaleTrigger.Metadata.Add("functionName", function.FunctionName);
yield return scaleTrigger;
}
}
Expand Down Expand Up @@ -183,7 +174,7 @@ public static string GetKedaTriggerType(string triggerType)
return triggerType;
}
}

private static bool TryGetDurableKedaTrigger(string hostJsonText, out ScaleTrigger scaleTrigger)
{
scaleTrigger = null;
Expand Down Expand Up @@ -222,6 +213,55 @@ private static bool TryGetDurableKedaTrigger(string hostJsonText, out ScaleTrigg
return scaleTrigger != null;
}

// match https://github.com/Azure/azure-functions-core-tools/blob/6bfab24b2743f8421475d996402c398d2fe4a9e0/src/Azure.Functions.Cli/Kubernetes/KEDA/V2/KedaV2Resource.cs#L91
public static IDictionary<string, string> PopulateMetadataDictionary(JToken t)
{
const string ConnectionField = "connection";
const string ConnectionFromEnvField = "connectionFromEnv";

IDictionary<string, string> metadata = t.ToObject<Dictionary<string, JToken>>()
.Where(i => i.Value.Type == JTokenType.String)
.ToDictionary(k => k.Key, v => v.Value.ToString());

var triggerType = t["type"].ToString().ToLower();

switch (triggerType)
{
case TriggerTypes.AzureBlobStorage:
case TriggerTypes.AzureStorageQueue:
metadata[ConnectionFromEnvField] = metadata[ConnectionField] ?? "AzureWebJobsStorage";
metadata.Remove(ConnectionField);
break;
case TriggerTypes.AzureServiceBus:
metadata[ConnectionFromEnvField] = metadata[ConnectionField] ?? "AzureWebJobsServiceBus";
metadata.Remove(ConnectionField);
break;
case TriggerTypes.AzureEventHubs:
metadata[ConnectionFromEnvField] = metadata[ConnectionField];
metadata.Remove(ConnectionField);
break;

case TriggerTypes.Kafka:
metadata["bootstrapServers"] = metadata["brokerList"];
metadata.Remove("brokerList");
metadata.Remove("protocol");
metadata.Remove("authenticationMode");
break;

case TriggerTypes.RabbitMq:
metadata["hostFromEnv"] = metadata["connectionStringSetting"];
metadata.Remove("connectionStringSetting");
break;
}

// Clean-up for all triggers

metadata.Remove("type");
metadata.Remove("name");

return metadata;
}

private class FunctionTrigger
{
public FunctionTrigger(string functionName, JObject binding, string type)
Expand All @@ -235,5 +275,15 @@ public FunctionTrigger(string functionName, JObject binding, string type)
public JObject Binding { get; }
public string Type { get; }
}

public class TriggerTypes
{
public const string AzureBlobStorage = "blobtrigger";
public const string AzureEventHubs = "eventhubtrigger";
public const string AzureServiceBus = "servicebustrigger";
public const string AzureStorageQueue = "queuetrigger";
public const string Kafka = "kafkatrigger";
public const string RabbitMq = "rabbitmqtrigger";
}
}
}
50 changes: 49 additions & 1 deletion Kudu.Tests/Core/Function/KedaFunctionTriggersProviderTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Kudu.Core.Functions;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -40,7 +41,7 @@ public void DurableFunctionApp()
Assert.True(double.TryParse(targetValue, out _));

string connectionStringName = Assert.Contains("connectionStringFromEnv", mssqlTrigger.Metadata);
Assert.Equal("SQLDB_Connection", connectionStringName);
Assert.Equal("SQLDB_Connection", connectionStringName);

ScaleTrigger httpTrigger = Assert.Single(result, trigger => trigger.Type.Equals("httpTrigger", StringComparison.OrdinalIgnoreCase));
string functionName = Assert.Contains("functionName", httpTrigger.Metadata);
Expand All @@ -60,5 +61,52 @@ private static void CreateJsonFileEntry(ZipArchive archive, string path, string
streamWriter.Write(content);
}
}

public void PopulateMetadataDictionary_KedaV1_CorrectlyPopulatesRabbitMQMetadata()
{
string jsonText = @"
{
""type"": ""rabbitMQTrigger"",
""connectionStringSetting"": ""RabbitMQConnection"",
""queueName"": ""myQueue"",
""name"": ""message""
}";

JToken jsonObj = JToken.Parse(jsonText);

IDictionary<string, string> metadata = KedaFunctionTriggerProvider.PopulateMetadataDictionary(jsonObj);

Assert.Equal(4, metadata.Count);
Assert.True(metadata.ContainsKey("type"));
Assert.True(metadata.ContainsKey("host"));
Assert.True(metadata.ContainsKey("name"));
Assert.True(metadata.ContainsKey("queueName"));
Assert.Equal("rabbitMQTrigger", metadata["type"]);
Assert.Equal("RabbitMQConnection", metadata["host"]);
Assert.Equal("message", metadata["name"]);
Assert.Equal("myQueue", metadata["queueName"]);
}

[Fact]
public void PopulateMetadataDictionary_KedaV2_CorrectlyPopulatesRabbitMQMetadata()
{
string jsonText = @"
{
""type"": ""rabbitMQTrigger"",
""connectionStringSetting"": ""RabbitMQConnection"",
""queueName"": ""myQueue"",
""name"": ""message""
}";

JToken jsonObj = JToken.Parse(jsonText);

IDictionary<string, string> metadata = KedaFunctionTriggerProvider.PopulateMetadataDictionary(jsonObj);

Assert.Equal(2, metadata.Count);
Assert.True(metadata.ContainsKey("queueName"));
Assert.True(metadata.ContainsKey("hostFromEnv"));
Assert.Equal("myQueue", metadata["queueName"]);
Assert.Equal("RabbitMQConnection", metadata["hostFromEnv"]);
}
}
}

0 comments on commit 64d80a7

Please sign in to comment.