This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
nebolintegration_tutorial_1 [2021/08/11 22:46] – 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 | ||
- | Install-Package Microsoft.EntityFrameworkCore.SqlServer | ||
- | Install-Package SharpRepository.IocMicrosoft.DependencyInjection | ||
- | Install-Package NewtonSoft.Json | ||
- | </ | ||
- | |||
- | 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_Database_and_Flow]] - So what happened? |