Beispiel #1
0
        // Helper Methods
        private List <Interface> GetDeviceInterfaces(FarmForgeDataContext context, AskToRegisterDevice message)
        {
            var client  = new RestClient(new Uri($"http://{message.IpAddress}"));
            var request = new RestRequest($"{message.InterfaceEndpoint}", Method.GET);
            // TODO: Add security
            // request.AddHeader("Authorization", message.SecurityToken);

            // TODO: Make the conversion more resilient
            IRestResponse response = client.Execute(request);

            if (response.StatusCode == HttpStatusCode.OK)
            {
                return(JsonConvert.DeserializeObject <List <Interface> >(response.Content));
            }
            else
            {
                var logMessage = $"Error getting Interfaces from {message.DeviceName}:{message.IpAddress}";
                var logData    = new
                {
                    Response = response.StatusCode.ToString(),
                    response?.Content,
                    response?.ErrorMessage
                };
                var logDataString = JsonConvert.SerializeObject(logData);

                context.Logs.Add(new Log
                {
                    Message = logMessage,
                    Data    = logDataString
                });

                context.SaveChanges();

                return(new List <Interface>());
            }
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var settings = new ApiSettings();

            Configuration.GetSection("ApiSettings").Bind(settings);

            var securitySettings = new SecuritySettings();

            Configuration.GetSection("SecuritySettings").Bind(securitySettings);

            // Allow DI for Settings
            services.Configure <ApiSettings>(Configuration.GetSection("ApiSettings"));
            services.Configure <SecuritySettings>(Configuration.GetSection("SecuritySettings"));

            // Setup CORS
            if (settings.CORS != null)
            {
                services.AddCors(options =>
                {
                    options.AddPolicy(
                        "CorsPolicy",
                        builder => builder.WithOrigins(settings.CORS)
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials()
                        );
                });
            }

            // Add versioning
            services.AddApiVersioning(config =>
            {
                config.DefaultApiVersion = new ApiVersion(settings.MajorVersion, settings.MinorVersion);
                config.AssumeDefaultVersionWhenUnspecified = true;
                config.ReportApiVersions = true;
            });

            // Register swagger services
            services.AddOpenApiDocument(config =>
            {
                config.PostProcess = document =>
                {
                    document.Info.Version        = $"{settings.MajorVersion}.{settings.MinorVersion}";
                    document.Info.Title          = settings.SwaggerSettings.Title;
                    document.Info.Description    = settings.SwaggerSettings.Description;
                    document.Info.TermsOfService = settings.SwaggerSettings.TermsOfService;
                    document.Info.Contact        = new NSwag.OpenApiContact
                    {
                        Name  = settings.SwaggerSettings.ContactName,
                        Email = settings.SwaggerSettings.ContactEmail,
                        Url   = settings.SwaggerSettings.ContactURL
                    };
                    document.Info.License = new NSwag.OpenApiLicense
                    {
                        Name = settings.SwaggerSettings.LicenseName,
                        Url  = settings.SwaggerSettings.LicenseURL
                    };
                };
            });

            // Add the DbContext
            services.AddDbContext <FarmForgeDataContext>(options =>
            {
                if (settings.DatabaseType == DatabaseType.SQLITE)
                {
                    options.UseSqlite(settings.ConnectionStrings["Database"]);
                }

                else if (settings.DatabaseType == DatabaseType.SQLSERVER)
                {
                    options.UseSqlServer(settings.ConnectionStrings["Database"]);
                }
            });

            // Add Akka.net
            services.AddSingleton((serviceProvider) =>
            {
                // Create the actor system
                var actorSystem = ActorSystem.Create("FarmForge");

                // Register the actors
                var serviceScopeFactory = serviceProvider.GetService <IServiceScopeFactory>();

                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new DeviceActor(serviceScopeFactory)),
                                        "DeviceActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new WebSocketActor(serviceScopeFactory)),
                                        "WebSocketActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new AuthenticationActor(
                                                         serviceScopeFactory,
                                                         securitySettings
                                                         )),
                                        "AuthenticationActor")
                    );
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new CropActor(serviceScopeFactory)),
                                        "CropActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new CropTypeActor(serviceScopeFactory)),
                                        "CropTypeActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new LocationActor(serviceScopeFactory)),
                                        "LocationActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new LogTypeActor(serviceScopeFactory)),
                                        "LogTypeActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new StatusActor(serviceScopeFactory)),
                                        "StatusActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new CropClassificationActor(serviceScopeFactory)),
                                        "CropClassificationActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new CropLogActor(serviceScopeFactory)),
                                        "CropLogActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new UnitActor(serviceScopeFactory)),
                                        "UnitActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new ProductActor(serviceScopeFactory)),
                                        "ProductActor"
                                        ));
                Actors.Add(
                    actorSystem.ActorOf(Props.Create(() =>
                                                     new SupplierActor(serviceScopeFactory)),
                                        "SupplierActor"
                                        ));

                return(actorSystem);
            });

            // Access Actors via Dependency Injection
            services.AddSingleton(_ => Actors);

            // Access HttpContext within AuthenticationHandlers
            services.AddHttpContextAccessor();

            // Add Authorization policies
            services.AddSingleton <IAuthorizationHandler, AuthenticatedWebClientHandler>();
            services.AddAuthorization(options =>
            {
                options.AddPolicy("AuthenticatedWebClient", policy =>
                                  policy.Requirements.Add(new AuthenticatedWebClient()));
            });

            // Add JWT options
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer           = true,
                    ValidateAudience         = true,
                    ValidateLifetime         = true,
                    ValidateIssuerSigningKey = true,

                    ValidIssuer      = securitySettings.Issuer,
                    ValidAudience    = securitySettings.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securitySettings.SecretKey))
                };
            });

            services.AddControllers();

            // use PascalCase instead of camelCase in serialization
            services.AddMvc(setupAction =>
            {
                setupAction.EnableEndpointRouting = false;
            })
            .AddJsonOptions(jsonOptions =>
            {
                jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            FarmForgeDataContext.SetTriggers();
        }