Fix install/uninstall files to use correct path for installation on rpi.

Fix CardReaderService.conf for supervisorctl to ensure correct pathing as per install directories.
Correct MessageLogger to ensure it appends log messages, previously overwrote the logs.
Add manual Reset event in Service1.cs to ensure that we exit when we stop.
Add configurationmanager/config property, to allow DataCenterHelper to pull updated configurations at runtime.
Add TimeStamp to CardDataPost object
#103
This commit is contained in:
chris.watts90@outlook.com 2019-09-11 17:28:34 +01:00
parent e49111ebfc
commit 4c99dfba71
13 changed files with 240 additions and 56 deletions

View File

@ -1,5 +1,5 @@
[program:CardReaderService] [program:CardReaderService]
command=mono-service CardReaderService.exe --no-daemon command=mono-service CardReaderService.exe --no-daemon
directory=/home/osboxes/CardReaderService directory=/DIRECTORYTOSET/CardReaderService
stdout_logfile=/home/osboxes/CardReaderService/out.log stdout_logfile=/DIRECTORYTOSET/CardReaderService/out.log
redirect_stderr=true redirect_stderr=true

View File

@ -9,6 +9,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderServiceHost", "Ca
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logger", "Logger\Logger.csproj", "{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logger", "Logger\Logger.csproj", "{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux Conf", "Linux Conf", "{F9053F37-761D-45EE-9153-46776B083DBA}"
ProjectSection(SolutionItems) = preProject
CardReaderService.conf = CardReaderService.conf
install.sh = install.sh
uninstall.sh = uninstall.sh
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU

View File

@ -0,0 +1,10 @@
using System;
namespace CardReaderService
{
public class CardDataPost
{
public DateTime UtcTimeStamp { get; set; }
public string CardUId { get; set; }
}
}

View File

@ -34,12 +34,12 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="PCSC, Version=4.2.0.0, Culture=neutral, PublicKeyToken=13b76e54a2ee80a7, processorArchitecture=MSIL"> <Reference Include="PCSC, Version=4.2.0.0, Culture=neutral, PublicKeyToken=13b76e54a2ee80a7, processorArchitecture=MSIL">
<HintPath>..\packages\PCSC.3.6.0\lib\net40\pcsc-sharp.dll</HintPath> <HintPath>..\packages\PCSC.4.2.0\lib\net40\PCSC.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
@ -54,6 +54,11 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CardDataPost.cs" />
<Compile Include="CircularBuffer.cs" />
<Compile Include="ConfigurationManager.cs" />
<Compile Include="ConfigurationProperty.cs" />
<Compile Include="ConfigurationType.cs" />
<Compile Include="ConfigureService.cs" /> <Compile Include="ConfigureService.cs" />
<Compile Include="DataCenterHelper.cs" /> <Compile Include="DataCenterHelper.cs" />
<Compile Include="Service1.cs"> <Compile Include="Service1.cs">

View File

@ -0,0 +1,38 @@
using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
namespace CardReaderService
{
public class ConfigurationManager
{
public ConfigurationProperty GetConfiguration(string configName)
{
var cfgManager = GetConfigManager();
if (cfgManager.AppSettings.Settings.AllKeys.Contains(configName))
{
var cfg = cfgManager.AppSettings.Settings[configName];
return new ConfigurationProperty
{
Group=string.Empty,
Id="NOTIMPLEMENTED",
Name = cfg.Key,
Value = cfg.Value,
ReadOnly = false,
Source = "CardReaderService",
Type = ConfigurationType.STRING
};
}
return null;
}
private Configuration GetConfigManager()
{
return System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigFilePath);
}
public string ConfigFilePath => new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath;
}
}

View File

@ -0,0 +1,55 @@
namespace CardReaderService
{
/// <summary>
/// An object used to detail an element that can be configured in the system.
/// </summary>
public class ConfigurationProperty
{
/// <summary>
/// Unique Id for the configuration property.
/// </summary>
public string Id { get; set; }
/// <summary>
/// The display name of the configuration
/// </summary>
public string Name { get; set; }
/// <summary>
/// The group under which this configuration falls (e.g.: TCP Settings - "TCP" or similar.)
/// </summary>
/// <remarks>Application Specific grouping.</remarks>
public string Group { get; set; }
/// <summary>
/// The actual value of the Configuration property
/// </summary>
public string Value { get; set; }
/// <summary>
/// The source of the configuration properties.
/// </summary>
/// <remarks>
/// Using this property allows aggregation of configuration settings
/// by any configuration managers
/// </remarks>
/// <example>{TYPE}.getType().Name (or other suitably unique identifier)</example>
public string Source { get; set; }
/// <summary>
/// The type of the configuration
/// </summary>
/// <remarks>
/// This can be used for UI proofing/validation to ensure a user
/// enters expected format (e.g.: enters a date time for a datetime type)
/// </remarks>
public ConfigurationType Type { get; set; }
/// <summary>
/// Specifies whether the configuration setting can be set by user or is readonly
/// </summary>
public bool ReadOnly { get; set; }
//TODO: in future, add access level, could go read level/edit level
//public UserAccessLevel UserLevel {get;set;}
}
}

View File

@ -0,0 +1,33 @@
namespace CardReaderService
{
/// <summary>
/// The type of the configuration.
/// </summary>
public enum ConfigurationType
{
/// <summary>
/// No Type - shouldnt be used, but default for enum
/// </summary>
NONE,
/// <summary>
/// a string type configuration (could also be used for complex objects, e.g.: a json string/object).
/// </summary>
STRING,
/// <summary>
/// A whole number configuration
/// </summary>
INT,
/// <summary>
/// A number config with a decimal component
/// </summary>
DECIMAL,
/// <summary>
/// A Date Time Configuration
/// </summary>
DATETIME,
/// <summary>
/// A Boolean/TrueFalse configuration property (e.g.: On Off)
/// </summary>
BOOL
}
}

View File

@ -1,36 +1,40 @@
using System; using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Logger;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace CardReaderService namespace CardReaderService
{ {
static class DataCenterHelper static class DataCenterHelper
{ {
static DataCenterHelper()
{
}
public static void Post(CardDataPost postObject, string url) public static void Post(CardDataPost postObject, string url)
{ {
var endpointConfig = ConfigurationManager.AppSettings["DataCenterServiceEndpoint"] ?? var cfgMgr = new ConfigurationManager();
"http://localhost:8800"; //using ConfigurationManager means we can change the value at runtime without having to restart the service.
var endpointConfig = cfgMgr.GetConfiguration("DataCenterServiceEndpoint")?.Value?? "http://localhost:8800";
MessageLogger.Log("Targeting Endpoint: " + endpointConfig);
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
var jsonObject = JsonConvert.SerializeObject(postObject); var jsonObject = JsonConvert.SerializeObject(postObject);
var content = new StringContent(jsonObject, Encoding.UTF8, "application/json"); var content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
try try
{ {
Console.WriteLine("Writing"); MessageLogger.Log("Writing uid: "+ postObject.CardUId + " to the server.");
var fullUrl = endpointConfig + url; var fullUrl = endpointConfig + url;
MessageLogger.Log("Writing to URL: " + fullUrl);
var response = client.PostAsync(fullUrl, content).Result; var response = client.PostAsync(fullUrl, content).Result;
Console.WriteLine("Written"); MessageLogger.Log("Successfully written to server");
} }
catch (Exception) catch (Exception)
{ {
Console.WriteLine("exceptioning"); MessageLogger.Log("Failed to send log to server.");
//ignore
} }
} }
} }
@ -40,10 +44,4 @@ namespace CardReaderService
return Task.Run(() => Post(postObject, url)); return Task.Run(() => Post(postObject, url));
} }
} }
public class CardDataPost
{
public DateTime UtcTimeStamp { get; set; }
public string CardUId { get; set; }
}
} }

View File

@ -15,6 +15,7 @@ namespace CardReaderService
{ {
private Thread _mainWorkThread; private Thread _mainWorkThread;
private bool _stopMainWorkerThread; private bool _stopMainWorkerThread;
private readonly ManualResetEvent _mre;
private string _readerName = string.Empty; private string _readerName = string.Empty;
private SCardMonitor _cardMonitor; private SCardMonitor _cardMonitor;
@ -22,6 +23,7 @@ namespace CardReaderService
public Service1() public Service1()
{ {
InitializeComponent(); InitializeComponent();
_mre = new ManualResetEvent(false);
} }
public void Start() public void Start()
@ -64,6 +66,7 @@ namespace CardReaderService
{ {
MessageLogger.Log("Stopping.."); MessageLogger.Log("Stopping..");
_stopMainWorkerThread = true; _stopMainWorkerThread = true;
_mre.Set();
if (_mainWorkThread != null && _mainWorkThread.IsAlive) if (_mainWorkThread != null && _mainWorkThread.IsAlive)
{ {
_mainWorkThread.Join(3000); _mainWorkThread.Join(3000);
@ -94,6 +97,8 @@ namespace CardReaderService
} }
private void CardMonitor_CardInserted(object sender, CardStatusEventArgs e) private void CardMonitor_CardInserted(object sender, CardStatusEventArgs e)
{
try
{ {
var ctxFac = ContextFactory.Instance; var ctxFac = ContextFactory.Instance;
using (var ctx = ctxFac.Establish(SCardScope.System)) using (var ctx = ctxFac.Establish(SCardScope.System))
@ -137,6 +142,12 @@ namespace CardReaderService
} }
} }
} }
catch (Exception ex)
{
MessageLogger.Log("Exception has occurred in Card Inserted Event handler. Exception: "+ ex);
throw;
}
}
private void MainWorkerThread() private void MainWorkerThread()
{ {
@ -166,6 +177,7 @@ namespace CardReaderService
} }
} }
//dont actually need to do anything.. but cannot exit right away? //dont actually need to do anything.. but cannot exit right away?
_mre.WaitOne(minimumLoopTimemS);
} }
} }

View File

@ -34,8 +34,8 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
@ -53,6 +53,18 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\CardReaderService.conf">
<Link>CardReaderService.conf</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\install.sh">
<Link>install.sh</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\uninstall.sh">
<Link>uninstall.sh</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="App.config" /> <None Include="App.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>

View File

@ -14,7 +14,7 @@ namespace Logger
public static void Log(string message) public static void Log(string message)
{ {
Console.WriteLine(message); Console.WriteLine(message);
System.IO.File.WriteAllText(_logPath, string.Format("{0} | {1}", DateTime.Now, message)); File.AppendAllText(_logPath, string.Format("{0} | {1}{2}", DateTime.Now, message, Environment.NewLine));
} }
} }
} }

View File

@ -1,12 +1,21 @@
#!/bin/sh #!/bin/sh
if [ -z "$1" ]
then
echo "No arguments supplied, supply the base path"
fi
echo "Installing dependencies" echo "Installing dependencies"
apt-get install mono-complete pcscd supervisor -y apt-get install mono-complete pcscd supervisor -y
echo "Modifying supervisor conf file"
sed -i "s|/DIRECTORYTOSET|$1|g" CardReaderService.conf
echo "Installing service configuration file" echo "Installing service configuration file"
cp CardReaderService.conf /etc/supervisor/conf.d/ cp CardReaderService.conf /etc/supervisor/conf.d/
echo "Installing applicaton" echo "Installing applicaton"
mkdir /home/osboxes/CardReaderService mkdir $1/CardReaderService
cp CardReaderServiceHost/bin/Debug/*.* /home/osboxes/CardReaderService cp ./*.* $1/CardReaderService
cd /home/osboxes/CardReaderService cd $1/CardReaderService
rm *.pdb rm *.pdb
rm *.vshost.exe rm *.vshost.exe
rm *.vshost.exe.config rm *.vshost.exe.config

View File

@ -1,7 +1,12 @@
echo "Stopping application...." #!/bin/sh
if [ -z "$1" ]
then
echo "No arguments supplied, supply the base path"
fi
echo "Stopping service...."
service supervisor stop service supervisor stop
rm -f /etc/supervisor/conf.d/CardReaderService.conf rm -f /etc/supervisor/conf.d/CardReaderService.conf
echo "Removing Application.." echo "Removing Application.."
rm -r -f /home/osboxes/CardReaderService rm -r -f $1/CardReaderService
echo "Removing application dependencies.." echo "Removing application dependencies.."
apt-get remove pcscd supervisor mono-complete -y apt-get remove pcscd supervisor mono-complete -y