Skip to content

Commit 1d201a5

Browse files
Ticket #2 : Complete the architecture + develop gateway
1 parent 73228b9 commit 1d201a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+871
-25
lines changed

FaasNet.sln

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FaasNet.Runtime.Startup", "
1111
EndProject
1212
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FaasNet.Kubernetes", "src\FaasNet.Kubernetes\FaasNet.Kubernetes.csproj", "{2B6F7B44-91D5-44DD-8615-4EE8447F4839}"
1313
EndProject
14-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaasNet.Runtime", "src\FaasNet.Runtime\FaasNet.Runtime.csproj", "{74F28744-9578-4547-8CE8-A388EFED1DB6}"
14+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FaasNet.Runtime", "src\FaasNet.Runtime\FaasNet.Runtime.csproj", "{74F28744-9578-4547-8CE8-A388EFED1DB6}"
1515
EndProject
1616
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02. Functions", "02. Functions", "{E407AB8F-BDC8-4084-BE20-B4442CFE5EE9}"
1717
EndProject
1818
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FaasNet.Runtime.GetSql", "src\FaasNet.Runtime.GetSql\FaasNet.Runtime.GetSql.csproj", "{39083E6B-D9AE-41A7-A364-82681B781A8B}"
1919
EndProject
2020
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FaasNet.Runtime.Transform", "src\FaasNet.Runtime.Transform\FaasNet.Runtime.Transform.csproj", "{E1FBEF1B-892D-4F3B-ADB2-A150152F4E51}"
2121
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FaasNet.Gateway.Core", "src\FaasNet.Gateway.Core\FaasNet.Gateway.Core.csproj", "{65DA8EDF-48A2-4AB5-B93A-6301718F1C1B}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaasNet.Gateway.Startup", "src\FaasNet.Gateway.Startup\FaasNet.Gateway.Startup.csproj", "{24686604-17C3-4BBB-9B05-7668073546E2}"
25+
EndProject
2226
Global
2327
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2428
Debug|Any CPU = Debug|Any CPU
@@ -45,6 +49,14 @@ Global
4549
{E1FBEF1B-892D-4F3B-ADB2-A150152F4E51}.Debug|Any CPU.Build.0 = Debug|Any CPU
4650
{E1FBEF1B-892D-4F3B-ADB2-A150152F4E51}.Release|Any CPU.ActiveCfg = Release|Any CPU
4751
{E1FBEF1B-892D-4F3B-ADB2-A150152F4E51}.Release|Any CPU.Build.0 = Release|Any CPU
52+
{65DA8EDF-48A2-4AB5-B93A-6301718F1C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53+
{65DA8EDF-48A2-4AB5-B93A-6301718F1C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
54+
{65DA8EDF-48A2-4AB5-B93A-6301718F1C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
55+
{65DA8EDF-48A2-4AB5-B93A-6301718F1C1B}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{24686604-17C3-4BBB-9B05-7668073546E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57+
{24686604-17C3-4BBB-9B05-7668073546E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
58+
{24686604-17C3-4BBB-9B05-7668073546E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
59+
{24686604-17C3-4BBB-9B05-7668073546E2}.Release|Any CPU.Build.0 = Release|Any CPU
4860
EndGlobalSection
4961
GlobalSection(SolutionProperties) = preSolution
5062
HideSolutionNode = FALSE
@@ -55,6 +67,8 @@ Global
5567
{74F28744-9578-4547-8CE8-A388EFED1DB6} = {1064A767-7322-4A14-BFD4-97FDD40E76B4}
5668
{39083E6B-D9AE-41A7-A364-82681B781A8B} = {E407AB8F-BDC8-4084-BE20-B4442CFE5EE9}
5769
{E1FBEF1B-892D-4F3B-ADB2-A150152F4E51} = {E407AB8F-BDC8-4084-BE20-B4442CFE5EE9}
70+
{65DA8EDF-48A2-4AB5-B93A-6301718F1C1B} = {1064A767-7322-4A14-BFD4-97FDD40E76B4}
71+
{24686604-17C3-4BBB-9B05-7668073546E2} = {B0C38F6D-3F83-458A-A493-428AB3DD9F85}
5872
EndGlobalSection
5973
GlobalSection(ExtensibilityGlobals) = postSolution
6074
SolutionGuid = {46764455-0D10-4266-9C37-35D7BD67517C}

FaasNetDoc.txt

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ docker run -d -p 5000:5000 --restart=always --name registry registry:2
33

44
# Construire l'image du runtime
55

6-
Construire l'image et la nommer "localhost:5000/runtime" :
7-
docker build -f RuntimeDockerfile -t localhost:5000/runtime .
6+
Construire l'image et la nommer "localhost:5000/getsql" && "localhost:5000/transform" :
7+
docker build -f RuntimeGetSqlDockerfile -t localhost:5000/getsql .
8+
docker build -f RuntimeTransformDockerfile -t localhost:5000/transform .
89

910
Pousser vers le "registry" local :
10-
docker push localhost:5000/runtime
11+
docker push localhost:5000/getsql
12+
docker push localhost:5000/transform
1113

1214
# Construire et déployer FAAS kubernetes
1315

@@ -20,20 +22,32 @@ Pousser vers le "registry" local :
2022
docker push localhost:5000/kubernetes
2123

2224
Créer le namespace faas
23-
kubectl apply -f ./faas-namespace.yml
25+
kubectl apply -f ./kubernetes/faas-namespace.yml
2426

2527
Déployer sur kubernetes
26-
kubectl apply -f ./run-faas-kubernetes.yml --namespace=faas
28+
kubectl apply -f ./kubernetes/run-faas-kubernetes.yml --namespace=faas
2729

2830
Déployer le service
29-
kubectl apply -f ./faas-kubernetes-svc.yml --namespace=faas
31+
kubectl apply -f ./kubernetes/faas-kubernetes-svc.yml --namespace=faas
3032

3133
# Faas Kubernetes
3234

3335
Cette API REST gère le déploiement des fonctions dans Kubernetes.
3436

3537
# Gateway
3638

39+
Construire l'image et la nommer "localhost:5000/gateway"
40+
docker build -f GatewayDockerfile -t localhost:5000/gateway .
41+
42+
Pousser vers le "registry" local :
43+
docker push localhost:5000/gateway
44+
45+
Déployer sur kubernetes
46+
kubectl apply -f ./kubernetes/run-faas-gateway.yml --namespace=faas
47+
48+
Déployer le service
49+
kubectl apply -f ./kubernetes/faas-gateway-svc.yml --namespace=faas
50+
3751
La gateway est utilisée pour déployer les fonctions mais aussi appeler des APIs.
3852

3953
Example de workflow :
@@ -44,18 +58,20 @@ provider:
4458

4559
apis:
4660
persons:
47-
path: persons
48-
async: false
49-
workflow:
50-
- function: getSql
51-
configuration: {"ConnectionString": "", "Query": ""}
52-
next: transform
53-
- function: transform
54-
configuration: { "mapping": { "input": "output" } }
55-
next: setPayload
56-
- function: setPayload
57-
configuration: { "forwardResponse" : true }
58-
61+
- path: persons
62+
operations:
63+
- name: getPerson
64+
async: false
65+
workflow:
66+
- function: getSql
67+
configuration: {"ConnectionString": "", "Query": ""}
68+
next: transform
69+
- function: transform
70+
configuration: { "mapping": { "input": "output" } }
71+
next: setPayload
72+
- function: setPayload
73+
configuration: { "forwardResponse" : true }
74+
- path: person/{id}
5975

6076
functions:
6177
- name: getSql

GatewayDockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM mcr.microsoft.com/dotnet/aspnet:5.0
2+
3+
COPY build/results/services/Gateway/ App/
4+
ENV ASPNETCORE_URLS=http://*:8080
5+
6+
EXPOSE 8080
7+
8+
WORKDIR /App
9+
10+
ENTRYPOINT ["dotnet", "FaasNet.Gateway.Startup.dll"]

default.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ task publish {
2222
exec { dotnet publish $source_dir\FaasNet.Runtime.GetSql\FaasNet.Runtime.GetSql.csproj -c $config -o $result_dir\services\RuntimeGetSql }
2323
exec { dotnet publish $source_dir\FaasNet.Runtime.Transform\FaasNet.Runtime.Transform.csproj -c $config -o $result_dir\services\RuntimeTransform }
2424
exec { dotnet publish $source_dir\FaasNet.Kubernetes\FaasNet.Kubernetes.csproj -c $config -o $result_dir\services\Kubernetes }
25+
exec { dotnet publish $source_dir\FaasNet.Gateway.Startup\FaasNet.Gateway.Startup.csproj -c $config -o $result_dir\services\Gateway }
2526
}
2627

2728
task clean {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
apiVersion: v1
22
kind: Service
33
metadata:
4-
name: faas-kubernetes-entry
4+
name: faas-gateway-entry
55
spec:
66
type: NodePort
77
selector:
8-
run: faas-kubernetes
8+
run: faas-gateway
99
ports:
1010
- port: 8080
1111
protocol: TCP

kubernetes/faas-kubernetes-svc.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: faas-kubernetes-entry
5+
spec:
6+
type: ClusterIP
7+
selector:
8+
run: faas-kubernetes
9+
ports:
10+
- port: 80
11+
protocol: TCP
12+
targetPort: 8080

kubernetes/run-faas-gateway.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: faas-gateway
5+
spec:
6+
selector:
7+
matchLabels:
8+
run: faas-gateway
9+
replicas: 1
10+
template:
11+
metadata:
12+
labels:
13+
run: faas-gateway
14+
spec:
15+
containers:
16+
- name: faas-gateway
17+
image: localhost:5000/gateway
18+
ports:
19+
- containerPort: 8080
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using FaasNet.Gateway.Core.ApiDefinitions.Commands.Results;
2+
using FaasNet.Gateway.Core.Domains;
3+
using FaasNet.Gateway.Core.Extensions;
4+
using FaasNet.Gateway.Core.Factories;
5+
using FaasNet.Gateway.Core.Parameters;
6+
using FaasNet.Gateway.Core.Repositories;
7+
using MediatR;
8+
using Microsoft.Extensions.Options;
9+
using Newtonsoft.Json;
10+
using Newtonsoft.Json.Linq;
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Net.Http;
14+
using System.Text;
15+
using System.Threading;
16+
using System.Threading.Tasks;
17+
18+
namespace FaasNet.Gateway.Core.ApiDefinitions.Commands.Handlers
19+
{
20+
public class InvokeApiDefinitionCommandHandler : IRequestHandler<InvokeApiDefinitionCommand, InvokeApiDefinitionResult>
21+
{
22+
private readonly IApiDefinitionRepository _apiDefinitionRepository;
23+
private readonly IHttpClientFactory _httpClientFactory;
24+
private readonly GatewayConfiguration _configuration;
25+
26+
public InvokeApiDefinitionCommandHandler(
27+
IApiDefinitionRepository apiDefinitionRepository,
28+
IHttpClientFactory httpClientFactory,
29+
IOptions<GatewayConfiguration> configuration)
30+
{
31+
_apiDefinitionRepository = apiDefinitionRepository;
32+
_httpClientFactory = httpClientFactory;
33+
_configuration = configuration.Value;
34+
}
35+
36+
public async Task<InvokeApiDefinitionResult> Handle(InvokeApiDefinitionCommand request, CancellationToken cancellationToken)
37+
{
38+
var path = request.FullPath.CleanPath();
39+
var result = await _apiDefinitionRepository.GetByPath(path, cancellationToken);
40+
if (result == null)
41+
{
42+
return InvokeApiDefinitionResult.NoMatch();
43+
}
44+
45+
Dictionary<string, string> parameters;
46+
ApiDefinitionOperation operation;
47+
if (!result.TryGetOperation(path, out operation, out parameters))
48+
{
49+
return InvokeApiDefinitionResult.NoMatch();
50+
}
51+
52+
var input = request.Content;
53+
input = await ExecuteWorkflow(operation, operation.GetRootFunction(), request.Content, cancellationToken);
54+
return InvokeApiDefinitionResult.Match(input);
55+
}
56+
57+
private async Task<JObject> ExecuteWorkflow(ApiDefinitionOperation operation, ApiDefinitionFunction func, JObject input, CancellationToken cancellationToken)
58+
{
59+
var parameter = new InvokeFunctionParameter
60+
{
61+
Name = func.Function,
62+
Content = new FunctionParameter
63+
{
64+
Configuration = JObject.Parse(func.SerializedConfiguration),
65+
Input = input
66+
}
67+
};
68+
using (var httpClient = _httpClientFactory.Build())
69+
{
70+
var request = new HttpRequestMessage
71+
{
72+
Content = new StringContent(JsonConvert.SerializeObject(parameter), Encoding.UTF8, "application/json"),
73+
Method = HttpMethod.Post,
74+
RequestUri = new Uri($"{_configuration.FunctionApi}/functions/invoke")
75+
};
76+
var httpResult = await httpClient.SendAsync(request);
77+
httpResult.EnsureSuccessStatusCode();
78+
var str = await httpResult.Content.ReadAsStringAsync();
79+
input = new JObject();
80+
if (!string.IsNullOrWhiteSpace(str))
81+
{
82+
input = JObject.Parse(str);
83+
}
84+
}
85+
86+
var nextFunc = operation.GetNextFunction(func);
87+
if (nextFunc == null)
88+
{
89+
return input;
90+
}
91+
92+
return await ExecuteWorkflow(operation, nextFunc, input, cancellationToken);
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)