This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| nebolintegration_tutorial_1 [2021/08/11 21:37] – nebol | nebolintegration_tutorial_1 [2021/08/11 22:55] (current) – removed nebol | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ==== NebolIntegration Tutorial 1: Creating your first integration ==== | ||
| - | We will build a simple .NET Core Console application with SQL LocalDB | ||
| - | |||
| - | ==== NOT DONE! WORK IN PROGRESS! ==== | ||
| - | |||
| - | Create a .NET Core 3.1 Console application | ||
| - | |||
| - | We need a bunch of packages, first we get the Nebol packages: | ||
| - | |||
| - | < | ||
| - | Install-Package NebolIntegration | ||
| - | Install-Package NebolIntegration.EntityFramework | ||
| - | </ | ||
| - | |||
| - | And then the additional ones: | ||
| - | < | ||
| - | Install-Package SharpRepository.EfCoreRepository # EF Core support for SharpRepository | ||
| - | Install-Package Microsoft.EntityFrameworkCore.SqlServer # MS SQL support for Entity Framework | ||
| - | Install-Package SharpRepository.IocMicrosoft.DependencyInjection # MS dependency injection support for SharpRepository | ||
| - | Install-Package NewtonSoft.Json # needed for some JSON converting later | ||
| - | </ | ||
| - | |||
| - | SharpRepository.EfCoreRepository is needed for EF Core support for SharpRepository | ||
| - | Microsoft.EntityFrameworkCore.SqlServer is needed for MS SQL support for Entity Framework | ||
| - | SharpRepository.IocMicrosoft.DependencyInjection is needed for MS dependency injection support for SharpRepository | ||
| - | NewtonSoft.Json is needed for some JSON converting later on | ||
| - | |||
| - | The SharpRepository.EfCoreRepository installation will add a default settings file to your project named repository.efCore.json file, it's for the configuration of SharpRepository. Set the "Copy to Output Directory" | ||
| - | |||
| - | Replace the dbContextType line with: | ||
| - | |||
| - | < | ||
| - | " | ||
| - | </ | ||
| - | |||
| - | The connection string will look something like this for SQL LocalDB: | ||
| - | < | ||
| - | "Data Source=(LocalDb)\MSSQLLocalDB; | ||
| - | </ | ||
| - | |||
| - | You can add it to the repository.efCore.json file or use DI to add it in code in a way you prefer. | ||
| - | |||
| - | Now let's get coding. | ||
| - | |||
| - | First, the actual integration. We'll use a public webservice that just returns a UUID. Very simple. | ||
| - | |||
| - | We create a class derived from SystemIntegration. We supply it with a few parameters that specifies how the integration is managed, and we override the ProcessRequest() and ProcessResponse() methods. | ||
| - | The ProcessRequest() method is called when a new task is found in the queue. It does what needs to be done, in this case call a simple webservice. The ProcessResponse() handles the response recieved from the webservice, in this case it just outputs the UUID that is fetched. | ||
| - | |||
| - | < | ||
| - | public class FetchedUUID | ||
| - | { | ||
| - | public string UUID { get; set; } | ||
| - | } | ||
| - | |||
| - | public class FetchUUID : SystemIntegration | ||
| - | { | ||
| - | // this name is used to uniquely identify this integration | ||
| - | public static readonly new string TechnicalName = " | ||
| - | |||
| - | public FetchUUID(ISharpRepositoryConfiguration config) | ||
| - | : base(config, | ||
| - | { | ||
| - | Name = "UUID Fetcher"; | ||
| - | Description = " | ||
| - | RetryScheme = " | ||
| - | CleaningScheme = "?"; | ||
| - | Direction = DirectionEnum.Outgoing; | ||
| - | ExpectedSecondsToComplete = 10; | ||
| - | PollingIntervalSeconds = 60 * 3; // three minutes | ||
| - | ReferenceDescription = string.Empty; | ||
| - | |||
| - | InitiateIntegration(); | ||
| - | } | ||
| - | |||
| - | public override IntegrationResponse ProcessRequest(IntegrationQueue iqueue) | ||
| - | { | ||
| - | IntegrationResponse resp = new IntegrationResponse(); | ||
| - | |||
| - | // any exception will be caught by caller so this is fine | ||
| - | using (var wc = new System.Net.WebClient()) | ||
| - | resp.Response = wc.DownloadString(" | ||
| - | |||
| - | resp.Status = StatusEnum.Success; | ||
| - | |||
| - | return (resp); | ||
| - | } | ||
| - | |||
| - | public override IntegrationResponse ProcessResponse(IntegrationQueue iqueue, IntegrationResponse response) | ||
| - | { | ||
| - | var fuuid = JsonConvert.DeserializeObject< | ||
| - | |||
| - | Console.WriteLine(" | ||
| - | |||
| - | return (response); | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | Now let's set everything up. | ||
| - | |||
| - | < | ||
| - | static void SetupIntegration() | ||
| - | { | ||
| - | var config = new ConfigurationBuilder() | ||
| - | .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) | ||
| - | .AddJsonFile(" | ||
| - | .Build(); | ||
| - | |||
| - | var section = config.GetSection(" | ||
| - | ISharpRepositoryConfiguration sharpConfig = RepositoryFactory.BuildSharpRepositoryConfiguation(section); | ||
| - | |||
| - | // roundabout way to get connection string from the config section | ||
| - | var connection_string = sharpConfig.Repositories.Where(item => item.Name.Equals(" | ||
| - | .Attributes.Where(item => item.Key.Equals(" | ||
| - | |||
| - | // create an instance of the DB context so we can create the schema (if it doesn' | ||
| - | var optionsBuilder = new DbContextOptionsBuilder< | ||
| - | optionsBuilder.UseSqlServer(connection_string); | ||
| - | using (var db = new NebolIntegrationDbContext(optionsBuilder.Options)) | ||
| - | db.Database.EnsureCreated(); | ||
| - | |||
| - | // setup dependency injection | ||
| - | services = new ServiceCollection(); | ||
| - | services.AddDbContext< | ||
| - | services.UseSharpRepository(section); | ||
| - | var serviceProvider = services.BuildServiceProvider(true); | ||
| - | |||
| - | // create integration engine | ||
| - | engine = new Engine(sharpConfig); | ||
| - | |||
| - | // create instance of our integration class | ||
| - | var fetchuuid = new FetchUUID(sharpConfig); | ||
| - | |||
| - | // add it to the engine | ||
| - | engine.SystemIntegrations.Add(fetchuuid); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | NebolIntegration takes advantage of NebolLogger, | ||
| - | |||
| - | < | ||
| - | protected static void InitLoggingFramework() | ||
| - | { | ||
| - | Destination cc = new Destination_ColorConsole(); | ||
| - | Logger.Instance.Destinations.Add(cc); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Now let's start the integration engine: | ||
| - | < | ||
| - | engine.StartIntegrations(); | ||
| - | </ | ||
| - | |||
| - | And we'll add a basic console loop: | ||
| - | < | ||
| - | string command; | ||
| - | Console.WriteLine(" | ||
| - | do | ||
| - | { | ||
| - | command = Console.ReadLine(); | ||
| - | |||
| - | if (command.ToLower() != " | ||
| - | engine.Submit(FetchUUID.TechnicalName); | ||
| - | } | ||
| - | while (command.ToLower() != " | ||
| - | </ | ||
| - | |||
| - | (In a real-world scenario, the submit " | ||
| - | |||
| - | Finally, the cleanup: | ||
| - | |||
| - | < | ||
| - | engine.StopIntegrations(); | ||
| - | </ | ||
| - | |||
| - | This will shutdown the engine NICELY. It will not abort a running integration job. If you have multiple integrations it will signal them all that it's time to shutdown then wait nicely until they are all done. | ||
| - | |||
| - | When run, the program should output this: | ||
| - | |||
| - | {{: | ||
| - | (include logger & output) | ||
| - | |||
| - | As instructed, press ENTER to submit a request to the engine. | ||
| - | |||
| - | {{: | ||
| - | |||
| - | Congrats! A call was made to the webservice and the responce processed. Your integration is up and running! | ||
| - | |||
| - | Next: [[NebolIntegration_Tutorial_2]] - So what happened? | ||