abpframework / abp

Open Source Web Application Framework for ASP.NET Core. Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET and the ASP.NET Core platforms. Provides the fundamental infrastructure, production-ready startup templates, application modules, UI themes, tooling, guides and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.31k stars 3.32k forks source link

Serverless and the framework..... #527

Closed natiki closed 9 months ago

natiki commented 5 years ago

Hi,

1) Just having a play with the framework to build a https://kubeless.io/ managed by https://konghq.com/.

At this point is my best bet to base the ABP side of things on https://abp.io/documents/abp/latest/Getting-Started-AspNetCore-Application adding the necessary ABP "bits" mainly DI as needed?

2) Are there any thoughts as to whether the framework would do serverless itself? As the WebAPI is not going to get throttling (from Boilerplate) etc.

hikalkan commented 5 years ago

Hi @natiki,

I don't know how ABP would do serverless itself. Can you provide more details? I didn't understand what to do.

bbakermmc commented 5 years ago

@hikalkan I think they want to run most of the back end function "server-less". IE a bunch of functions/endpoints that just run when needed, the key here is cost/performance usually. You dont need to do dedicate hardware and if there is an influx the underlying infrastructure ie AWS Lambda, Azure Functions, Google Cloud Functions auto scale and spin up resources.

For azure see: https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#functions-class-library-project and https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-types-features-overview

http://codingsoul.de/2018/06/12/azure-functions-dependency-injection-autofac-on-functions-nuget-package/

natiki commented 5 years ago

Hi @hikalkan,

Ultimately I want to build some serverless functions using ABP Framework (ABPf). I want to use ABPf for things like DI, Modules, Validation and all the good non visual things originally found in ABP. (Then I don't need things like https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1157 for instance)

Ultimately writing a serverless function is akin to the old days where you would load a DLL into the application of your choice and access one of the exported functions after doing a LoadLibrary() Win32 call.

In serverless and .NET this ultimately means creating a library project and then writing some entry points that would be called by the "serverless runtime". If you look at the .NET Core approach from https://kubeless.io/docs/runtimes/ you will get a good idea of what I mean.

Now my issue is that ultimately all I need is a class library. However because it is merely a class library and not in the context of a console application or mvc application I don't know how I would bootstrap the ABP framework? Putting this in the class constructor of the class in the class library does not seem all that elegant.

So what I am trying to understand is does ABPf (ABP Framework) have a position on how serverless will ultimately be implemented?

Serverless can be seen as a very low effort way to get micro services going. And when coupled by plugging it directly into AWS, GCP, Azure infrastructure etc. etc. complexities like scalability does not have to be coded for. And in particular with Kong you can allow it to be the micro service api gateway and handle:

image

And as Kong is ultimately talking to a K8s cluster running on AWS etc. we have the best of all worlds ;-)

So to restate my question. How would I use ABPf without a Console App, MVC App etc. where all I wanted is a collection of class libraries? If I could find an entry point in my "main" class library to do the ABPf bootstrapping I think I would be away.

hikalkan commented 5 years ago

Well... It depends on how it's hosted. I don't know how Kong loads DLL, find functions and call them. Does it uses ASP.NET Core pipeline? If so, you will have a Startup class where you begin.

bbakermmc commented 5 years ago

In azure you can just reference the nuget packages. The issue just becomes you need a way to override/intercept the API calls to then redirect to the server less endpoints instead.

Ideally I would think it would be a different project type when you goto download, and maybe you have a deployment script for Azure, AWS, etc.

hikalkan commented 5 years ago

Can you share a sample service developed like that. It can be a simple open source code or even a tutorial.

bbakermmc commented 5 years ago

Twilio does a pretty decent job with it. https://www.twilio.com/docs/usage/tutorials/serverless-webhooks-azure-functions-and-csharp

bbakermmc commented 5 years ago
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using MMCExtensions;

namespace Conversion
{
    public static partial class ConvertExcel
    {
        [FunctionName("ConvertCSVToJson")]
        public static async Task<IActionResult> RunCsvToJson(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request for ConvertCSVToJson.");

            try
            {
                var reqParams = new RequestParams(req, false);

                var resultSet = CsvToJson(log, reqParams);

                return new OkObjectResult(resultSet);
                ;
            }
            catch (Exception ex)
            {
                log.LogInformation("BadRequest: " + ex.GetAllExceptionMessages());
                return new BadRequestObjectResult(ex.GetAllExceptionMessages());
            }
        }
    }
}
using System.Linq;
using Microsoft.Extensions.Logging;
using MMCExtensions;
using Newtonsoft.Json.Linq;

namespace Conversion
{
    public static partial class ConvertExcel
    {
        private static JsonResult CsvToJson(ILogger log, RequestParams reqParams)
        {
            log.LogInformation(
                $"Called ExcelToJson: fileName: {reqParams.FileName}, fieldSeparator: {reqParams.FieldSeparator[0]}");

            var csvLines = reqParams.Data.ToLines();

            log.LogInformation($"There are {csvLines.Length} lines in the csv content {reqParams.FileName}.");

            var headers = csvLines[0]
                          .Split(reqParams.FieldSeparator)
                          .ToList();

            var resultSet = new JsonResult(reqParams.FileName);

            var lineSkipCounter = 0;

            foreach (var line in csvLines.Skip(reqParams.HasHeader ? 1 : 0))
                //Check to see if a line is blank.
                //This can happen on the last row if improperly terminated.
                if (line != "" || line.Trim()
                                      .Length > 0)
                {
                    var lineObject = new JObject();
                    var fields = line.Split(reqParams.FieldSeparator);

                    for (var x = 0; x < headers.Count; x++) lineObject[headers[x]] = fields[x];

                    resultSet.Rows.Add(lineObject);
                }
                else
                {
                    lineSkipCounter += 1;
                }

            log.LogInformation($"There were {lineSkipCounter} lines skipped, not including the header row.");
            return resultSet;
        }
    }
}

Postman:

    {
            "name": "Csv To Json",
            "request": {
                "url": "http://localhost:7071/api/ConvertCsvToJson",
                "method": "POST",
                "header": [],
                "body": {
                    "mode": "raw",
                    "raw": "{\n  \"fileName\": \"MyTestCSVFile.csv\",\n  \"hasHeader\": true,\n  \"fieldSeparator\": \"|\",\n  \"data\":\"ID|Name|Score\n1|Aaron|99\n2|Dave|55\n3|Susy|77\n\"\n}"
                },
                "description": ""
            },
            "response": []
        },
natiki commented 5 years ago

@hikalkan

Well... It depends on how it's hosted. I don't know how Kong loads DLL, find functions and call them. Does it uses ASP.NET Core pipeline? If so, you will have a Startup class where you begin.

I am trying to find out

natiki commented 5 years ago

@bbakermmc It is not clear to me how the bootstrapping is actually occurring in the code you have shown?

bbakermmc commented 5 years ago

@natiki he didnt ask for how to bootstrap it, he asked for an azure function example.
Again I wouldnt use kubeless, I would use azure...

Just google azure functions and direct inject

https://blog.mexia.com.au/dependency-injections-on-azure-functions-v2

jzhouw commented 5 years ago

@bbakermmc I'm going to use Abp in Azure Function env too. Any further reading or best practices especially on Abp + Azure Fuction. Thanks

bbakermmc commented 5 years ago

@jamesatgithub We don't currently use ABP in Azure Functions. Not sure what what youre trying to do. For us we might just reference some of the table directly to pull a connection string or something, but trying to use the full framework might take some tweaking.

kelvinksau commented 3 years ago

Maybe you guys can take a look on KEDA ?

Now Azure function can run against Openshift. You can refer to the video here

https://github.com/kedacore/keda

rlavaud commented 3 years ago

I know this thread is old but I have been thinking about this as well and I think it is possible to use ABP in an Azure Function environment. The fist thing is to be familiar with what ABP does provide build in, for example in ABP you create application services which can dynamically generate plain rest API. The beauty of the Application Service is that you logic leaves there or it at the very least is the entry point to application logic (think create invoice, post entry, etc). Long story short once you have an application service created, you can use it in an Azure Function. This is a very interesting way to deploy ABP, it will require you to write the the Azure Function code to call the application service but this is possible. I will test it out.

ricxsar commented 3 years ago

I'm also interested on this. My idea is to reuse the abp boilerplate, remove the presentation layer and replace it with azure functions entry point. That way I am able to reuse the business logic, crud operations and authentication layer.

i believe the intent of the framework is reuseability. The same structure but different presentation layer either mobile, web etc.

I hope some will provide an insight or examples on how to achieve this.

vflores90 commented 3 years ago

Also interested! Has anyone been able to do this successfully? I got as far as being able to inject an appService in the function, but it fails as soon as I try to hit a repository, seems like an issue with Autofac DI.. The exception is "Value cannot be null. (Parameter 'provider')" somewhere in the DI resolution pipeline "at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)".

I suspect this has to do with never calling the .useAutofac() method in the IHostBuilder process, but I haven't found a way to go around this.

wboebel commented 3 years ago

I know this thread is old but I have been thinking about this as well and I think it is possible to use ABP in an Azure Function environment. The fist thing is to be familiar with what ABP does provide build in, for example in ABP you create application services which can dynamically generate plain rest API. The beauty of the Application Service is that you logic leaves there or it at the very least is the entry point to application logic (think create invoice, post entry, etc). Long story short once you have an application service created, you can use it in an Azure Function. This is a very interesting way to deploy ABP, it will require you to write the the Azure Function code to call the application service but this is possible. I will test it out.

This approach works for me. It doesn't let you leverage your ABP functionality within your function, but is a way to utilize functions along with your ABP implementation. Have ABP microservices deployed to App Services, then some external functions that call ABP methods based on different trigger types (queues, event hub, timer, etc.).

Did run in to one issue... tried to have ApplicationContracts referenced by the function to get the Dto's. Currently running ABP in .NET 5. Unfortunately functions only support 3.1. At runtime it fails because even though ApplicationContracts is .NET Standard, it references some .NET 5 libraries, so it fails at runtime in the 3.1 function. :(

Hoping .NET 5 will soon be an option for the functions, so I don't have to add another shared library or try to clean up the dependencies.

aicukltd commented 2 years ago

Would anyone have an open source project or example Startup.cs file to share to aid in the integration of an Azure Function with ABP?