* Added MySQL dependencies, check mysql connection on startup

* Added default Api unhandled exceptions
* Fixed config file
This commit is contained in:
CMS4390\marantalu
2017-12-06 12:11:01 +01:00
parent 2b9f74a1b2
commit 512a2200c6
13 changed files with 146 additions and 82 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<ncConfig>
<ncPort>8080</ncPort>
<ncVendor>1</ncVendor>
<ncIpAddress>127.0.0.1</ncIpAddress>
</ncConfig>
<ncPort>8080</ncPort>
</ncConfig>
<serverConfig>
<serverPort>9000</serverPort>
<language>ita</language>
+22 -22
View File
@@ -2,95 +2,95 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="ncConfig">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="ncVendor" type="NcType" minOccurs='1' maxOccurs='1'/>
<xs:element name="ncIpAddress" minOccurs='1' maxOccurs='1'/>
<xs:element name="ncPort" type="xs:int" minOccurs='1' maxOccurs='1'/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="serverConfig">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="serverPort" type="xs:int" minOccurs='1' maxOccurs='1'/>
<xs:element name="language" type="xs:language" minOccurs='1' maxOccurs='1' default="en"/>
<xs:element name="enableDirectoryBrowsing" type="xs:boolean" default="false"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="areasConfig">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="production">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" fixed="false"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="tooling">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" fixed="false"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="report">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" type="xs:boolean"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="alarms">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" type="xs:boolean"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="maintenance">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" fixed="false"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="utilities">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" fixed="false"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="scada">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element name="enabled" type="xs:boolean"/>
<xs:element name="allowExternalBrowser" type="xs:boolean"/>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:all>
</xs:complexType>
</xs:element>
+22 -4
View File
@@ -6,11 +6,14 @@ using System.Text;
using System.Threading.Tasks;
using Step.Model;
using MySql.Data.Entity;
using System.Data.SqlClient;
using static Step.Utils.ExceptionManager;
using static Step.Utils.Constants;
namespace Step.Database
{
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class DatabaseContext : DbContext
public class DatabaseContext : DbContext
{
public DbSet<UserModel> Users { get; set; }
public DbSet<RoleModel> Roles { get; set; }
@@ -20,12 +23,27 @@ namespace Step.Database
: base("mySQLDatabaseConnection")
{
}
public void TestDatabaseConnection()
public static void TestDatabaseConnection()
{
using (DatabaseContext dbContext = new DatabaseContext())
{
dbContext.Database.Exists();
try
{
dbContext.Database.Connection.Open();
dbContext.Database.Connection.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
if (ex.Number == 1042) // Can't find MySQLServer
{
Manage(ERROR_LEVEL.FATAL, ex);
}
else
{
Manage(ERROR_LEVEL.ERROR, ex);
}
}
}
}
}
+4
View File
@@ -80,6 +80,10 @@
<Project>{631375dd-06d3-49bb-8130-d9ddb34c429d}</Project>
<Name>Step.Model</Name>
</ProjectReference>
<ProjectReference Include="..\Step.Utils\Step.Utils.csproj">
<Project>{cbeb631b-abfa-4042-9779-c0060b0dfefe}</Project>
<Name>Step.Utils</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="docs\MySqlCommand.xml" />
+41 -16
View File
@@ -1,7 +1,9 @@
using System;
using System.Windows.Forms;
using Step.Model;
using TeamDev.SDK.MVVM;
using static Step.Utils.Constants;
using static Step.Utils.StepLogger;
namespace Step.Utils
{
@@ -12,16 +14,14 @@ namespace Step.Utils
if (ex is System.IO.FileNotFoundException)
{
// File not found
LogAndSendMessage(CreateMessageModel("File not found!", ex.Message, ERROR_LEVEL.FATAL));
LogAndNotifyUsers(CreateMessageModel("Configuration file not found!", ex.Message, ERROR_LEVEL.FATAL));
// Close the application
Environment.Exit(1);
}
else if(ex is MySql.Data.MySqlClient.MySqlException)
{
// MySql Error // TODO CHECK NUMBERS
// Log
LogAndSendMessage(CreateMessageModel("Database Error!", ex.Message, ERROR_LEVEL.FATAL));
// Close the application
// MySql Error
LogAndNotifyUsers(CreateMessageModel("Database Error!", ex.Message, ERROR_LEVEL.FATAL));
}
else
{
@@ -32,54 +32,79 @@ namespace Step.Utils
else
{
// Default case
LogAndSendMessage(CreateMessageModel("Generic Error!", ex.Message, ERROR_LEVEL.FATAL));
LogAndNotifyUsers(CreateMessageModel("Generic Error!", ex.Message, ERROR_LEVEL.FATAL));
// Close the application
Environment.Exit(1);
}
}
}
public static void Manage(ERROR_LEVEL errorLevel, Exception exception)
{
Manage(errorLevel, exception.Message);
}
public static void Manage(ERROR_LEVEL errorLevel, string message)
{
switch (errorLevel)
{
case ERROR_LEVEL.INFO:
{
LogAndSendMessage(CreateMessageModel("Info", message, ERROR_LEVEL.INFO));
// Log
LogInfo(message);
// Notify users
NotifyUsers(CreateMessageModel("Info!", message, ERROR_LEVEL.INFO));
}
break;
case ERROR_LEVEL.WARNING:
{
LogAndSendMessage(CreateMessageModel("Warning", message, ERROR_LEVEL.WARNING));
LogWarning(message);
NotifyUsers(CreateMessageModel("Warning!", message, ERROR_LEVEL.WARNING));
}
break;
case ERROR_LEVEL.ERROR:
{
LogAndSendMessage(CreateMessageModel("Error", message, ERROR_LEVEL.ERROR));
LogError(message);
NotifyUsers(CreateMessageModel("Error!", message, ERROR_LEVEL.ERROR));
}
break;
case ERROR_LEVEL.FATAL:
{
LogAndSendMessage(CreateMessageModel("Fatal Error", message, ERROR_LEVEL.FATAL));
LogFatal(message);
NotifyUsers(CreateMessageModel("Fatal Error!", message, ERROR_LEVEL.FATAL));
// Close the application
Environment.Exit(1);
}break;
default:
{
LogAndSendMessage(CreateMessageModel("Generic Error", message, ERROR_LEVEL.FATAL));
LogFatal(message);
NotifyUsers(CreateMessageModel("Generic Error!", message, ERROR_LEVEL.FATAL));
// Close the application
Environment.Exit(1);
}
break;
}
}
private static void LogAndSendMessage(ErrorMessageModel error)
private static void LogAndNotifyUsers(ErrorMessageModel error)
{
// Log
StepLogger.LogMessage(error.Message, (ERROR_LEVEL)error.errorLevel);
// Notify user
MessageServices.Current.Publish(SEND_MESSAGE, null, error);
LogMessage(error.Message, (ERROR_LEVEL)error.errorLevel);
NotifyUsers(error);
}
private static void NotifyUsers(ErrorMessageModel error)
{
if (error.errorLevel > (int)ERROR_LEVEL.WARNING)
{
// Notify user
MessageBox.Show(error.Message, error.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
// Notify user
MessageServices.Current.Publish(SEND_MESSAGE, null, error);
}
}
private static ErrorMessageModel CreateMessageModel(string title, string message, ERROR_LEVEL level)
+1
View File
@@ -39,6 +39,7 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
+16 -1
View File
@@ -40,9 +40,24 @@ namespace Step.Utils
}
}
public static void Info(string message)
public static void LogInfo(string message)
{
Log.Info(message);
}
public static void LogWarning(string message)
{
Log.Warn(message);
}
public static void LogError(string message)
{
Log.Error(message);
}
public static void LogFatal(string message)
{
Log.Fatal(message);
}
}
}
+2
View File
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.ExceptionHandling;
namespace Step
{
@@ -27,6 +28,7 @@ namespace Step
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.EnableCors();
config.Services.Replace(typeof(IExceptionHandler), new WebApiUnhandledExceptionHandler());
// Web API routes
config.MapHttpAttributeRoutes();
+18 -26
View File
@@ -37,38 +37,30 @@ namespace Step
private bool CheckAuthorization(int userLevel, string functionName)
{
try
using (FunctionAccessController acController = new FunctionAccessController())
{
using (FunctionAccessController acController = new FunctionAccessController())
// Read from db category levels
FunctionAccessModel functionAccess = acController.FindEnabledFunctionByName(functionName);
if (functionAccess != null && StartupConfigController.CheckAreaStatus(functionAccess.Area))
{
// Read from db category levels
FunctionAccessModel functionAccess = acController.FindEnabledFunctionByName(functionName);
if (functionAccess != null && StartupConfigController.CheckAreaStatus(functionAccess.Area))
{
if (Action == ACTIONS.READ)
{ // Check read permissions
if (functionAccess.ReadLevelMin > userLevel)
return false; // Not authorized
}
else
{ // Check write permissions
if (functionAccess.WriteLevelMin > userLevel)
return false; // Not authorized
}
if (Action == ACTIONS.READ)
{ // Check read permissions
if (functionAccess.ReadLevelMin > userLevel)
return false; // Not authorized
}
else
{
return false;
{ // Check write permissions
if (functionAccess.WriteLevelMin > userLevel)
return false; // Not authorized
}
// Authorized
return true;
}
}
catch (Exception ex)
{
ExceptionManager.Manage(ex);
throw new HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError)); // FIX
else
{
return false;
}
// Authorized
return true;
}
}
}
-9
View File
@@ -29,17 +29,8 @@ namespace Step.Controllers
[Route("crash"), HttpGet]
public IHttpActionResult Crash()
{
try
{
UsersController users = new UsersController();
return Ok(users.Find(13));
}
catch (Exception ex)
{
ExceptionManager.Manage(ex);
return InternalServerError(ex);
}
}
}
}
+1
View File
@@ -156,6 +156,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Provider\ApplicationOAuthProvider.cs" />
<Compile Include="Provider\SignalROAuthBearerProvider.cs" />
<Compile Include="WebApiUnhandledExceptionHandler.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="App.config" />
+13
View File
@@ -0,0 +1,13 @@
using System.Web.Http.ExceptionHandling;
using static Step.Utils.ExceptionManager;
namespace Step
{
public class WebApiUnhandledExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
Manage(context.Exception);
}
}
}
+4 -2
View File
@@ -26,9 +26,11 @@ namespace Step
public static void Main()
{
Info("Application started");
LogInfo("Application started");
StartupConfigController.ReadStartupConfig();
DatabaseContext.TestDatabaseConnection();
// Start self host application
string configuredUri = "http://localhost:" + ServerConfig.ServerPort.ToString();
@@ -45,7 +47,7 @@ namespace Step
using (WebApp.Start<Step.App_Start.Startup>(url: configuredUri))
{
StopRequest.WaitOne();
Info("Application closed");
LogInfo("Application closed");
}
// Close WinForm