Skip to content

Commit 9827c63

Browse files
authored
Merge pull request #507 from serverlessworkflow/fix-function-call
Fixed the `FunctionCallExecutor` to support custom functions that do not specify an @ catalog, falling back to the default Serverless Workflow catalog
2 parents 6dacc40 + 855a57f commit 9827c63

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

src/runner/Synapse.Runner/Program.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14+
using Json.Schema;
1415
using Moq;
1516
using Neuroglia.AsyncApi;
1617
using Neuroglia.AsyncApi.Client;
@@ -129,4 +130,17 @@
129130

130131
using var app = builder.Build();
131132

133+
SchemaRegistry.Global.Fetch = uri =>
134+
{
135+
using var scope = app.Services.CreateScope();
136+
using var client = scope.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient();
137+
using var request = new HttpRequestMessage(HttpMethod.Get, uri);
138+
using var response = client.Send(request);
139+
response.EnsureSuccessStatusCode();
140+
using var stream = response.Content.ReadAsStream();
141+
var contentType = response.Content.Headers.ContentType?.MediaType!;
142+
var serializer = scope.ServiceProvider.GetRequiredService<ISerializerProvider>().GetSerializersFor(contentType).FirstOrDefault() ?? throw new NullReferenceException($"Failed to find a serializer for the specified content type '{contentType}'");
143+
return serializer.Deserialize<JsonSchema>(stream);
144+
};
145+
132146
await app.RunAsync();

src/runner/Synapse.Runner/Services/Executors/FunctionCallExecutor.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public class FunctionCallExecutor(IServiceProvider serviceProvider, ILogger<Func
3535
{
3636

3737
const string CustomFunctionDefinitionFile = "function.yaml";
38-
const string GithubHost = "github.com";
39-
const string GitlabHost = "gitlab";
38+
const string GitHubHost = "github.com";
39+
const string GitLabHost = "gitlab";
4040

4141
/// <summary>
4242
/// Gets the service used to serialize/deserialize objects to/from YAML
@@ -65,6 +65,15 @@ public override async Task InitializeAsync(CancellationToken cancellationToken =
6565
if (components.Length != 2) throw new NotSupportedException($"Unknown/unsupported function '{this.Task.Definition.Call}'");
6666
this.Function = await this.GetCustomFunctionAsync(components[0], components[1], cancellationToken).ConfigureAwait(false);
6767
}
68+
else if (this.Task.Definition.Call.Contains(':'))
69+
{
70+
var components = this.Task.Definition.Call.Split(':', StringSplitOptions.RemoveEmptyEntries);
71+
if (components.Length != 2) throw new Exception($"The specified value '{this.Task.Definition.Call}' is not a valid custom function qualified name ({{name}}:{{version}})");
72+
var functionName = components[0];
73+
var functionVersion = components[1];
74+
uri = new Uri($"https://github.com/serverlessworkflow/catalog/tree/main/functions/{functionName}/{functionVersion}/{CustomFunctionDefinitionFile}");
75+
this.Function = await this.GetCustomFunctionAsync(new() { Uri = uri }, cancellationToken).ConfigureAwait(false);
76+
}
6877
else throw new NotSupportedException($"Unknown/unsupported function '{this.Task.Definition.Call}'");
6978
}
7079

@@ -79,8 +88,8 @@ protected virtual async Task<TaskDefinition> GetCustomFunctionAsync(EndpointDefi
7988
ArgumentNullException.ThrowIfNull(endpoint);
8089
var uri = endpoint.Uri;
8190
if (!uri.OriginalString.EndsWith(CustomFunctionDefinitionFile)) uri = new Uri(uri, CustomFunctionDefinitionFile);
82-
if (uri.Host.Equals(GithubHost, StringComparison.OrdinalIgnoreCase)) uri = this.TransformGithubUriToRawUri(uri);
83-
else if (uri.Host.Contains(GitlabHost)) uri = this.TransformGitlabUriToRawUri(uri);
91+
if (uri.Host.Equals(GitHubHost, StringComparison.OrdinalIgnoreCase)) uri = this.TransformGithubUriToRawUri(uri);
92+
else if (uri.Host.Contains(GitLabHost)) uri = this.TransformGitlabUriToRawUri(uri);
8493
var authentication = endpoint.Authentication == null ? null : await this.Task.Workflow.Expressions.EvaluateAsync<AuthenticationPolicyDefinition>(endpoint.Authentication, this.Task.Input, this.Task.Arguments, cancellationToken).ConfigureAwait(false);
8594
using var httpClient = this.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient();
8695
await httpClient.ConfigureAuthenticationAsync(authentication, this.ServiceProvider, this.Task.Workflow.Definition, cancellationToken).ConfigureAwait(false);
@@ -138,8 +147,8 @@ protected virtual async Task<TaskDefinition> GetCustomFunctionAsync(string funct
138147
protected virtual Uri TransformGithubUriToRawUri(Uri uri)
139148
{
140149
ArgumentNullException.ThrowIfNull(uri);
141-
if (uri.Host.Equals(GithubHost, StringComparison.OrdinalIgnoreCase)) return uri;
142-
var rawUri = uri.AbsoluteUri.Replace(GithubHost, "raw.githubusercontent.com", StringComparison.OrdinalIgnoreCase);
150+
if (!uri.Host.Equals(GitHubHost, StringComparison.OrdinalIgnoreCase)) return uri;
151+
var rawUri = uri.AbsoluteUri.Replace(GitHubHost, "raw.githubusercontent.com", StringComparison.OrdinalIgnoreCase);
143152
rawUri = rawUri.Replace("/tree/", "/refs/heads/", StringComparison.OrdinalIgnoreCase);
144153
return new(rawUri, UriKind.Absolute);
145154
}
@@ -152,7 +161,7 @@ protected virtual Uri TransformGithubUriToRawUri(Uri uri)
152161
protected virtual Uri TransformGitlabUriToRawUri(Uri uri)
153162
{
154163
ArgumentNullException.ThrowIfNull(uri);
155-
if (!uri.AbsoluteUri.Contains(GitlabHost, StringComparison.OrdinalIgnoreCase)) return uri;
164+
if (!uri.Host.Equals(GitLabHost, StringComparison.OrdinalIgnoreCase)) return uri;
156165
var rawUri = uri.AbsoluteUri.Replace("/-/blob/", "/-/raw/", StringComparison.OrdinalIgnoreCase);
157166
return new(rawUri, UriKind.Absolute);
158167
}

src/runner/Synapse.Runner/Services/Executors/HttpCallExecutor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ protected override async Task DoExecuteAsync(CancellationToken cancellationToken
104104
{
105105
requestContent = this.Http.Body switch
106106
{
107-
string stringContent => new StringContent(stringContent, Encoding.UTF8, mediaType),
107+
string stringContent => stringContent.IsRuntimeExpression() ? null : new StringContent(stringContent, Encoding.UTF8, mediaType),
108108
byte[] byteArrayContent => new StreamContent(new MemoryStream(byteArrayContent)),
109109
_ => null
110110
};

0 commit comments

Comments
 (0)