From c726f497cf2d8b3c0d2637720c5449c109bdace8 Mon Sep 17 00:00:00 2001 From: CaptainMesomorph Date: Tue, 1 Dec 2020 19:36:16 +0800 Subject: [PATCH 01/16] Updates required after a new clone. --- .../Sif.Framework.EnvironmentProvider.csproj | 8 +++--- .../packages.config | 3 ++- .../Sif.Framework/Sif.Framework.csproj | 23 +----------------- .../Sif.Framework.Demo.Hits.Consumer.csproj | 3 +++ Data/Databases/SQLite/SifFrameworkDatabase.db | Bin 205824 -> 205824 bytes 5 files changed, 10 insertions(+), 27 deletions(-) diff --git a/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Sif.Framework.EnvironmentProvider.csproj b/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Sif.Framework.EnvironmentProvider.csproj index dc740cad..5324fc94 100644 --- a/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Sif.Framework.EnvironmentProvider.csproj +++ b/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Sif.Framework.EnvironmentProvider.csproj @@ -82,8 +82,8 @@ True - - ..\packages\System.Data.SQLite.Core.1.0.109.2\lib\net46\System.Data.SQLite.dll + + ..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.113.3\lib\net46\System.Data.SQLite.dll @@ -183,12 +183,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + +
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/EntityFrameworkTest.db b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/EntityFrameworkTest.db new file mode 100644 index 0000000000000000000000000000000000000000..16c6f2b6ecf053ec416d93e90dc26b47d9c83638 GIT binary patch literal 12288 zcmeI0&rjQC7{{Hw{3f8ol$@5 z=OESv0YN|z5CjAPK|l}?1Ox#=KoAfF1cA3j;PivU@Wk|V;`D^!uN=tvei<0Ey&8=i zCi5jDS246o?$L&!r6Vh8?Y2Co@hx4j(ptrMR?&)EeBa&J(DGZwa;20j6f0VKdwsvl zYr9m~%$1&N>&EjtmjZj(sY6SH`^#f$!gNBiJqupZLx*?s`?$_X^E@iJpN*)8 zef>ztQ%(hvGJYnhf2u#IU#1jwdi+fJNBL1HDRW99RhEB|zfT47dFuVQMPJ-k5D)|e z0YN|z5CjAPK|m0=h6L0v@DOrslX$f5LZE}!umj?`;4z(n>pPf%ZefNui3Ls(yFh(x z!U1Fc{Y>WQ=t!q_6;nz~8#9}DItgl-(B2L0Gq|2v)bHj8(Ba(Gx8S|S0l%khHdQu( z9T2Nrc)b5)GnX$v$t^4`Po~g=ciSR9K6VJUbZna7vuB$d@_FL+Yy~LOcLPT+K@|e< zOwfxYe}DsQG6?9*$+sDc9C@K9mCvRB3Na1^uYn!gih5mMdf2`ek>NS>*IbOu8Ub1) z%y?x}mZNKg&7A1nZolUHxXqk|B0K`7H)XorPmLIN!}Zzm9$rz9QRrdCFEB{+rCyB9 zC685(ec&voWVAXF$aP+G+f1s=B6D|7KSvRvZUINDJo5;fk}>K<;`wdM=n#x*G0 z-@wxB7}|NKZ3hjW15|fy?7+Vn6jX5vU&h}Je7E=FX{_=_S0eX zayIs{+SNmeQx8j{V3qCa;^TnV&=Co~zBh>Q&8t0It6|x#flKn2Rl150e9~HsFInvS z&Sf#J!*O`ysDPeCTT`(DlotzFoO%H4;+y-;XA}dZspHQ=U?vs`KioGOhff{M`J!cMbn@MaY7HARq_`0)l`bAP5Ko zf`A}!y$IxZ_nC<8z&d^7mEGsa9rUuFK)dlAUPgy~jN=9{1M>*_xpnoK=wtL^G&ZW< zKJi2JprhSA&Pgf%N?y!#BRb1bxy|P>Ha+7Tg(udd7{kthMngvLlkg}QA4Y@|5oHps z#u;3ULu9T$*^aq8knD|HXea9WhB3%^m)RSqAY&h)m5y3;WWi@3qmpzNx$(>Goa&wA Y4e1E?acTt@jv)qbqOExI=;R>zKPFHD8~^|S literal 0 HcmV?d00001 diff --git a/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/FrameworkSettingsTest.cs b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/FrameworkSettingsTest.cs new file mode 100644 index 00000000..d70775a2 --- /dev/null +++ b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/FrameworkSettingsTest.cs @@ -0,0 +1,65 @@ +/* + * Copyright 2020 Systemic Pty Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Sif.Framework.EntityFramework.Settings; +using Sif.Framework.Model.Infrastructure; +using Sif.Framework.Model.Requests; +using Sif.Framework.Model.Settings; +using Tardigrade.Framework.Configurations; +using Tardigrade.Framework.EntityFramework.Configurations; +using Xunit; + +namespace Sif.Framework.EntityFramework.Tests +{ + public class FrameworkSettingsTest + { + private readonly IFrameworkSettings settings; + + public FrameworkSettingsTest() + { + settings = new ConsumerSettings( + new ApplicationConfiguration(new AppSettingsConfigurationSource("name=SettingsDb"))); + } + + [Fact] + public void GetSettings_ValidSettings_Success() + { + Assert.Equal(Accept.XML, settings.Accept); + Assert.Equal("Sif3DemoConsumer", settings.ApplicationKey); + Assert.Equal("SIF_HMACSHA256", settings.AuthenticationMethod); + Assert.False(settings.CompressPayload); + Assert.Equal("DemoConsumer", settings.ConsumerName); + Assert.Equal(ContentType.XML, settings.ContentType); + Assert.Equal("http://www.sifassociation.org/datamodel/au/3.4", settings.DataModelNamespace); + Assert.False(settings.DeleteOnUnregister); + Assert.Equal(EnvironmentType.DIRECT, settings.EnvironmentType); + Assert.Equal("http://localhost:62921/api/environments/environment", settings.EnvironmentUrl); + Assert.Equal(10, settings.EventProcessingWaitTime); + Assert.Equal("http://www.sifassociation.org/infrastructure/3.2.1", settings.InfrastructureNamespace); + Assert.Null(settings.InstanceId); + Assert.True(settings.JobBinding); + Assert.Equal("any", settings.JobClasses); + Assert.True(settings.JobTimeoutEnabled); + Assert.Equal(60, settings.JobTimeoutFrequency); + Assert.Equal(5, settings.NavigationPageSize); + Assert.Equal("SecretDem0", settings.SharedSecret); + Assert.Equal("Sif3Framework", settings.SolutionId); + Assert.Equal(10, settings.StartupDelay); + Assert.Equal("3.2.1", settings.SupportedInfrastructureVersion); + Assert.Null(settings.UserToken); + } + } +} \ No newline at end of file diff --git a/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Properties/AssemblyInfo.cs b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..82abc040 --- /dev/null +++ b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Sif.Framework.EntityFramework.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Sif.Framework.EntityFramework.Tests")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f4546d54-e46e-4d8d-9a8f-ffdc67c54e1d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj new file mode 100644 index 00000000..0892db54 --- /dev/null +++ b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj @@ -0,0 +1,80 @@ + + + + + Debug + AnyCPU + {F4546D54-E46E-4D8D-9A8F-FFDC67C54E1D} + Library + Properties + Sif.Framework.EntityFramework.Tests + Sif.Framework.EntityFramework.Tests + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + 5.0.0 + + + 1.0.113.6 + + + 2.4.1 + + + 2.4.3 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + PreserveNewest + + + + + {01841a7c-0ea3-43c0-8d67-c97376d7442a} + Sif.Framework.EntityFramework + + + {2b13d050-aa2c-45a6-ba26-8b2706b7e227} + Sif.Framework + + + + \ No newline at end of file diff --git a/Code/Sif.Framework.Tests/Sif.Framework.Tests.sln b/Code/Sif.Framework.Tests/Sif.Framework.Tests.sln new file mode 100644 index 00000000..e06d4b35 --- /dev/null +++ b/Code/Sif.Framework.Tests/Sif.Framework.Tests.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30717.126 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework.EntityFramework.Tests", "Sif.Framework.EntityFramework.Tests\Sif.Framework.EntityFramework.Tests.csproj", "{F4546D54-E46E-4D8D-9A8F-FFDC67C54E1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework.Tests", "Sif.Framework.Tests\Sif.Framework.Tests.csproj", "{2BCC7798-CA9C-42B5-971B-4374DB30D4F6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sif.Framework", "..\Sif3Framework\Sif.Framework\Sif.Framework.csproj", "{2B13D050-AA2C-45A6-BA26-8B2706B7E227}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sif.Framework.EntityFramework", "..\Sif3Framework\Sif.Framework.EntityFramework\Sif.Framework.EntityFramework.csproj", "{01841A7C-0EA3-43C0-8D67-C97376D7442A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F4546D54-E46E-4D8D-9A8F-FFDC67C54E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4546D54-E46E-4D8D-9A8F-FFDC67C54E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4546D54-E46E-4D8D-9A8F-FFDC67C54E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4546D54-E46E-4D8D-9A8F-FFDC67C54E1D}.Release|Any CPU.Build.0 = Release|Any CPU + {2BCC7798-CA9C-42B5-971B-4374DB30D4F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BCC7798-CA9C-42B5-971B-4374DB30D4F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BCC7798-CA9C-42B5-971B-4374DB30D4F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BCC7798-CA9C-42B5-971B-4374DB30D4F6}.Release|Any CPU.Build.0 = Release|Any CPU + {2B13D050-AA2C-45A6-BA26-8B2706B7E227}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B13D050-AA2C-45A6-BA26-8B2706B7E227}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B13D050-AA2C-45A6-BA26-8B2706B7E227}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B13D050-AA2C-45A6-BA26-8B2706B7E227}.Release|Any CPU.Build.0 = Release|Any CPU + {01841A7C-0EA3-43C0-8D67-C97376D7442A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01841A7C-0EA3-43C0-8D67-C97376D7442A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01841A7C-0EA3-43C0-8D67-C97376D7442A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01841A7C-0EA3-43C0-8D67-C97376D7442A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1F1A78DA-B94C-422F-A1A0-88D153DD81FE} + EndGlobalSection +EndGlobal diff --git a/Code/Sif.Framework.Tests/Sif.Framework.Tests/Class1.cs b/Code/Sif.Framework.Tests/Sif.Framework.Tests/Class1.cs new file mode 100644 index 00000000..bae8ec3f --- /dev/null +++ b/Code/Sif.Framework.Tests/Sif.Framework.Tests/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace Sif.Framework.Tests +{ + public class Class1 + { + } +} diff --git a/Code/Sif.Framework.Tests/Sif.Framework.Tests/Sif.Framework.Tests.csproj b/Code/Sif.Framework.Tests/Sif.Framework.Tests/Sif.Framework.Tests.csproj new file mode 100644 index 00000000..9f5c4f4a --- /dev/null +++ b/Code/Sif.Framework.Tests/Sif.Framework.Tests/Sif.Framework.Tests.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/ConsumerSettings.cs b/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/ConsumerSettings.cs new file mode 100644 index 00000000..74941753 --- /dev/null +++ b/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/ConsumerSettings.cs @@ -0,0 +1,39 @@ +/* + * Copyright 2020 Systemic Pty Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Microsoft.Extensions.Configuration; + +namespace Sif.Framework.EntityFramework.Settings +{ + /// + /// This class represents Consumer application settings that are stored in a database. + /// + public class ConsumerSettings : FrameworkSettings + { + /// + /// Prefix used to indicate Consumer specific application settings. + /// + protected override string SettingsPrefix => "consumer"; + + /// + /// Create an instance of this class based upon the configuration provided. + /// + /// Application configuration properties. + public ConsumerSettings(IConfiguration configuration) : base(configuration) + { + } + } +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/FrameworkSettings.cs b/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/FrameworkSettings.cs new file mode 100644 index 00000000..4464a8d8 --- /dev/null +++ b/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/FrameworkSettings.cs @@ -0,0 +1,127 @@ +/* + * Copyright 2020 Systemic Pty Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Microsoft.Extensions.Configuration; +using Sif.Framework.Model.Infrastructure; +using Sif.Framework.Model.Requests; +using Sif.Framework.Model.Settings; +using Tardigrade.Framework.Extensions; + +namespace Sif.Framework.EntityFramework.Settings +{ + /// + /// This class represents application settings that are stored in a database. + /// + public abstract class FrameworkSettings : IFrameworkSettings + { + /// + /// Application configuration properties. + /// + protected IConfiguration Configuration { get; } + + /// + public Accept Accept => Configuration.GetAsEnum($"{SettingsPrefix}.payload.accept") ?? Accept.XML; + + /// + public string ApplicationKey => + Configuration.GetAsString($"{SettingsPrefix}.environment.template.applicationKey"); + + /// + public string AuthenticationMethod => + Configuration.GetAsString($"{SettingsPrefix}.environment.template.authenticationMethod"); + + /// + public bool CompressPayload => Configuration.GetAsBoolean($"{SettingsPrefix}.payload.compress") ?? false; + + /// + public string ConsumerName => Configuration.GetAsString($"{SettingsPrefix}.environment.template.consumerName"); + + /// + public ContentType ContentType => + Configuration.GetAsEnum($"{SettingsPrefix}.payload.contentType") ?? ContentType.XML; + + /// + public string DataModelNamespace => + Configuration.GetAsString($"{SettingsPrefix}.environment.template.dataModelNamespace"); + + /// + public bool DeleteOnUnregister => + Configuration.GetAsBoolean($"{SettingsPrefix}.environment.deleteOnUnregister") ?? false; + + /// + public EnvironmentType EnvironmentType => + Configuration.GetAsEnum($"{SettingsPrefix}.environmentType") ?? EnvironmentType.DIRECT; + + /// + public string EnvironmentUrl => Configuration.GetAsString($"{SettingsPrefix}.environment.url"); + + /// + public int EventProcessingWaitTime => + Configuration.GetAsInt($"{SettingsPrefix}.events.minWaitTimeSeconds") ?? 60; + + /// + public string InfrastructureNamespace => + "http://www.sifassociation.org/infrastructure/" + SupportedInfrastructureVersion; + + /// + public string InstanceId => Configuration.GetAsString($"{SettingsPrefix}.environment.template.instanceId"); + + /// + public bool JobBinding => Configuration.GetAsBoolean($"{SettingsPrefix}.job.binding") ?? true; + + /// + public string JobClasses => Configuration.GetAsString($"{SettingsPrefix}.job.classes", "any"); + + /// + public bool JobTimeoutEnabled => Configuration.GetAsBoolean($"{SettingsPrefix}.job.timeout.enabled") ?? true; + + /// + public int JobTimeoutFrequency => Configuration.GetAsInt($"{SettingsPrefix}.job.timeout.frequency") ?? 60; + + /// + public int NavigationPageSize => Configuration.GetAsInt($"{SettingsPrefix}.paging.navigationPageSize") ?? 100; + + /// + public string SharedSecret => Configuration.GetAsString($"{SettingsPrefix}.environment.sharedSecret"); + + /// + public string SolutionId => Configuration.GetAsString($"{SettingsPrefix}.environment.template.solutionId"); + + /// + public int StartupDelay => Configuration.GetAsInt($"{SettingsPrefix}.startup.delay") ?? 10; + + /// + public string SupportedInfrastructureVersion => + Configuration.GetAsString($"{SettingsPrefix}.environment.template.supportedInfrastructureVersion"); + + /// + public string UserToken => Configuration.GetAsString($"{SettingsPrefix}.environment.template.userToken"); + + /// + /// Prefix associated will all setting names. + /// + protected abstract string SettingsPrefix { get; } + + /// + /// Create an instance of this class based upon the configuration provided. + /// + /// Application configuration properties. + protected FrameworkSettings(IConfiguration configuration) + { + Configuration = configuration; + } + } +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/ProviderSettings.cs b/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/ProviderSettings.cs new file mode 100644 index 00000000..3e982240 --- /dev/null +++ b/Code/Sif3Framework/Sif.Framework.EntityFramework/Settings/ProviderSettings.cs @@ -0,0 +1,39 @@ +/* + * Copyright 2020 Systemic Pty Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Microsoft.Extensions.Configuration; + +namespace Sif.Framework.EntityFramework.Settings +{ + /// + /// This class represents Provider application settings that are stored in a database. + /// + public class ProviderSettings : FrameworkSettings + { + /// + /// Prefix used to indicate Provider specific application settings. + /// + protected override string SettingsPrefix => "provider"; + + /// + /// Create an instance of this class based upon the configuration provided. + /// + /// Application configuration properties. + public ProviderSettings(IConfiguration configuration) : base(configuration) + { + } + } +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework.EntityFramework/Sif.Framework.EntityFramework.csproj b/Code/Sif3Framework/Sif.Framework.EntityFramework/Sif.Framework.EntityFramework.csproj new file mode 100644 index 00000000..955825af --- /dev/null +++ b/Code/Sif3Framework/Sif.Framework.EntityFramework/Sif.Framework.EntityFramework.csproj @@ -0,0 +1,16 @@ + + + + net472;net461 + + + + + + + + + + + + diff --git a/Code/Sif3Framework/Sif3Framework.sln b/Code/Sif3Framework/Sif3Framework.sln index 1a86938c..1fb83a57 100644 --- a/Code/Sif3Framework/Sif3Framework.sln +++ b/Code/Sif3Framework/Sif3Framework.sln @@ -1,20 +1,26 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30717.126 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework.EnvironmentProvider", "Sif.Framework.EnvironmentProvider\Sif.Framework.EnvironmentProvider.csproj", "{A727F19D-BEDF-46A4-96E0-E0D9672457C3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework", "Sif.Framework\Sif.Framework.csproj", "{202E8CB9-9AED-4034-908F-0B3BB04B171A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sif.Framework", "Sif.Framework\Sif.Framework.csproj", "{202E8CB9-9AED-4034-908F-0B3BB04B171A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework.Tests", "Sif.Framework.Tests\Sif.Framework.Tests.csproj", "{D8C0E0E8-B96F-42D5-9FB0-8D055546E308}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework.EntityFramework", "Sif.Framework.EntityFramework\Sif.Framework.EntityFramework.csproj", "{BDCD2305-A0F7-415A-B46D-A852AC679016}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Release|Any CPU.Build.0 = Release|Any CPU {202E8CB9-9AED-4034-908F-0B3BB04B171A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {202E8CB9-9AED-4034-908F-0B3BB04B171A}.Debug|Any CPU.Build.0 = Debug|Any CPU {202E8CB9-9AED-4034-908F-0B3BB04B171A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -23,12 +29,15 @@ Global {D8C0E0E8-B96F-42D5-9FB0-8D055546E308}.Debug|Any CPU.Build.0 = Debug|Any CPU {D8C0E0E8-B96F-42D5-9FB0-8D055546E308}.Release|Any CPU.ActiveCfg = Release|Any CPU {D8C0E0E8-B96F-42D5-9FB0-8D055546E308}.Release|Any CPU.Build.0 = Release|Any CPU - {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A727F19D-BEDF-46A4-96E0-E0D9672457C3}.Release|Any CPU.Build.0 = Release|Any CPU + {BDCD2305-A0F7-415A-B46D-A852AC679016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDCD2305-A0F7-415A-B46D-A852AC679016}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDCD2305-A0F7-415A-B46D-A852AC679016}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDCD2305-A0F7-415A-B46D-A852AC679016}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D5909109-35D5-4CD9-899E-0611F0A043DB} + EndGlobalSection EndGlobal From f4313313d5c084ea3875c91a8760e60f30678749 Mon Sep 17 00:00:00 2001 From: rafidzal Date: Fri, 11 Dec 2020 19:12:05 +0800 Subject: [PATCH 04/16] Modified the constructor of the Consumer class to include an IFrameworkSettings parameter. --- .../Sif.Framework/Consumers/BasicConsumer.cs | 17 +- .../Sif.Framework/Consumers/Consumer.cs | 223 ++++++++++-------- Data/Databases/SQLite/SifFrameworkDatabase.db | Bin 205824 -> 205824 bytes 3 files changed, 129 insertions(+), 111 deletions(-) diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs index 6c57d699..dbba897e 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs @@ -15,6 +15,8 @@ */ using Sif.Framework.Model.DataModels; +using Sif.Framework.Model.Infrastructure; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Serialisation; using Sif.Framework.Utils; using System.Collections.Generic; @@ -30,21 +32,22 @@ namespace Sif.Framework.Consumers public class BasicConsumer : Consumer, string>, IBasicConsumer where T : ISifRefId { /// - /// Consumer + /// Consumer /// - public BasicConsumer(Model.Infrastructure.Environment environment) : base(environment) + public BasicConsumer(Environment environment, IFrameworkSettings settings = null) : base(environment, settings) { } /// - /// Consumer + /// Consumer /// public BasicConsumer( string applicationKey, string instanceId = null, string userToken = null, - string solutionId = null) - : base(applicationKey, instanceId, userToken, solutionId) + string solutionId = null, + IFrameworkSettings settings = null) + : base(applicationKey, instanceId, userToken, solutionId, settings) { } @@ -53,7 +56,7 @@ public BasicConsumer( /// protected override string SerialiseMultiple(List obj) { - XmlRootAttribute xmlRootAttribute = new XmlRootAttribute(TypeName + "s") + var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, IsNullable = false @@ -67,7 +70,7 @@ protected override string SerialiseMultiple(List obj) /// protected override List DeserialiseMultiple(string payload) { - XmlRootAttribute xmlRootAttribute = new XmlRootAttribute(TypeName + "s") + var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, IsNullable = false diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs index f6446bcf..6b9b7fc1 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs @@ -21,6 +21,7 @@ using Sif.Framework.Model.Query; using Sif.Framework.Model.Requests; using Sif.Framework.Model.Responses; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Mapper; using Sif.Framework.Service.Registration; using Sif.Framework.Service.Serialisation; @@ -40,63 +41,46 @@ namespace Sif.Framework.Consumers /// Type that defines a single object entity. /// Type that defines a multiple objects entity. /// Primary key type of the SIF data model object. - public class Consumer : IConsumer where TSingle : ISifRefId + public class Consumer : IConsumer + where TSingle : ISifRefId { - private static readonly slf4net.ILogger log = slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private readonly slf4net.ILogger log = + slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private Model.Infrastructure.Environment environmentTemplate; - protected Accept Accept - { - get - { - return SettingsManager.ConsumerSettings.Accept; - } - } + protected Accept Accept => ConsumerSettings.Accept; - protected ContentType ContentType - { - get - { - return SettingsManager.ConsumerSettings.ContentType; - } - } + protected IFrameworkSettings ConsumerSettings { get; } + + protected ContentType ContentType => ConsumerSettings.ContentType; /// /// Consumer environment. /// - protected Model.Infrastructure.Environment EnvironmentTemplate - { - get - { - return environmentTemplate; - } - } + protected Model.Infrastructure.Environment EnvironmentTemplate => environmentTemplate; /// /// Service for Consumer registration. /// - protected IRegistrationService RegistrationService { get; private set; } + protected IRegistrationService RegistrationService { get; } /// /// Name of the SIF data model that the Consumer is based on, e.g. SchoolInfo, StudentPersonal, etc. /// - protected virtual string TypeName - { - get - { - return typeof(TSingle).Name; - } - } + protected virtual string TypeName => typeof(TSingle).Name; /// /// Create a Consumer instance based upon the Environment passed. /// /// Environment object. - public Consumer(Model.Infrastructure.Environment environment) + /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. + public Consumer(Model.Infrastructure.Environment environment, IFrameworkSettings settings = null) { - environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, SettingsManager.ConsumerSettings); - RegistrationService = new RegistrationService(SettingsManager.ConsumerSettings, SessionsManager.ConsumerSessionService); + ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; + + environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); + RegistrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// @@ -106,11 +90,19 @@ public Consumer(Model.Infrastructure.Environment environment) /// Instance ID. /// User token. /// Solution ID. - public Consumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null) + /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. + public Consumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) { - Model.Infrastructure.Environment environment = new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId); - environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, SettingsManager.ConsumerSettings); - RegistrationService = new RegistrationService(SettingsManager.ConsumerSettings, SessionsManager.ConsumerSessionService); + ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; + + var environment = new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId); + environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); + RegistrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// @@ -119,19 +111,20 @@ public Consumer(string applicationKey, string instanceId = null, string userToke /// /// Message parameters. /// Query parameter string if message parameters exist; an empty string otherwise. - private string GenerateQueryParameterString(params RequestParameter[] messageParameters) + private static string GenerateQueryParameterString(params RequestParameter[] messageParameters) { - string queryParameterString = string.Empty; - - if (messageParameters != null) + if (messageParameters == null) { - IEnumerable queryParameters = messageParameters - .Where(m => m?.Type == ConveyanceType.QueryParameter) - .Select(m => $"{m.Name}={m.Value}"); - queryParameterString = string.Join("&", queryParameters); - queryParameterString = (string.IsNullOrWhiteSpace(queryParameterString) ? string.Empty : $"?{queryParameterString}"); + return string.Empty; } + IEnumerable queryParameters = messageParameters + .Where(m => m?.Type == ConveyanceType.QueryParameter) + .Select(m => $"{m.Name}={m.Value}"); + string queryParameterString = string.Join("&", queryParameters); + queryParameterString = + string.IsNullOrWhiteSpace(queryParameterString) ? string.Empty : $"?{queryParameterString}"; + return queryParameterString; } @@ -204,10 +197,11 @@ public virtual string GetChangesSinceMarker( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); WebHeaderCollection responseHeaders = HttpUtils.HeadRequest(url, RegistrationService.AuthorisationToken); return responseHeaders[ResponseParameterType.changesSinceMarker.ToDescription()]; @@ -228,11 +222,12 @@ public virtual TSingle Create( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{TypeName}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string requestBody = SerialiseSingle(obj); string responseBody = HttpUtils.PostRequest( url, @@ -241,6 +236,7 @@ public virtual TSingle Create( contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), mustUseAdvisory: mustUseAdvisory); + if (log.IsDebugEnabled) log.Debug("Response from POST request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); @@ -262,10 +258,11 @@ public virtual MultipleCreateResponse Create( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string requestBody = SerialiseMultiple(obj); string responseBody = HttpUtils.PostRequest( url, @@ -274,10 +271,14 @@ public virtual MultipleCreateResponse Create( contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), mustUseAdvisory: mustUseAdvisory); + if (log.IsDebugEnabled) log.Debug("Response from POST request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); - createResponseType createResponseType = SerialiserFactory.GetSerialiser(Accept).Deserialise(responseBody); - MultipleCreateResponse createResponse = MapperFactory.CreateInstance(createResponseType); + + createResponseType createResponseType = + SerialiserFactory.GetSerialiser(Accept).Deserialise(responseBody); + MultipleCreateResponse createResponse = + MapperFactory.CreateInstance(createResponseType); return createResponse; } @@ -296,22 +297,25 @@ public virtual TSingle Query( throw new InvalidOperationException("Consumer has not registered."); } - TSingle obj = default(TSingle); + TSingle obj = default; try { - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{refId}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug("Response from GET request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); + obj = DeserialiseSingle(responseBody); } catch (WebException ex) @@ -330,10 +334,6 @@ public virtual TSingle Query( throw; } } - catch (Exception) - { - throw; - } return obj; } @@ -353,10 +353,11 @@ public virtual TMultiple Query( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) @@ -397,10 +398,11 @@ public virtual TMultiple QueryByExample( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string requestBody = SerialiseSingle(obj); // TODO: Update PostRequest to accept paging parameters. string responseBody = HttpUtils.PostRequest( @@ -410,6 +412,7 @@ public virtual TMultiple QueryByExample( methodOverride: "GET", contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug("Response from POST (Query by Example) request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); @@ -432,7 +435,7 @@ public virtual TMultiple QueryByServicePath( throw new InvalidOperationException("Consumer has not registered."); } - StringBuilder servicePath = new StringBuilder(); + var servicePath = new StringBuilder(); if (conditions != null) { @@ -442,12 +445,14 @@ public virtual TMultiple QueryByServicePath( } } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append(servicePath) - .Append($"/{TypeName}s") - .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append($"/{TypeName}s").Append(HttpUtils.MatrixParameters(zoneId, contextId)) + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); + if (log.IsDebugEnabled) log.Debug("Service Path URL is " + url); + string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) @@ -456,10 +461,10 @@ public virtual TMultiple QueryByServicePath( url, RegistrationService.AuthorisationToken, ServiceType.SERVICEPATH, - navigationPage: (int)navigationPage, - navigationPageSize: (int)navigationPageSize, - contentTypeOverride: ContentType.ToDescription(), - acceptOverride: Accept.ToDescription()); + (int)navigationPage, + (int)navigationPageSize, + ContentType.ToDescription(), + Accept.ToDescription()); } else { @@ -494,11 +499,14 @@ public virtual TMultiple QueryChangesSince( RequestParameter[] messageParameters = (requestParameters ?? (new RequestParameter[0])); messageParameters = string.IsNullOrWhiteSpace(changesSinceMarker) ? messageParameters - : messageParameters.Concat(new RequestParameter[1] { new ChangesSinceQueryParameter(changesSinceMarker) }).ToArray(); - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + : messageParameters + .Concat(new RequestParameter[] { new ChangesSinceQueryParameter(changesSinceMarker) }) + .ToArray(); + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(messageParameters)).ToString(); + .Append(GenerateQueryParameterString(messageParameters)) + .ToString(); WebHeaderCollection responseHeaders; string responseBody; @@ -547,11 +555,12 @@ public TMultiple DynamicQuery( RequestParameter[] messageParameters = (requestParameters ?? (new RequestParameter[0])); messageParameters = string.IsNullOrWhiteSpace(whereClause) ? messageParameters - : messageParameters.Concat(new RequestParameter[1] { new DynamicQueryParameter(whereClause) }).ToArray(); - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + : messageParameters.Concat(new RequestParameter[] { new DynamicQueryParameter(whereClause) }).ToArray(); + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(messageParameters)).ToString(); + .Append(GenerateQueryParameterString(messageParameters)) + .ToString(); string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) @@ -590,11 +599,12 @@ public virtual void Update( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{obj.RefId}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string requestBody = SerialiseSingle(obj); string responseBody = HttpUtils.PutRequest( url, @@ -602,6 +612,7 @@ public virtual void Update( requestBody, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug("Response from PUT request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); } @@ -620,10 +631,11 @@ public virtual MultipleUpdateResponse Update( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string requestBody = SerialiseMultiple(obj); string responseBody = HttpUtils.PutRequest( url, @@ -631,10 +643,14 @@ public virtual MultipleUpdateResponse Update( requestBody, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug("Response from PUT request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); - updateResponseType updateResponseType = SerialiserFactory.GetSerialiser(Accept).Deserialise(responseBody); - MultipleUpdateResponse updateResponse = MapperFactory.CreateInstance(updateResponseType); + + updateResponseType updateResponseType = + SerialiserFactory.GetSerialiser(Accept).Deserialise(responseBody); + MultipleUpdateResponse updateResponse = + MapperFactory.CreateInstance(updateResponseType); return updateResponse; } @@ -653,16 +669,17 @@ public virtual void Delete( throw new InvalidOperationException("Consumer has not registered."); } - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") - .Append($"/{refId}") - .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append($"/{refId}").Append(HttpUtils.MatrixParameters(zoneId, contextId)) + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string responseBody = HttpUtils.DeleteRequest( url, RegistrationService.AuthorisationToken, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug("Response from DELETE request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); } @@ -681,19 +698,13 @@ public virtual MultipleDeleteResponse Delete( throw new InvalidOperationException("Consumer has not registered."); } - List deleteIds = new List(); - - foreach (TPrimaryKey id in refIds) - { - deleteIdType deleteId = new deleteIdType { id = id.ToString() }; - deleteIds.Add(deleteId); - } - - deleteRequestType request = new deleteRequestType { deletes = deleteIds.ToArray() }; - string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) + var request = + new deleteRequestType { deletes = refIds.Select(id => new deleteIdType { id = id.ToString() }).ToArray() }; + var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) - .Append(GenerateQueryParameterString(requestParameters)).ToString(); + .Append(GenerateQueryParameterString(requestParameters)) + .ToString(); string requestBody = SerialiserFactory.GetSerialiser(ContentType).Serialise(request); string responseBody = HttpUtils.PutRequest( url, @@ -702,10 +713,14 @@ public virtual MultipleDeleteResponse Delete( methodOverride: "DELETE", contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug("Response from PUT (DELETE) request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); - deleteResponseType updateResponseType = SerialiserFactory.GetSerialiser(Accept).Deserialise(responseBody); - MultipleDeleteResponse updateResponse = MapperFactory.CreateInstance(updateResponseType); + + deleteResponseType updateResponseType = + SerialiserFactory.GetSerialiser(Accept).Deserialise(responseBody); + MultipleDeleteResponse updateResponse = + MapperFactory.CreateInstance(updateResponseType); return updateResponse; } diff --git a/Data/Databases/SQLite/SifFrameworkDatabase.db b/Data/Databases/SQLite/SifFrameworkDatabase.db index a56081a06d51083d4392f2c66cf21a22a747eb8c..d114678f70bf481c29309892a1f3d1c1b96599ab 100644 GIT binary patch delta 677 zcmZoT!P9VpXM(ig90mr4lR$g|h$|QvR`gBF*iFzK%@v%PX6%xhn;(^*mujR0@|Zfhn$4fQ&oLXLi=t>`Qe@Fl z$FOnnXa5C^o}0hCXXRn^-u&zL4`xQM&7c4CDs0nWWMSFPqQLlveVY!WJeyjQv1w|e zrD>XOVp5W&u8C1fimrvJL5i-qfq}7+p}B>Lxv9CX@?^tYz4l@w#_h#MOg*nTy@AQe z1BgARbI38PGkQ%okYmo*^a6_b1F;Pd+X1mF5Q9|u0&xHkI{-0Q*Y*=~%oeNwCK}Zg delta 676 zcmZoT!P9VpXM(h#9s>izNgzG}#1#w-E9OnqF=o`;m|&wVaENi^^jXQi4r_BH3%(w> zUAuXWwhIS_=q8f{?s{~k%4}k6EIN#g=;BJOVyxK26dx}G*@tDnz2i2ZhlmLUaFB2$Ybj0YBqoJKF4f~E{dX&Ns&cI z9mB@OpZymwdT;*no|T8uYxA$)KbRRkH-G-mtFTOkkz< Date: Fri, 11 Dec 2020 22:46:17 +0800 Subject: [PATCH 05/16] Restructuring and code clean up of Providers and Provider services. Corrected a logic issue with the mustUseAdvisory flag. --- .../Sif.Framework/Providers/BasicProvider.cs | 64 ++--- .../Sif.Framework/Providers/IBasicProvider.cs | 31 --- .../Sif.Framework/Providers/IProvider.cs | 56 ++-- .../Sif.Framework/Providers/ObjectProvider.cs | 129 ++++++++++ .../Sif.Framework/Providers/Provider.cs | 243 ++++++------------ .../Providers/IBasicProviderService.cs | 4 +- .../Providers/IObjectProviderService.cs | 67 +++++ .../Service/Providers/IProviderService.cs | 41 +-- 8 files changed, 334 insertions(+), 301 deletions(-) delete mode 100644 Code/Sif3Framework/Sif.Framework/Providers/IBasicProvider.cs create mode 100644 Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs create mode 100644 Code/Sif3Framework/Sif.Framework/Service/Providers/IObjectProviderService.cs diff --git a/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs index 02e52208..f5d5bec6 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs @@ -36,16 +36,14 @@ namespace Sif.Framework.Providers /// type System.String and the multiple objects entity is represented as a list of single objects. /// /// Type of object associated with the Service Provider. - public abstract class BasicProvider : Provider>, IProvider, string> - where T : ISifRefId + public abstract class BasicProvider : Provider> where T : ISifRefId { /// /// Create an instance based on the specified service. /// /// Service used for managing the object type. - protected BasicProvider(IBasicProviderService service) : base() + protected BasicProvider(IBasicProviderService service) : base(service) { - this.service = service; } /// @@ -56,18 +54,13 @@ public override IHttpActionResult Post( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised( - Request.Headers, - sessionToken, - $"{TypeName}s", - RightType.CREATE, - RightValue.APPROVED)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.CREATE)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -77,7 +70,6 @@ public override IHttpActionResult Post( return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } - IHttpActionResult result; ICollection createStatuses = new List(); try @@ -87,34 +79,32 @@ public override IHttpActionResult Post( foreach (T obj in objs) { bool hasAdvisoryId = !string.IsNullOrWhiteSpace(obj.RefId); - createType status = new createType + var status = new createType { advisoryId = (hasAdvisoryId ? obj.RefId : null) }; try { - if (mustUseAdvisory.HasValue && mustUseAdvisory.Value == true) + if (mustUseAdvisory.HasValue) { - if (hasAdvisoryId) - { - status.id = service - .Create(obj, mustUseAdvisory, zoneId: (zoneId?[0]), contextId: (contextId?[0])) - .RefId; - status.statusCode = ((int)HttpStatusCode.Created).ToString(); - } - else + if (mustUseAdvisory.Value && !hasAdvisoryId) { status.error = ProviderUtils.CreateError( HttpStatusCode.BadRequest, TypeName, "Create request failed as object ID is not provided, but mustUseAdvisory is true."); - status.statusCode = ((int)HttpStatusCode.BadRequest).ToString(); + status.statusCode = ((int) HttpStatusCode.BadRequest).ToString(); + } + else + { + status.id = Service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0]).RefId; + status.statusCode = ((int) HttpStatusCode.Created).ToString(); } } else { - status.id = service.Create(obj, zoneId: (zoneId?[0]), contextId: (contextId?[0])).RefId; + status.id = Service.Create(obj, null, zoneId?[0], contextId?[0]).RefId; status.statusCode = ((int)HttpStatusCode.Created).ToString(); } } @@ -167,10 +157,9 @@ public override IHttpActionResult Post( // Need to ignore exceptions otherwise it would not be possible to return status records of processed objects. } - createResponseType createResponse = new createResponseType { creates = createStatuses.ToArray() }; - result = Ok(createResponse); + var createResponse = new createResponseType { creates = createStatuses.ToArray() }; - return result; + return Ok(createResponse); } /// @@ -181,18 +170,13 @@ public override IHttpActionResult Put( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised( - Request.Headers, - sessionToken, - $"{TypeName}s", - RightType.CREATE, - RightValue.APPROVED)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.CREATE)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -202,21 +186,20 @@ public override IHttpActionResult Put( return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } - IHttpActionResult result; ICollection updateStatuses = new List(); try { foreach (T obj in objs) { - updateType status = new updateType + var status = new updateType { id = obj.RefId }; try { - service.Update(obj, zoneId: (zoneId?[0]), contextId: (contextId?[0])); + Service.Update(obj, (zoneId?[0]), (contextId?[0])); status.statusCode = ((int)HttpStatusCode.NoContent).ToString(); } catch (ArgumentException e) @@ -260,10 +243,9 @@ public override IHttpActionResult Put( // Need to ignore exceptions otherwise it would not be possible to return status records of processed objects. } - updateResponseType updateResponse = new updateResponseType { updates = updateStatuses.ToArray() }; - result = Ok(updateResponse); + var updateResponse = new updateResponseType { updates = updateStatuses.ToArray() }; - return result; + return Ok(updateResponse); } /// @@ -272,7 +254,7 @@ public override IHttpActionResult Put( [NonAction] public override string SerialiseEvents(List obj) { - XmlRootAttribute xmlRootAttribute = new XmlRootAttribute(TypeName + "s") + var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, IsNullable = false diff --git a/Code/Sif3Framework/Sif.Framework/Providers/IBasicProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/IBasicProvider.cs deleted file mode 100644 index 81655d0b..00000000 --- a/Code/Sif3Framework/Sif.Framework/Providers/IBasicProvider.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2016 Systemic Pty Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; - -namespace Sif.Framework.Providers -{ - - /// - /// This is a convenience interface for Providers of SIF data model objects whereby the primary key is of type - /// System.String and the multiple objects entity is represented as a list of single objects. - /// - /// Type that defines a SIF data model object. - interface IBasicProvider : IProvider, string> - { - } - -} diff --git a/Code/Sif3Framework/Sif.Framework/Providers/IProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/IProvider.cs index a7572906..e83a875c 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/IProvider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/IProvider.cs @@ -1,12 +1,12 @@ /* - * Copyright 2017 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,22 +19,20 @@ namespace Sif.Framework.Providers { - /// /// This interface defines the operations available for Providers of SIF data model objects. /// /// Type that defines a single object entity. /// Type that defines a multiple objects entity. /// Primary key type of the SIF data model object. - interface IProvider + internal interface IProvider { - /// /// Create a single object. /// POST api/{controller}/TSingle /// /// 201 - Success, object created - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 404 - Failure, not found (reject mustUseAdvisory) @@ -52,7 +50,7 @@ interface IProvider /// POST api/{controller} /// /// 200 - Success, ok - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 500 - Failure, internal service error @@ -68,7 +66,7 @@ interface IProvider /// GET api/{controller}/{id} /// /// 200 - Success, ok - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 404 - Failure, not found @@ -86,11 +84,11 @@ interface IProvider /// GET api/{controller} -> where obj is null /// /// Retrieve multiple objects using Query by Example. - /// GET api/{controller} -> POST api/{controller} where methodOverride=GET and obj is not nullvvvv + /// GET api/{controller} -> POST api/{controller} where methodOverride=GET and obj is not null /// /// 200 - Success, ok /// 204 - Success, no content - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 413 - Failure, response too large @@ -101,7 +99,11 @@ interface IProvider /// Zone associated with the request. /// Zone context. /// All objects, objects that match the properties of the example object or no objects (TMultiple). - IHttpActionResult Get(TSingle obj, string changesSinceMarker = null, string[] zoneId = null, string[] contextId = null); + IHttpActionResult Get( + TSingle obj, + string changesSinceMarker = null, + string[] zoneId = null, + string[] contextId = null); /// /// Retrieve multiple objects using Service Paths. @@ -113,7 +115,7 @@ interface IProvider /// /// 200 - Success, ok /// 204 - Success, no content - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 413 - Failure, response too large @@ -128,14 +130,22 @@ interface IProvider /// Zone associated with the request. /// Zone context. /// Objects that meet the associated object and identifier pairs (TMultiple). - IHttpActionResult Get(string object1, string id1, string object2 = null, string id2 = null, string object3 = null, string id3 = null, string[] zoneId = null, string[] contextId = null); + IHttpActionResult Get( + string object1, + string id1, + string object2 = null, + string id2 = null, + string object3 = null, + string id3 = null, + string[] zoneId = null, + string[] contextId = null); /// /// Update a single object. /// PUT api/{controller}/{id} /// /// 204 - Success, no content - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 404 - Failure, not found @@ -153,7 +163,7 @@ interface IProvider /// PUT api/{controller} /// /// 200 - Success, ok - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 500 - Failure, internal service error @@ -169,7 +179,7 @@ interface IProvider /// DELETE api/{controller}/{id} /// /// 204 - Success, no content - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 404 - Failure, not found @@ -186,7 +196,7 @@ interface IProvider /// DELETE api/{controller} -> PUT api/{controller} with methodOverride=DELETEvv /// /// 200 - Success, ok - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 500 - Failure, internal service error @@ -203,7 +213,7 @@ interface IProvider /// /// 200 - Success, ok /// 204 - Success, no content - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 403 - Failure, forbidden /// 413 - Failure, response too large @@ -218,7 +228,7 @@ interface IProvider /// Broadcast SIF Events. /// /// 200 - Success, ok - /// 400 - Failue, bad request + /// 400 - Failure, bad request /// 401 - Failure, unauthorised /// 500 - Failure, internal service error /// @@ -226,7 +236,5 @@ interface IProvider /// Zone context. /// Ok IHttpActionResult BroadcastEvents(string zoneId = null, string contextId = null); - } - -} +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs new file mode 100644 index 00000000..b9427329 --- /dev/null +++ b/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs @@ -0,0 +1,129 @@ +/* + * Copyright 2020 Systemic Pty Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Sif.Framework.Model.DataModels; +using Sif.Framework.Model.Infrastructure; +using Sif.Framework.Model.Parameters; +using Sif.Framework.Model.Responses; +using Sif.Framework.Service.Mapper; +using Sif.Framework.Service.Providers; +using Sif.Framework.Service.Serialisation; +using Sif.Framework.Utils; +using Sif.Framework.WebApi.ModelBinders; +using Sif.Specification.Infrastructure; +using System.Net; +using System.Web.Http; + +namespace Sif.Framework.Providers +{ + public abstract class ObjectProvider + : Provider where TSingle : ISifRefId + { + private readonly IObjectProviderService service; + + /// + /// Create an instance based on the specified service. + /// + /// Service used for managing the object type. + protected ObjectProvider(IObjectProviderService service) : base(service) + { + this.service = service; + } + + /// + /// Post + /// + public override IHttpActionResult Post( + TMultiple obj, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) + { + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + { + return Unauthorized(); + } + + // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.CREATE)) + { + return StatusCode(HttpStatusCode.Forbidden); + } + + if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) + { + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); + } + + bool? mustUseAdvisory = HttpUtils.GetMustUseAdvisory(Request.Headers); + RequestParameter[] requestParameters = GetQueryParameters(Request); + MultipleCreateResponse multipleCreateResponse = service.Create( + obj, + mustUseAdvisory, + zoneId?[0], + contextId?[0], + requestParameters); + createResponseType createResponse = + MapperFactory.CreateInstance(multipleCreateResponse); + + return Ok(createResponse); + } + + /// + /// Put + /// + public override IHttpActionResult Put( + TMultiple obj, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) + { + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + { + return Unauthorized(); + } + + // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.UPDATE)) + { + return StatusCode(HttpStatusCode.Forbidden); + } + + if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) + { + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); + } + + RequestParameter[] requestParameters = GetQueryParameters(Request); + MultipleUpdateResponse multipleUpdateResponse = service.Update( + obj, + zoneId?[0], + contextId?[0], + requestParameters); + updateResponseType updateResponse = + MapperFactory.CreateInstance(multipleUpdateResponse); + + return Ok(updateResponse); + } + + /// + /// SerialiseEvents + /// + [NonAction] + public override string SerialiseEvents(TMultiple obj) + { + return SerialiserFactory.GetSerialiser(ContentType).Serialise(obj); + } + } +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs b/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs index 13ebeca3..716358bc 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs @@ -23,15 +23,11 @@ using Sif.Framework.Model.Parameters; using Sif.Framework.Model.Query; using Sif.Framework.Model.Requests; -using Sif.Framework.Model.Responses; -using Sif.Framework.Service; using Sif.Framework.Service.Authentication; using Sif.Framework.Service.Authorisation; using Sif.Framework.Service.Infrastructure; -using Sif.Framework.Service.Mapper; using Sif.Framework.Service.Providers; using Sif.Framework.Service.Registration; -using Sif.Framework.Service.Serialisation; using Sif.Framework.Utils; using Sif.Framework.WebApi.ModelBinders; using Sif.Specification.Infrastructure; @@ -54,47 +50,35 @@ public abstract class Provider : ApiController, IProvider, IEventPayloadSerialisable where TSingle : ISifRefId { + /// + /// Accepted content type (XML or JSON) for a message payload. + /// + protected Accept Accept => SettingsManager.ProviderSettings.Accept; + /// /// Service used for request authentication. /// - protected IAuthenticationService authenticationService; + protected IAuthenticationService AuthenticationService { get; } /// /// Service used for request authorisation. /// - protected IAuthorisationService authorisationService; + protected IAuthorisationService AuthorisationService { get; } /// - /// Object service associated with this Provider. + /// Content type (XML or JSON) of the message payload. /// - protected IObjectService service; - - protected Accept Accept - { - get - { - return SettingsManager.ProviderSettings.Accept; - } - } + protected ContentType ContentType => SettingsManager.ProviderSettings.ContentType; - protected ContentType ContentType - { - get - { - return SettingsManager.ProviderSettings.ContentType; - } - } + /// + /// Object service associated with this Provider. + /// + protected IProviderService Service { get; } /// /// Name of the SIF data model that the Provider is based on, e.g. SchoolInfo, StudentPersonal, etc. /// - protected virtual string TypeName - { - get - { - return typeof(TSingle).Name; - } - } + protected virtual string TypeName => typeof(TSingle).Name; /// /// Default constructor that is only available to derived instances of @@ -104,25 +88,38 @@ protected Provider() { if (EnvironmentType.DIRECT.Equals(SettingsManager.ProviderSettings.EnvironmentType)) { - authenticationService = + AuthenticationService = new DirectAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); } else if (EnvironmentType.BROKERED.Equals(SettingsManager.ProviderSettings.EnvironmentType)) { - authenticationService = + AuthenticationService = new BrokeredAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); } - authorisationService = new AuthorisationService(authenticationService); + AuthorisationService = new AuthorisationService(AuthenticationService); } /// /// Create an instance based on the specified service. /// /// Service used for managing the object type. - protected Provider(IProviderService service) : base() + protected Provider(IProviderService service) { - this.service = service; + Service = service; + + if (EnvironmentType.DIRECT.Equals(SettingsManager.ProviderSettings.EnvironmentType)) + { + AuthenticationService = + new DirectAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); + } + else if (EnvironmentType.BROKERED.Equals(SettingsManager.ProviderSettings.EnvironmentType)) + { + AuthenticationService = + new BrokeredAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); + } + + AuthorisationService = new AuthorisationService(AuthenticationService); } /// @@ -130,7 +127,7 @@ protected Provider(IProviderService service) : base() /// /// HTTP Request. /// Query parameters if found; an empty collection otherwise. - private RequestParameter[] GetQueryParameters(HttpRequestMessage request) + protected RequestParameter[] GetQueryParameters(HttpRequestMessage request) { if (request == null) { @@ -151,13 +148,13 @@ public virtual IHttpActionResult Post( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.CREATE)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.CREATE)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -174,29 +171,26 @@ public virtual IHttpActionResult Post( bool hasAdvisoryId = !string.IsNullOrWhiteSpace(obj.RefId); bool? mustUseAdvisory = HttpUtils.GetMustUseAdvisory(Request.Headers); - if (mustUseAdvisory.HasValue && mustUseAdvisory.Value == true) + if (mustUseAdvisory.HasValue) { - if (hasAdvisoryId) + if (mustUseAdvisory.Value && !hasAdvisoryId) + { + result = BadRequest( + $"Request failed for object {TypeName} as object ID is not provided, but mustUseAdvisory is true."); + } + else { RequestParameter[] requestParameters = GetQueryParameters(Request); TSingle createdObject = - service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0], requestParameters); + Service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0], requestParameters); string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); result = Created(uri, createdObject); } - else - { - result = BadRequest($"Request failed for object {TypeName} as object ID is not provided, but mustUseAdvisory is true."); - } } else { RequestParameter[] requestParameters = GetQueryParameters(Request); - TSingle createdObject = service.Create( - obj, - zoneId: zoneId?[0], - contextId: contextId?[0], - requestParameters: requestParameters); + TSingle createdObject = Service.Create(obj, null, zoneId?[0], contextId?[0], requestParameters); string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); result = Created(uri, createdObject); } @@ -233,41 +227,7 @@ public virtual IHttpActionResult Post( /// /// Post /// - public virtual IHttpActionResult Post( - TMultiple obj, - [MatrixParameter] string[] zoneId = null, - [MatrixParameter] string[] contextId = null) - { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) - { - return Unauthorized(); - } - - // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.CREATE)) - { - return StatusCode(HttpStatusCode.Forbidden); - } - - if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) - { - return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); - } - - bool? mustUseAdvisory = HttpUtils.GetMustUseAdvisory(Request.Headers); - RequestParameter[] requestParameters = GetQueryParameters(Request); - MultipleCreateResponse multipleCreateResponse = ((IProviderService)service).Create( - obj, - mustUseAdvisory, - zoneId?[0], - contextId?[0], - requestParameters); - createResponseType createResponse = - MapperFactory.CreateInstance(multipleCreateResponse); - IHttpActionResult result = Ok(createResponse); - - return result; - } + public abstract IHttpActionResult Post(TMultiple obj, string[] zoneId = null, string[] contextId = null); /// /// Get @@ -277,13 +237,13 @@ public virtual IHttpActionResult Get( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.QUERY)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.QUERY)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -303,7 +263,7 @@ public virtual IHttpActionResult Get( try { RequestParameter[] requestParameters = GetQueryParameters(Request); - TSingle obj = service.Retrieve(refId, zoneId?[0], contextId?[0], requestParameters); + TSingle obj = Service.Retrieve(refId, zoneId?[0], contextId?[0], requestParameters); if (obj == null) { @@ -351,7 +311,7 @@ private IHttpActionResult GetAll(string zoneId, string contextId) uint? navigationPageSize = HttpUtils.GetNavigationPageSize(Request.Headers); RequestParameter[] requestParameters = GetQueryParameters(Request); TMultiple objs = - service.Retrieve(navigationPage, navigationPageSize, zoneId, contextId, requestParameters); + Service.Retrieve(navigationPage, navigationPageSize, zoneId, contextId, requestParameters); IHttpActionResult result; if (objs == null) @@ -385,7 +345,7 @@ private IHttpActionResult GetChangesSince(string changesSinceMarker, string zone } bool changesSinceRequested = !string.IsNullOrWhiteSpace(changesSinceMarker); - IChangesSinceService changesSinceService = service as IChangesSinceService; + var changesSinceService = Service as IChangesSinceService; bool changesSinceSupported = (changesSinceService != null); if (changesSinceRequested && !changesSinceSupported) @@ -429,7 +389,7 @@ private IHttpActionResult GetChangesSince(string changesSinceMarker, string zone catch (Exception) { throw new QueryException( - "Implementaton to retrieve the next Changes Since marker returned an error."); + "Implementation to retrieve the next Changes Since marker returned an error."); } } @@ -458,7 +418,7 @@ private IHttpActionResult GetQueryByExample(TSingle obj, string zoneId, string c uint? navigationPageSize = HttpUtils.GetNavigationPageSize(Request.Headers); RequestParameter[] requestParameters = GetQueryParameters(Request); TMultiple objs = - service.Retrieve(obj, navigationPage, navigationPageSize, zoneId, contextId, requestParameters); + Service.Retrieve(obj, navigationPage, navigationPageSize, zoneId, contextId, requestParameters); IHttpActionResult result; if (objs == null) @@ -482,13 +442,13 @@ public virtual IHttpActionResult Get( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.QUERY)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.QUERY)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -509,14 +469,9 @@ public virtual IHttpActionResult Get( { if (obj == null) { - if (changesSinceMarker == null) - { - result = GetAll(zoneId?[0], contextId?[0]); - } - else - { - result = GetChangesSince(changesSinceMarker, zoneId?[0], contextId?[0]); - } + result = changesSinceMarker == null + ? GetAll(zoneId?[0], contextId?[0]) + : GetChangesSince(changesSinceMarker, zoneId?[0], contextId?[0]); } else { @@ -525,7 +480,7 @@ public virtual IHttpActionResult Get( } catch (ArgumentException e) { - result = BadRequest("One or more parameters of the GET request are invalid.\n{e.Message}"); + result = BadRequest($"One or more parameters of the GET request are invalid.\n{e.Message}"); } catch (QueryException e) { @@ -555,7 +510,7 @@ public virtual IHttpActionResult Get(string object1, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } @@ -576,7 +531,7 @@ public virtual IHttpActionResult Get(string object1, } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, serviceName, RightType.QUERY)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, serviceName, RightType.QUERY)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -611,7 +566,7 @@ public virtual IHttpActionResult Get(string object1, uint? navigationPage = HttpUtils.GetNavigationPage(Request.Headers); uint? navigationPageSize = HttpUtils.GetNavigationPageSize(Request.Headers); RequestParameter[] requestParameters = GetQueryParameters(Request); - TMultiple objs = service.Retrieve( + TMultiple objs = Service.Retrieve( conditions, navigationPage, navigationPageSize, @@ -657,13 +612,13 @@ public virtual IHttpActionResult Put( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.UPDATE)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.UPDATE)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -684,7 +639,7 @@ public virtual IHttpActionResult Put( try { RequestParameter[] requestParameters = GetQueryParameters(Request); - service.Update(obj, zoneId?[0], contextId?[0], requestParameters); + Service.Update(obj, zoneId?[0], contextId?[0], requestParameters); result = StatusCode(HttpStatusCode.NoContent); } catch (ArgumentException e) @@ -710,39 +665,7 @@ public virtual IHttpActionResult Put( /// /// Put /// - public virtual IHttpActionResult Put( - TMultiple obj, - [MatrixParameter] string[] zoneId = null, - [MatrixParameter] string[] contextId = null) - { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) - { - return Unauthorized(); - } - - // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.UPDATE)) - { - return StatusCode(HttpStatusCode.Forbidden); - } - - if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) - { - return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); - } - - RequestParameter[] requestParameters = GetQueryParameters(Request); - MultipleUpdateResponse multipleUpdateResponse = ((IProviderService)service).Update( - obj, - zoneId?[0], - contextId?[0], - requestParameters); - updateResponseType updateResponse = - MapperFactory.CreateInstance(multipleUpdateResponse); - IHttpActionResult result = Ok(updateResponse); - - return result; - } + public abstract IHttpActionResult Put(TMultiple obj, string[] zoneId = null, string[] contextId = null); /// /// Delete @@ -752,13 +675,13 @@ public virtual IHttpActionResult Delete( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.DELETE)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.DELETE)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -773,7 +696,7 @@ public virtual IHttpActionResult Delete( try { RequestParameter[] requestParameters = GetQueryParameters(Request); - service.Delete(refId, zoneId?[0], contextId?[0], requestParameters); + Service.Delete(refId, zoneId?[0], contextId?[0], requestParameters); result = StatusCode(HttpStatusCode.NoContent); } catch (ArgumentException e) @@ -804,13 +727,13 @@ public virtual IHttpActionResult Delete( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.DELETE)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.DELETE)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -820,14 +743,13 @@ public virtual IHttpActionResult Delete( return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } - IHttpActionResult result; ICollection deleteStatuses = new List(); try { foreach (deleteIdType deleteId in deleteRequest.deletes) { - deleteStatus status = new deleteStatus + var status = new deleteStatus { id = deleteId.id }; @@ -835,7 +757,7 @@ public virtual IHttpActionResult Delete( try { RequestParameter[] requestParameters = GetQueryParameters(Request); - service.Delete(deleteId.id, zoneId?[0], contextId?[0], requestParameters); + Service.Delete(deleteId.id, zoneId?[0], contextId?[0], requestParameters); status.statusCode = ((int)HttpStatusCode.NoContent).ToString(); } catch (ArgumentException e) @@ -879,10 +801,9 @@ public virtual IHttpActionResult Delete( // Need to ignore exceptions otherwise it would not be possible to return status records of processed objects. } - deleteResponseType deleteResponse = new deleteResponseType { deletes = deleteStatuses.ToArray() }; - result = Ok(deleteResponse); + var deleteResponse = new deleteResponseType { deletes = deleteStatuses.ToArray() }; - return result; + return Ok(deleteResponse); } /// @@ -893,13 +814,13 @@ public virtual IHttpActionResult Head( [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) { - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string sessionToken)) { return Unauthorized(); } // Check ACLs and return StatusCode(HttpStatusCode.Forbidden) if appropriate. - if (!authorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.QUERY)) + if (!AuthorisationService.IsAuthorised(Request.Headers, sessionToken, $"{TypeName}s", RightType.QUERY)) { return StatusCode(HttpStatusCode.Forbidden); } @@ -920,7 +841,7 @@ public virtual IHttpActionResult Head( { result = GetAll(zoneId?[0], contextId?[0]).ClearContent(); - if (service is ISupportsChangesSince supportsChangesSince) + if (Service is ISupportsChangesSince supportsChangesSince) { result = result.AddHeader( "changesSinceMarker", @@ -954,7 +875,7 @@ public virtual IHttpActionResult Head( [HttpGet] public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string contextId = null) { - IEventService eventService = service as IEventService; + var eventService = Service as IEventService; bool eventsSupported = (eventService != null); if (!eventsSupported) @@ -997,7 +918,7 @@ public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string co { SifEvent sifEvent = eventIterator.GetNext(); - NameValueCollection requestHeaders = new NameValueCollection() + var requestHeaders = new NameValueCollection() { { EventParameterType.eventAction.ToDescription(), sifEvent.EventAction.ToDescription() }, { EventParameterType.messageId.ToDescription(), sifEvent.Id.ToString() }, @@ -1041,10 +962,6 @@ public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string co /// /// /// - [NonAction] - public virtual string SerialiseEvents(TMultiple obj) - { - return SerialiserFactory.GetSerialiser(ContentType).Serialise(obj); - } + public abstract string SerialiseEvents(TMultiple obj); } } \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework/Service/Providers/IBasicProviderService.cs b/Code/Sif3Framework/Sif.Framework/Service/Providers/IBasicProviderService.cs index af1563e3..5222ddab 100644 --- a/Code/Sif3Framework/Sif.Framework/Service/Providers/IBasicProviderService.cs +++ b/Code/Sif3Framework/Sif.Framework/Service/Providers/IBasicProviderService.cs @@ -1,5 +1,5 @@ /* - * Copyright 2016 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ namespace Sif.Framework.Service.Providers /// single objects. /// /// SIF data model object type. - public interface IBasicProviderService : IObjectService, string> + public interface IBasicProviderService : IProviderService> { } diff --git a/Code/Sif3Framework/Sif.Framework/Service/Providers/IObjectProviderService.cs b/Code/Sif3Framework/Sif.Framework/Service/Providers/IObjectProviderService.cs new file mode 100644 index 00000000..50a64d90 --- /dev/null +++ b/Code/Sif3Framework/Sif.Framework/Service/Providers/IObjectProviderService.cs @@ -0,0 +1,67 @@ +/* + * Copyright 2020 Systemic Pty Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Sif.Framework.Model.Parameters; +using Sif.Framework.Model.Responses; + +namespace Sif.Framework.Service.Providers +{ + /// + /// In addition to the operations provided by the IProviderService interface, this interface defines operations for + /// the creation and update of the multiple objects type. + /// + /// Type that defines a single object entity. + /// Type that defines a multiple objects entity. + public interface IObjectProviderService : IProviderService + { + /// + /// Create multiple objects. + /// + /// Object (multiple object entity) to create. + /// Flag to indicate whether the object's identifier should be retained. + /// Zone associated with the request. + /// Zone context. + /// Additional parameters associated with the request. + /// Object already exists. + /// Parameter is invalid. + /// Error creating object. + /// Create operation not valid for the given object. + /// Response containing status of each object created. + MultipleCreateResponse Create( + TMultiple obj, + bool? mustUseAdvisory = null, + string zoneId = null, + string contextId = null, + params RequestParameter[] requestParameters); + + /// + /// Update multiple objects. + /// + /// Object (multiple object entity) to update + /// Zone associated with the request. + /// Zone context. + /// Additional parameters associated with the request. + /// Parameter is invalid. + /// Object to update not found. + /// Error updating objects. + /// Response containing status of each object updated. + MultipleUpdateResponse Update( + TMultiple obj, + string zoneId = null, + string contextId = null, + params RequestParameter[] requestParameters); + } +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework/Service/Providers/IProviderService.cs b/Code/Sif3Framework/Sif.Framework/Service/Providers/IProviderService.cs index d3463a8e..5472d442 100644 --- a/Code/Sif3Framework/Sif.Framework/Service/Providers/IProviderService.cs +++ b/Code/Sif3Framework/Sif.Framework/Service/Providers/IProviderService.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,6 @@ * limitations under the License. */ -using Sif.Framework.Model.Parameters; -using Sif.Framework.Model.Responses; - namespace Sif.Framework.Service.Providers { /// @@ -26,41 +23,5 @@ namespace Sif.Framework.Service.Providers /// Type that defines a multiple objects entity. public interface IProviderService : IObjectService { - /// - /// Create multiple objects. - /// - /// Object (multiple object entity) to create. - /// Flag to indicate whether the object's identifier should be retained. - /// Zone associated with the request. - /// Zone context. - /// Additional parameters associated with the request. - /// Object already exists. - /// Parameter is invalid. - /// Error creating object. - /// Create operation not valid for the given object. - /// Response containing status of each object created. - MultipleCreateResponse Create( - TMultiple obj, - bool? mustUseAdvisory = null, - string zoneId = null, - string contextId = null, - params RequestParameter[] requestParameters); - - /// - /// Update multiple objects. - /// - /// Object (multiple object entity) to update - /// Zone associated with the request. - /// Zone context. - /// Additional parameters associated with the request. - /// Parameter is invalid. - /// Object to update not found. - /// Error updating objects. - /// Response containing status of each object updated. - MultipleUpdateResponse Update( - TMultiple obj, - string zoneId = null, - string contextId = null, - params RequestParameter[] requestParameters); } } \ No newline at end of file From 18d92ae923dc29d11549f1de82bef86a58c1f142 Mon Sep 17 00:00:00 2001 From: rafidzal Date: Sat, 12 Dec 2020 17:03:02 +0800 Subject: [PATCH 06/16] Modified the constructors of the Event Consumer classes to include an IFrameworkSettings parameter. Updated demo projects (including Broker) to reflect these chnages. General code clean up. --- .../Sif.Framework/Consumers/BasicConsumer.cs | 5 +- .../Consumers/BasicEventConsumer.cs | 33 +-- .../Sif.Framework/Consumers/Consumer.cs | 9 + .../Sif.Framework/Consumers/EventConsumer.cs | 232 +++++++++++------- .../Sif.Framework/Providers/BasicProvider.cs | 11 +- .../Sif.Framework/Providers/ObjectProvider.cs | 5 +- .../Sif.Framework/Providers/Provider.cs | 41 ++-- .../ConsumerApp.cs | 5 +- .../Consumers/StudentPersonalConsumer.cs | 32 +-- .../Consumers/StudentPersonalEventConsumer.cs | 62 +++-- .../StudentSchoolEnrollmentConsumer.cs | 18 +- .../EnrollmentConsumerApp.cs | 5 +- .../EventConsumerApp.cs | 3 +- .../Controllers/SchoolInfosProvider.cs | 16 +- .../Controllers/StudentPersonalsProvider.cs | 19 +- .../StudentSchoolEnrollmentsProvider.cs | 6 +- .../Controllers/EventsProvider.cs | 81 +++--- .../Controllers/QueuesProvider.cs | 150 ++++++----- .../Controllers/SubscriptionsProvider.cs | 79 +++--- .../Sif.Framework.Demo.Broker.csproj | 9 +- .../Sif.Framework.Demo.Broker/packages.config | 1 - Data/Databases/SQLite/SifFrameworkDatabase.db | Bin 205824 -> 205824 bytes .../Configuring the Event Consumer demo.md | 17 ++ 23 files changed, 483 insertions(+), 356 deletions(-) create mode 100644 Documentation/Developer Guides/Configuring the Event Consumer demo.md diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs index dbba897e..8b2f9c15 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs @@ -18,7 +18,6 @@ using Sif.Framework.Model.Infrastructure; using Sif.Framework.Model.Settings; using Sif.Framework.Service.Serialisation; -using Sif.Framework.Utils; using System.Collections.Generic; using System.Xml.Serialization; @@ -58,7 +57,7 @@ protected override string SerialiseMultiple(List obj) { var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { - Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, + Namespace = ConsumerSettings.DataModelNamespace, IsNullable = false }; @@ -72,7 +71,7 @@ protected override List DeserialiseMultiple(string payload) { var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { - Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, + Namespace = ConsumerSettings.DataModelNamespace, IsNullable = false }; diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/BasicEventConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/BasicEventConsumer.cs index c3340a31..f8c08048 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/BasicEventConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/BasicEventConsumer.cs @@ -1,12 +1,12 @@ /* - * Copyright 2017 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,34 +15,37 @@ */ using Sif.Framework.Model.DataModels; +using Sif.Framework.Model.Settings; using System.Collections.Generic; namespace Sif.Framework.Consumers { - /// /// This is a convenience class for SIF Event Consumers of SIF data model objects whereby the primary key is of /// type System.String and the multiple objects entity is represented as a list of single objects. /// /// Type that defines a SIF data model object. - public abstract class BasicEventConsumer : EventConsumer, string>, IEventConsumer where T : ISifRefId + public abstract class BasicEventConsumer : EventConsumer, string> where T : ISifRefId { - /// - /// EventConsumer + /// EventConsumer /// - public BasicEventConsumer(Model.Infrastructure.Environment environment) : base(environment) + protected BasicEventConsumer(Model.Infrastructure.Environment environment, IFrameworkSettings settings = null) + : base(environment, settings) { } /// - /// EventConsumer + /// EventConsumer /// - public BasicEventConsumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null) - : base(applicationKey, instanceId, userToken, solutionId) + protected BasicEventConsumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) + : base(applicationKey, instanceId, userToken, solutionId, settings) { } - } - -} +} \ No newline at end of file diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs index 6b9b7fc1..4a3ec3cd 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs @@ -49,10 +49,19 @@ public class Consumer : IConsumer + /// Accepted content type (XML or JSON) for a message payload. + /// protected Accept Accept => ConsumerSettings.Accept; + /// + /// Application settings associated with the Consumer. + /// protected IFrameworkSettings ConsumerSettings { get; } + /// + /// Content type (XML or JSON) of the message payload. + /// protected ContentType ContentType => ConsumerSettings.ContentType; /// diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs index 5b94f7ae..c4ae3cfc 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs @@ -22,6 +22,7 @@ using Sif.Framework.Model.Parameters; using Sif.Framework.Model.Requests; using Sif.Framework.Model.Responses; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Registration; using Sif.Framework.Service.Serialisation; using Sif.Framework.Utils; @@ -41,38 +42,38 @@ namespace Sif.Framework.Consumers /// Type that defines a single object entity. /// Type that defines a multiple objects entity. /// Primary key type of the SIF data model object. - public abstract class EventConsumer : IEventConsumer where TSingle : ISifRefId + public abstract class EventConsumer + : IEventConsumer where TSingle : ISifRefId { - private static readonly slf4net.ILogger log = slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private readonly slf4net.ILogger log = + slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private CancellationTokenSource cancellationTokenSource; - private Model.Infrastructure.Environment environment; + private Model.Infrastructure.Environment _environment; private Task task; - protected Accept Accept - { - get - { - return SettingsManager.ConsumerSettings.Accept; - } - } + /// + /// Accepted content type (XML or JSON) for a message payload. + /// + protected Accept Accept => ConsumerSettings.Accept; - protected ContentType ContentType - { - get - { - return SettingsManager.ConsumerSettings.ContentType; - } - } + /// + /// Application settings associated with the Consumer. + /// + protected IFrameworkSettings ConsumerSettings { get; } + + /// + /// Content type (XML or JSON) of the message payload. + /// + protected ContentType ContentType => ConsumerSettings.ContentType; /// /// Consumer environment. /// protected Model.Infrastructure.Environment Environment { - get { return environment; } - - private set { environment = value; } + get => _environment; + private set => _environment = value; } /// @@ -83,7 +84,7 @@ protected Model.Infrastructure.Environment Environment /// /// Service for Consumer registration. /// - protected IRegistrationService RegistrationService { get; private set; } + protected IRegistrationService RegistrationService { get; } /// /// Subscription associated with Consumer SIF Events. @@ -93,22 +94,19 @@ protected Model.Infrastructure.Environment Environment /// /// Name of the SIF data model that the Consumer is based on, e.g. SchoolInfo, StudentPersonal, etc. /// - protected virtual string TypeName - { - get - { - return typeof(TSingle).Name; - } - } + protected virtual string TypeName => typeof(TSingle).Name; /// /// Create a Consumer instance based upon the Environment passed. /// /// Environment object. - protected EventConsumer(Model.Infrastructure.Environment environment) + /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. + protected EventConsumer(Model.Infrastructure.Environment environment, IFrameworkSettings settings = null) { - Environment = EnvironmentUtils.MergeWithSettings(environment, SettingsManager.ConsumerSettings); - RegistrationService = new RegistrationService(SettingsManager.ConsumerSettings, SessionsManager.ConsumerSessionService); + ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; + + Environment = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); + RegistrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// @@ -118,11 +116,19 @@ protected EventConsumer(Model.Infrastructure.Environment environment) /// Instance ID. /// User token. /// Solution ID. - protected EventConsumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null) + /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. + protected EventConsumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) { - Model.Infrastructure.Environment environment = new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId); - Environment = EnvironmentUtils.MergeWithSettings(environment, SettingsManager.ConsumerSettings); - RegistrationService = new RegistrationService(SettingsManager.ConsumerSettings, SessionsManager.ConsumerSessionService); + ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; + + var environment = new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId); + Environment = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); + RegistrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// @@ -132,7 +138,8 @@ protected EventConsumer(string applicationKey, string instanceId = null, string /// Instance of the created Queue. private queueType CreateQueue(queueType queue) { - string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}"; + var url = + $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}"; string requestBody = SerialiseQueue(queue); string responseBody = HttpUtils.PostRequest( url, @@ -140,6 +147,7 @@ private queueType CreateQueue(queueType queue) requestBody, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug($"Response from POST {url} request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); @@ -153,7 +161,8 @@ private queueType CreateQueue(queueType queue) /// Instance of the created Subscription. private subscriptionType CreateSubscription(subscriptionType subscription) { - string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.subscriptions)}"; + var url = + $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.subscriptions)}"; string requestBody = SerialiseSubscription(subscription); string responseBody = HttpUtils.PostRequest( url, @@ -161,6 +170,7 @@ private subscriptionType CreateSubscription(subscriptionType subscription) requestBody, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); + if (log.IsDebugEnabled) log.Debug($"Response from POST {url} request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); @@ -179,12 +189,14 @@ protected virtual TMultiple DeserialiseMultiple(string payload) try { - XmlRootAttribute xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, IsNullable = false }; + var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") + { Namespace = ConsumerSettings.DataModelNamespace, IsNullable = false }; obj = SerialiserFactory.GetSerialiser(Accept, xmlRootAttribute).Deserialise(payload); } catch (Exception e) { - throw new SerializationException($"Error deserialising the following payload of multiple objects:\n{payload}", e); + throw new SerializationException( + $"Error deserialising the following payload of multiple objects:\n{payload}", e); } return obj; @@ -241,7 +253,11 @@ private subscriptionType DeserialiseSubscription(string content) /// True if the objects associated with the update event only contained updated fields; false if the objects contain all fields (regardless of if they were changed). /// Zone associated with the update event. /// Zone context. - public abstract void OnUpdateEvent(TMultiple obj, bool partialUpdate, string zoneId = null, string contextId = null); + public abstract void OnUpdateEvent( + TMultiple obj, + bool partialUpdate, + string zoneId = null, + string contextId = null); /// /// Periodically process SIF Events. @@ -256,9 +272,10 @@ private void ProcessEvents(CancellationToken cancellationToken) break; } - bool getEvents = true; - TimeSpan waitTime = TimeSpan.FromSeconds(SettingsManager.ConsumerSettings.EventProcessingWaitTime); - string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}/{Queue.id}/messages"; + var getEvents = true; + TimeSpan waitTime = TimeSpan.FromSeconds(ConsumerSettings.EventProcessingWaitTime); + var url = + $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}/{Queue.id}/messages"; string deleteMessageId = null; // Read from the message queue until no more messages are found. @@ -266,8 +283,13 @@ private void ProcessEvents(CancellationToken cancellationToken) { try { - string deleteMessageIdMatrixParameter = (deleteMessageId == null ? "" : $";deleteMessageId={deleteMessageId.Trim()}"); - if (log.IsDebugEnabled) log.Debug($"Making a request for an event message from {url}{deleteMessageIdMatrixParameter}."); + string deleteMessageIdMatrixParameter = + (deleteMessageId == null ? "" : $";deleteMessageId={deleteMessageId.Trim()}"); + + if (log.IsDebugEnabled) + log.Debug( + $"Making a request for an event message from {url}{deleteMessageIdMatrixParameter}."); + string responseBody = HttpUtils.GetRequestAndHeaders( $"{url}{deleteMessageIdMatrixParameter}", RegistrationService.AuthorisationToken, @@ -282,7 +304,8 @@ private void ProcessEvents(CancellationToken cancellationToken) if (!string.IsNullOrWhiteSpace(minWaitTimeValue)) { - if (double.TryParse(minWaitTimeValue, out double minWaitTime) && (TimeSpan.FromSeconds(minWaitTime) > waitTime)) + if (double.TryParse(minWaitTimeValue, out double minWaitTime) && + (TimeSpan.FromSeconds(minWaitTime) > waitTime)) { waitTime = TimeSpan.FromSeconds(minWaitTime); } @@ -298,60 +321,93 @@ private void ProcessEvents(CancellationToken cancellationToken) if (EventAction.CREATE.ToDescription().Equals(eventAction)) { - if (log.IsDebugEnabled) log.Debug($"Received create event message."); + if (log.IsDebugEnabled) log.Debug("Received create event message."); + OnCreateEvent(obj, zoneId, contextId); } else if (EventAction.DELETE.ToDescription().Equals(eventAction)) { - if (log.IsDebugEnabled) log.Debug($"Received delete event message."); + if (log.IsDebugEnabled) log.Debug("Received delete event message."); + OnDeleteEvent(obj, zoneId, contextId); } else if ("UPDATE".Equals(eventAction)) { - string replacement = responseHeaders?[EventParameterType.Replacement.ToDescription()]; + string replacement = + responseHeaders?[EventParameterType.Replacement.ToDescription()]; if ("FULL".Equals(replacement)) { - if (log.IsDebugEnabled) log.Debug($"Received update (full) event message."); + if (log.IsDebugEnabled) log.Debug("Received update (full) event message."); + OnUpdateEvent(obj, false, zoneId, contextId); } else if ("PARTIAL".Equals(replacement)) { - if (log.IsDebugEnabled) log.Debug($"Received update (partial) event message."); + if (log.IsDebugEnabled) log.Debug("Received update (partial) event message."); + OnUpdateEvent(obj, true, zoneId, contextId); } else { - if (log.IsDebugEnabled) log.Debug($"Received update (partial) event message."); + if (log.IsDebugEnabled) log.Debug("Received update (partial) event message."); + OnUpdateEvent(obj, true, zoneId, contextId); } } else { - BaseException eventException = new EventException($"Event action {eventAction} not recognised for message received from {url}."); + BaseException eventException = new EventException( + $"Event action {eventAction} not recognised for message received from {url}."); + if (log.IsWarnEnabled) log.Warn(eventException.Message); - ResponseError error = new ResponseError { Id = eventException.ExceptionReference, Code = 500, Message = eventException.Message, Description = responseBody, Scope = TypeName }; + + var error = new ResponseError + { + Id = eventException.ExceptionReference, + Code = 500, + Message = eventException.Message, + Description = responseBody, + Scope = TypeName + }; + OnErrorEvent(error); } } catch (SerializationException e) { - BaseException eventException = new EventException($"Event message received from {url} could not be processed due to the following error:\n{e.GetBaseException().Message}.", e); + BaseException eventException = new EventException( + $"Event message received from {url} could not be processed due to the following error:\n{e.GetBaseException().Message}.", + e); + if (log.IsWarnEnabled) log.Warn(e.Message); - ResponseError error = new ResponseError { Id = eventException.ExceptionReference, Code = 500, Message = e.Message, Description = responseBody, Scope = TypeName }; + + var error = new ResponseError + { + Id = eventException.ExceptionReference, + Code = 500, + Message = e.Message, + Description = responseBody, + Scope = TypeName + }; + OnErrorEvent(error); } } else { - if (log.IsDebugEnabled) log.Debug($"No event messages."); + if (log.IsDebugEnabled) log.Debug("No event messages."); + getEvents = false; } } catch (Exception e) { - string errorMessage = $"Error processing event messages due to the following error:\n{e.GetBaseException().Message}."; + var errorMessage = + $"Error processing event messages due to the following error:\n{e.GetBaseException().Message}."; + if (log.IsErrorEnabled) log.Error($"{errorMessage}\n{e.StackTrace}"); + getEvents = false; } } while (getEvents); @@ -370,35 +426,18 @@ private void ProcessEvents(CancellationToken cancellationToken) /// Instance of the Queue if id is valid and queue is found, null otherwise. private queueType RetrieveQueue(string queueId) { - string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}/{queueId}"; + var url = + $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}/{queueId}"; string responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); - if (log.IsDebugEnabled) log.Debug($"Response from GET {url} request ..."); - if (log.IsDebugEnabled) log.Debug(responseBody); - return DeserialiseQueue(responseBody); - } - - /// - /// Retrieves a Queue that will be used by the Consumer using the subscription id. - /// - /// The subscription's identifier. - /// Instance of the Subscription if id is valid and subscription is found, null otherwise. - private subscriptionType RetrieveSubscription(string subscriptionId) - { - string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.subscriptions)}/{subscriptionId}"; - string responseBody = HttpUtils.GetRequest( - url, - RegistrationService.AuthorisationToken, - contentTypeOverride: ContentType.ToDescription(), - acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) log.Debug($"Response from GET {url} request ..."); if (log.IsDebugEnabled) log.Debug(responseBody); - return DeserialiseSubscription(responseBody); + return DeserialiseQueue(responseBody); } /// @@ -431,7 +470,7 @@ public void Start(string zoneId = null, string contextId = null) try { // Register the Event Consumer with the SIF Broker. - RegistrationService.Register(ref environment); + RegistrationService.Register(ref _environment); // Retrieve the Subscription identifier (if exist). string subscriptionId = SessionsManager.ConsumerSessionService.RetrieveSubscriptionId( @@ -443,17 +482,17 @@ public void Start(string zoneId = null, string contextId = null) // If the Subscription identifier does NOT exist, create a Subscription and associated Queue. if (string.IsNullOrWhiteSpace(subscriptionId)) { - string queueNameSuffix = DateTime.UtcNow.ToString("yyMMddHHmmssfff"); + var queueNameSuffix = DateTime.UtcNow.ToString("yyMMddHHmmssfff"); // For the SIF Broker, the name property is a mandatory. - queueType queue = new queueType + var queue = new queueType { name = $"{TypeName}-{queueNameSuffix}" }; Queue = CreateQueue(queue); - subscriptionType subscription = new subscriptionType() + var subscription = new subscriptionType() { contextId = contextId, queueId = Queue.id, @@ -494,9 +533,12 @@ public void Start(string zoneId = null, string contextId = null) } catch (Exception e) { - string errorMessage = $"Could not retrieve Queue details due to the following error:\n{e.GetBaseException().Message}."; + var errorMessage = + $"Could not retrieve Queue details due to the following error:\n{e.GetBaseException().Message}."; + if (log.IsErrorEnabled) log.Error($"{errorMessage}\n{e.StackTrace}"); - throw e; + + throw; } } @@ -511,15 +553,21 @@ public void Start(string zoneId = null, string contextId = null) } catch (RegistrationException e) { - string errorMessage = $"Error registering the Event Consumer:\n{e.GetBaseException().Message}.\n{e.StackTrace}"; + var errorMessage = + $"Error registering the Event Consumer:\n{e.GetBaseException().Message}.\n{e.StackTrace}"; + if (log.IsErrorEnabled) log.Error(e, errorMessage); - throw e; + + throw; } catch (Exception e) { - string errorMessage = $"Error starting the Event Consumer:\n{e.GetBaseException().Message}.\n{e.StackTrace}"; + var errorMessage = + $"Error starting the Event Consumer:\n{e.GetBaseException().Message}.\n{e.StackTrace}"; + if (log.IsErrorEnabled) log.Error(e, errorMessage); - throw e; + + throw; } } @@ -536,11 +584,15 @@ public void Stop(bool? deleteOnStop = null) } catch (AggregateException e) { - if (log.IsErrorEnabled) log.Error(e, $"Error occurred stopping the Event Consumer for {TypeName} - {e.GetBaseException().Message}."); + if (log.IsErrorEnabled) + log.Error(e, + $"Error occurred stopping the Event Consumer for {TypeName} - {e.GetBaseException().Message}."); } catch (Exception e) { - if (log.IsErrorEnabled) log.Error(e, $"Error occurred stopping the Event Consumer for {TypeName} - {e.GetBaseException().Message}."); + if (log.IsErrorEnabled) + log.Error(e, + $"Error occurred stopping the Event Consumer for {TypeName} - {e.GetBaseException().Message}."); } finally { diff --git a/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs index f5d5bec6..66a0160b 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/BasicProvider.cs @@ -17,6 +17,7 @@ using Sif.Framework.Model.DataModels; using Sif.Framework.Model.Exceptions; using Sif.Framework.Model.Infrastructure; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Providers; using Sif.Framework.Service.Serialisation; using Sif.Framework.Utils; @@ -42,7 +43,9 @@ public abstract class BasicProvider : Provider> where T : ISifRefI /// Create an instance based on the specified service. /// /// Service used for managing the object type. - protected BasicProvider(IBasicProviderService service) : base(service) + /// Provider settings. If null, Provider settings will be read from the SifFramework.config file. + protected BasicProvider(IBasicProviderService service, IFrameworkSettings settings = null) + : base(service, settings) { } @@ -94,12 +97,12 @@ public override IHttpActionResult Post( HttpStatusCode.BadRequest, TypeName, "Create request failed as object ID is not provided, but mustUseAdvisory is true."); - status.statusCode = ((int) HttpStatusCode.BadRequest).ToString(); + status.statusCode = ((int)HttpStatusCode.BadRequest).ToString(); } else { status.id = Service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0]).RefId; - status.statusCode = ((int) HttpStatusCode.Created).ToString(); + status.statusCode = ((int)HttpStatusCode.Created).ToString(); } } else @@ -256,7 +259,7 @@ public override string SerialiseEvents(List obj) { var xmlRootAttribute = new XmlRootAttribute(TypeName + "s") { - Namespace = SettingsManager.ConsumerSettings.DataModelNamespace, + Namespace = ProviderSettings.DataModelNamespace, IsNullable = false }; diff --git a/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs index b9427329..5ddac0ec 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/ObjectProvider.cs @@ -18,6 +18,7 @@ using Sif.Framework.Model.Infrastructure; using Sif.Framework.Model.Parameters; using Sif.Framework.Model.Responses; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Mapper; using Sif.Framework.Service.Providers; using Sif.Framework.Service.Serialisation; @@ -38,7 +39,9 @@ public abstract class ObjectProvider /// Create an instance based on the specified service. /// /// Service used for managing the object type. - protected ObjectProvider(IObjectProviderService service) : base(service) + /// Provider settings. If null, Provider settings will be read from the SifFramework.config file. + protected ObjectProvider(IObjectProviderService service, IFrameworkSettings settings = null) + : base(service, settings) { this.service = service; } diff --git a/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs b/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs index 716358bc..741e586a 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs @@ -23,6 +23,7 @@ using Sif.Framework.Model.Parameters; using Sif.Framework.Model.Query; using Sif.Framework.Model.Requests; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Authentication; using Sif.Framework.Service.Authorisation; using Sif.Framework.Service.Infrastructure; @@ -53,7 +54,7 @@ public abstract class Provider /// /// Accepted content type (XML or JSON) for a message payload. /// - protected Accept Accept => SettingsManager.ProviderSettings.Accept; + protected Accept Accept => ProviderSettings.Accept; /// /// Service used for request authentication. @@ -68,7 +69,12 @@ public abstract class Provider /// /// Content type (XML or JSON) of the message payload. /// - protected ContentType ContentType => SettingsManager.ProviderSettings.ContentType; + protected ContentType ContentType => ProviderSettings.ContentType; + + /// + /// Application settings associated with the Provider. + /// + protected IFrameworkSettings ProviderSettings { get; } /// /// Object service associated with this Provider. @@ -80,40 +86,22 @@ public abstract class Provider /// protected virtual string TypeName => typeof(TSingle).Name; - /// - /// Default constructor that is only available to derived instances of - /// this class. - /// - protected Provider() - { - if (EnvironmentType.DIRECT.Equals(SettingsManager.ProviderSettings.EnvironmentType)) - { - AuthenticationService = - new DirectAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); - } - else if (EnvironmentType.BROKERED.Equals(SettingsManager.ProviderSettings.EnvironmentType)) - { - AuthenticationService = - new BrokeredAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); - } - - AuthorisationService = new AuthorisationService(AuthenticationService); - } - /// /// Create an instance based on the specified service. /// /// Service used for managing the object type. - protected Provider(IProviderService service) + /// Provider settings. If null, Provider settings will be read from the SifFramework.config file. + protected Provider(IProviderService service, IFrameworkSettings settings = null) { Service = service; + ProviderSettings = settings ?? SettingsManager.ConsumerSettings; - if (EnvironmentType.DIRECT.Equals(SettingsManager.ProviderSettings.EnvironmentType)) + if (EnvironmentType.DIRECT.Equals(ProviderSettings.EnvironmentType)) { AuthenticationService = new DirectAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); } - else if (EnvironmentType.BROKERED.Equals(SettingsManager.ProviderSettings.EnvironmentType)) + else if (EnvironmentType.BROKERED.Equals(ProviderSettings.EnvironmentType)) { AuthenticationService = new BrokeredAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); @@ -501,7 +489,8 @@ public virtual IHttpActionResult Get( /// /// Get /// - public virtual IHttpActionResult Get(string object1, + public virtual IHttpActionResult Get( + string object1, [FromUri(Name = "id1")] string refId1, string object2 = null, [FromUri(Name = "id2")] string refId2 = null, diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs index cc335b57..2c71d82d 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,8 @@ private void RunStudentPersonalConsumer() SettingsManager.ConsumerSettings.ApplicationKey, SettingsManager.ConsumerSettings.InstanceId, SettingsManager.ConsumerSettings.UserToken, - SettingsManager.ConsumerSettings.SolutionId); + SettingsManager.ConsumerSettings.SolutionId, + SettingsManager.ConsumerSettings); studentPersonalConsumer.Register(); if (log.IsInfoEnabled) log.Info("Registered the Consumer."); diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalConsumer.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalConsumer.cs index 26e20072..854e41d6 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalConsumer.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalConsumer.cs @@ -1,12 +1,12 @@ /* - * Copyright 2017 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,23 +16,27 @@ using Sif.Framework.Consumers; using Sif.Framework.Demo.Au.Consumer.Models; +using Sif.Framework.Model.Settings; namespace Sif.Framework.Demo.Au.Consumer.Consumers { - - class StudentPersonalConsumer : BasicConsumer + internal class StudentPersonalConsumer : BasicConsumer { - - public StudentPersonalConsumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null) - : base(applicationKey, instanceId, userToken, solutionId) + public StudentPersonalConsumer( + Model.Infrastructure.Environment environment, + IFrameworkSettings settings = null) + : base(environment, settings) { } - public StudentPersonalConsumer(Model.Infrastructure.Environment environment) - : base(environment) + public StudentPersonalConsumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) + : base(applicationKey, instanceId, userToken, solutionId, settings) { } - } - -} +} \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalEventConsumer.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalEventConsumer.cs index 191cf87f..456a8a25 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalEventConsumer.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentPersonalEventConsumer.cs @@ -1,12 +1,12 @@ /* - * Copyright 2017 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,76 +17,84 @@ using Sif.Framework.Consumers; using Sif.Framework.Demo.Au.Consumer.Models; using Sif.Framework.Model.Responses; +using Sif.Framework.Model.Settings; using System.Collections.Generic; namespace Sif.Framework.Demo.Au.Consumer.Consumers { - - class StudentPersonalEventConsumer : BasicEventConsumer + internal class StudentPersonalEventConsumer : BasicEventConsumer { - private static readonly slf4net.ILogger log = slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private readonly slf4net.ILogger log = + slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - public StudentPersonalEventConsumer(Model.Infrastructure.Environment environment) - : base(environment) + public StudentPersonalEventConsumer( + Model.Infrastructure.Environment environment, + IFrameworkSettings settings = null) + : base(environment, settings) { } - public StudentPersonalEventConsumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null) - : base(applicationKey, instanceId, userToken, solutionId) + public StudentPersonalEventConsumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) + : base(applicationKey, instanceId, userToken, solutionId, settings) { } public override void OnCreateEvent(List objs, string zoneId = null, string contextId = null) { - if (log.IsDebugEnabled) log.Debug($"*** OnCreateEvent handler called ..."); + if (log.IsDebugEnabled) log.Debug("*** OnCreateEvent handler called ..."); if (log.IsDebugEnabled) log.Debug($"*** >>> Zone ID is {zoneId}."); if (log.IsDebugEnabled) log.Debug($"*** >>> Context ID is {contextId}."); foreach (StudentPersonal student in objs) { - if (log.IsDebugEnabled) log.Debug($"*** >>> Student created is {student.PersonInfo.Name.GivenName} {student.PersonInfo.Name.FamilyName}."); + if (log.IsDebugEnabled) + log.Debug( + $"*** >>> Student created is {student.PersonInfo.Name.GivenName} {student.PersonInfo.Name.FamilyName}."); } - } public override void OnDeleteEvent(List objs, string zoneId = null, string contextId = null) { - if (log.IsDebugEnabled) log.Debug($"*** OnDeleteEvent handler called ..."); + if (log.IsDebugEnabled) log.Debug("*** OnDeleteEvent handler called ..."); if (log.IsDebugEnabled) log.Debug($"*** >>> Zone ID is {zoneId}."); if (log.IsDebugEnabled) log.Debug($"*** >>> Context ID is {contextId}."); foreach (StudentPersonal student in objs) { - if (log.IsDebugEnabled) log.Debug($"*** >>> Student deleted is {student.PersonInfo.Name.GivenName} {student.PersonInfo.Name.FamilyName}."); + if (log.IsDebugEnabled) + log.Debug( + $"*** >>> Student deleted is {student.PersonInfo.Name.GivenName} {student.PersonInfo.Name.FamilyName}."); } - } public override void OnErrorEvent(ResponseError error, string zoneId = null, string contextId = null) { - if (log.IsDebugEnabled) log.Debug($"*** OnErrorEvent handler called ..."); + if (log.IsDebugEnabled) log.Debug("*** OnErrorEvent handler called ..."); if (log.IsDebugEnabled) log.Debug($"*** >>> Zone ID is {zoneId}."); if (log.IsDebugEnabled) log.Debug($"*** >>> Context ID is {contextId}."); - if (log.IsDebugEnabled) log.Debug($"*** >>> Error: {error.Message}."); - } - public override void OnUpdateEvent(List objs, bool partialUpdate, string zoneId = null, string contextId = null) + public override void OnUpdateEvent(List objs, bool partialUpdate, string zoneId = null, + string contextId = null) { - if (log.IsDebugEnabled) log.Debug($"*** OnUpdateEvent handler called ..."); + if (log.IsDebugEnabled) log.Debug("*** OnUpdateEvent handler called ..."); if (log.IsDebugEnabled) log.Debug($"*** >>> Partial update is {partialUpdate}."); if (log.IsDebugEnabled) log.Debug($"*** >>> Zone ID is {zoneId}."); if (log.IsDebugEnabled) log.Debug($"*** >>> Context ID is {contextId}."); foreach (StudentPersonal student in objs) { - if (log.IsDebugEnabled) log.Debug($"*** >>> Student updated is {student.PersonInfo.Name.GivenName} {student.PersonInfo.Name.FamilyName}."); + if (log.IsDebugEnabled) + log.Debug( + $"*** >>> Student updated is {student.PersonInfo.Name.GivenName} {student.PersonInfo.Name.FamilyName}."); } - } - } - -} +} \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentSchoolEnrollmentConsumer.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentSchoolEnrollmentConsumer.cs index 259805ba..0d428852 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentSchoolEnrollmentConsumer.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Consumers/StudentSchoolEnrollmentConsumer.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,26 @@ using Sif.Framework.Consumers; using Sif.Framework.Demo.Au.Consumer.Models; +using Sif.Framework.Model.Settings; namespace Sif.Framework.Demo.Au.Consumer.Consumers { internal class StudentSchoolEnrollmentConsumer : BasicConsumer { - public StudentSchoolEnrollmentConsumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null) - : base(applicationKey, instanceId, userToken, solutionId) + public StudentSchoolEnrollmentConsumer( + Model.Infrastructure.Environment environment, + IFrameworkSettings settings = null) + : base(environment, settings) { } - public StudentSchoolEnrollmentConsumer(Model.Infrastructure.Environment environment) - : base(environment) + public StudentSchoolEnrollmentConsumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) + : base(applicationKey, instanceId, userToken, solutionId, settings) { } } diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EnrollmentConsumerApp.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EnrollmentConsumerApp.cs index cbf98047..8bc1ca92 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EnrollmentConsumerApp.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EnrollmentConsumerApp.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,8 @@ private void RunConsumer() SettingsManager.ConsumerSettings.ApplicationKey, SettingsManager.ConsumerSettings.InstanceId, SettingsManager.ConsumerSettings.UserToken, - SettingsManager.ConsumerSettings.SolutionId); + SettingsManager.ConsumerSettings.SolutionId, + SettingsManager.ConsumerSettings); consumer.Register(); if (log.IsInfoEnabled) log.Info("Registered the Consumer."); diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EventConsumerApp.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EventConsumerApp.cs index c33bd493..e481566a 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EventConsumerApp.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/EventConsumerApp.cs @@ -65,7 +65,8 @@ private static void Main(string[] args) SettingsManager.ConsumerSettings.ApplicationKey, SettingsManager.ConsumerSettings.InstanceId, SettingsManager.ConsumerSettings.UserToken, - SettingsManager.ConsumerSettings.SolutionId); + SettingsManager.ConsumerSettings.SolutionId, + SettingsManager.ConsumerSettings); studentPersonalConsumer.Start("Sif3DemoZone1", "DEFAULT"); if (log.IsInfoEnabled) log.Info("Started the Event Consumer."); diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs index c8ff5454..7e8a999f 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs @@ -1,12 +1,12 @@ /* - * Copyright 2017 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,16 +17,14 @@ using Sif.Framework.Demo.Au.Provider.Models; using Sif.Framework.Demo.Au.Provider.Services; using Sif.Framework.Providers; +using Sif.Framework.Utils; using System.Web.Http; namespace Sif.Framework.Demo.Au.Provider.Controllers { - public class SchoolInfosProvider : BasicProvider { - - public SchoolInfosProvider() - : base(new SchoolInfoService()) + public SchoolInfosProvider() : base(new SchoolInfoService(), SettingsManager.ProviderSettings) { } @@ -35,7 +33,5 @@ public override IHttpActionResult BroadcastEvents(string zoneId = null, string c { return base.BroadcastEvents(zoneId, contextId); } - } - } \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs index 467d79fb..b4140dcb 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs @@ -1,12 +1,12 @@ /* - * Copyright 2017 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,22 +17,21 @@ using Sif.Framework.Demo.Au.Provider.Models; using Sif.Framework.Demo.Au.Provider.Services; using Sif.Framework.Providers; +using Sif.Framework.Utils; using Sif.Framework.WebApi.ModelBinders; using System.Web.Http; namespace Sif.Framework.Demo.Au.Provider.Controllers { - public class StudentPersonalsProvider : BasicProvider { - - public StudentPersonalsProvider() - : base(new StudentPersonalService()) + public StudentPersonalsProvider() : base(new StudentPersonalService(), SettingsManager.ProviderSettings) { } [Route("~/api/StudentPersonals/StudentPersonal")] - public override IHttpActionResult Post(StudentPersonal obj, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post(StudentPersonal obj, [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return base.Post(obj, zoneId, contextId); } @@ -42,7 +41,5 @@ public override IHttpActionResult BroadcastEvents(string zoneId = null, string c { return base.BroadcastEvents(zoneId, contextId); } - } - } \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs index 6ac33280..c8f5036e 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,15 @@ using Sif.Framework.Demo.Au.Provider.Models; using Sif.Framework.Demo.Au.Provider.Services; using Sif.Framework.Providers; +using Sif.Framework.Utils; using System.Web.Http; namespace Sif.Framework.Demo.Au.Provider.Controllers { public class StudentSchoolEnrollmentsProvider : BasicProvider { - public StudentSchoolEnrollmentsProvider() : base(new StudentSchoolEnrollmentService()) + public StudentSchoolEnrollmentsProvider() + : base(new StudentSchoolEnrollmentService(), SettingsManager.ProviderSettings) { } diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/EventsProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/EventsProvider.cs index a2f426f8..ba9e7aa2 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/EventsProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/EventsProvider.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,39 +31,43 @@ namespace Sif.Framework.Demo.Broker.Controllers { public class EventsProvider : BasicProvider { - private static readonly slf4net.ILogger log = slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private readonly slf4net.ILogger log = + slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - public EventsProvider() : base(new StudentPersonalService()) + public EventsProvider() : base(new StudentPersonalService(), SettingsManager.ProviderSettings) { } [Route("~/api/Events/Event")] - public override IHttpActionResult Post(StudentPersonal obj, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post( + StudentPersonal obj, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return base.Post(obj, zoneId, contextId); } - public override IHttpActionResult Post(List objs, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post( + List objs, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { foreach (KeyValuePair> nameValues in Request.Headers) { - if (log.IsDebugEnabled) log.Debug($"*** Header field is [{nameValues.Key}:{string.Join(",", nameValues.Value)}]"); + if (log.IsDebugEnabled) + log.Debug($"*** Header field is [{nameValues.Key}:{string.Join(",", nameValues.Value)}]"); } - //return base.Post(objs, zoneId, contextId); - string sessionToken; - - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string _)) { return Unauthorized(); } if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) { - return BadRequest("Request failed for object " + typeof(StudentPersonal).Name + " as Zone and/or Context are invalid."); + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } - IHttpActionResult result; ICollection createStatuses = new List(); try @@ -73,53 +77,73 @@ public override IHttpActionResult Post(List objs, [MatrixParame foreach (StudentPersonal obj in objs) { bool hasAdvisoryId = !string.IsNullOrWhiteSpace(obj.RefId); - createType status = new createType(); - status.advisoryId = (hasAdvisoryId ? obj.RefId : null); + var status = new createType { advisoryId = (hasAdvisoryId ? obj.RefId : null) }; try { - if (mustUseAdvisory.HasValue && mustUseAdvisory.Value == true) + if (mustUseAdvisory.HasValue) { - if (hasAdvisoryId) + if (mustUseAdvisory.Value && !hasAdvisoryId) { - status.id = service.Create(obj, mustUseAdvisory, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])).RefId; - status.statusCode = ((int)HttpStatusCode.Created).ToString(); + status.error = ProviderUtils.CreateError( + HttpStatusCode.BadRequest, + TypeName, + "Create request failed as object ID is not provided, but mustUseAdvisory is true."); + status.statusCode = ((int)HttpStatusCode.BadRequest).ToString(); } else { - status.error = ProviderUtils.CreateError(HttpStatusCode.BadRequest, typeof(StudentPersonal).Name, "Create request failed as object ID is not provided, but mustUseAdvisory is true."); - status.statusCode = ((int)HttpStatusCode.BadRequest).ToString(); + status.id = Service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0]).RefId; + status.statusCode = ((int)HttpStatusCode.Created).ToString(); } } else { - status.id = service.Create(obj, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])).RefId; + status.id = Service.Create(obj, null, zoneId?[0], contextId?[0]).RefId; status.statusCode = ((int)HttpStatusCode.Created).ToString(); } } catch (AlreadyExistsException e) { - status.error = ProviderUtils.CreateError(HttpStatusCode.Conflict, typeof(StudentPersonal).Name, "Object " + typeof(StudentPersonal).Name + " with ID of " + obj.RefId + " already exists.\n" + e.Message); + status.error = ProviderUtils.CreateError( + HttpStatusCode.Conflict, + TypeName, + $"Object {TypeName} with ID of {obj.RefId} already exists.\n{e.Message}"); status.statusCode = ((int)HttpStatusCode.Conflict).ToString(); } catch (ArgumentException e) { - status.error = ProviderUtils.CreateError(HttpStatusCode.BadRequest, typeof(StudentPersonal).Name, "Object to create of type " + typeof(StudentPersonal).Name + (hasAdvisoryId ? " with ID of " + obj.RefId : "") + " is invalid.\n " + e.Message); + status.error = ProviderUtils.CreateError( + HttpStatusCode.BadRequest, + TypeName, + $"Object to create of type {TypeName}" + + (hasAdvisoryId ? $" with ID of {obj.RefId}" : "") + $" is invalid.\n{e.Message}"); status.statusCode = ((int)HttpStatusCode.BadRequest).ToString(); } catch (CreateException e) { - status.error = ProviderUtils.CreateError(HttpStatusCode.BadRequest, typeof(StudentPersonal).Name, "Request failed for object " + typeof(StudentPersonal).Name + (hasAdvisoryId ? " with ID of " + obj.RefId : "") + ".\n " + e.Message); + status.error = ProviderUtils.CreateError( + HttpStatusCode.BadRequest, + TypeName, + $"Request failed for object {TypeName}" + + (hasAdvisoryId ? $" with ID of {obj.RefId}" : "") + $".\n{e.Message}"); status.statusCode = ((int)HttpStatusCode.BadRequest).ToString(); } catch (RejectedException e) { - status.error = ProviderUtils.CreateError(HttpStatusCode.NotFound, typeof(StudentPersonal).Name, "Create request rejected for object " + typeof(StudentPersonal).Name + " with ID of " + obj.RefId + ".\n" + e.Message); + status.error = ProviderUtils.CreateError( + HttpStatusCode.NotFound, + TypeName, + $"Create request rejected for object {TypeName} with ID of {obj.RefId}.\n{e.Message}"); status.statusCode = ((int)HttpStatusCode.Conflict).ToString(); } catch (Exception e) { - status.error = ProviderUtils.CreateError(HttpStatusCode.InternalServerError, typeof(StudentPersonal).Name, "Request failed for object " + typeof(StudentPersonal).Name + (hasAdvisoryId ? " with ID of " + obj.RefId : "") + ".\n " + e.Message); + status.error = ProviderUtils.CreateError( + HttpStatusCode.InternalServerError, + TypeName, + $"Request failed for object {TypeName}" + + (hasAdvisoryId ? $" with ID of {obj.RefId}" : "") + $".\n{e.Message}"); status.statusCode = ((int)HttpStatusCode.InternalServerError).ToString(); } @@ -131,10 +155,9 @@ public override IHttpActionResult Post(List objs, [MatrixParame // Need to ignore exceptions otherwise it would not be possible to return status records of processed objects. } - createResponseType createResponse = new createResponseType { creates = createStatuses.ToArray() }; - result = Ok(createResponse); + var createResponse = new createResponseType { creates = createStatuses.ToArray() }; - return result; + return Ok(createResponse); } } } \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/QueuesProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/QueuesProvider.cs index c149b0a4..a38f47a6 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/QueuesProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/QueuesProvider.cs @@ -1,12 +1,12 @@ /* - * Copyright 2018 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,6 @@ using Sif.Framework.Demo.Broker.Utils; using Sif.Framework.Model.Exceptions; using Sif.Framework.Providers; -using Sif.Framework.Service.Providers; using Sif.Framework.Utils; using Sif.Framework.WebApi.ActionResults; using Sif.Framework.WebApi.ModelBinders; @@ -32,19 +31,15 @@ namespace Sif.Framework.Demo.Broker.Controllers { - public class QueuesProvider : BasicProvider { - private static int availableMessageBatches = 5; - private static string[] eventActionType = { "CREATE", "DELETE", "UPDATE" }; - private static Random random = new Random(); - private static string[] replacementType = { "FULL", "PARTIAL" }; + private static readonly string[] EventActionType = { "CREATE", "DELETE", "UPDATE" }; + private static readonly Random Random = new Random(); + private static readonly string[] ReplacementType = { "FULL", "PARTIAL" }; - public QueuesProvider() : this(new QueueService()) - { - } + private static int availableMessageBatches = 5; - protected QueuesProvider(IBasicProviderService service) : base(service) + public QueuesProvider() : base(new QueueService(), SettingsManager.ProviderSettings) { } @@ -57,31 +52,33 @@ public override IHttpActionResult BroadcastEvents(string zoneId = null, string c /// /// Add a custom header to an action result and return it. /// - /// Action result. + /// Action result. /// Name of the header. /// Value associated with the header. /// Action result with a custom header. - private IHttpActionResult CreateCustomActionResult(IHttpActionResult result, string headerName, string headerValue) + private static IHttpActionResult CreateCustomActionResult( + IHttpActionResult result, + string headerName, + string headerValue) { return new CustomHeaderResult(result, headerName, new[] { headerValue }); } private static StudentPersonal CreateStudent() { - - NameOfRecordType name = new NameOfRecordType + var name = new NameOfRecordType { Type = NameOfRecordTypeType.LGL, FamilyName = RandomNameGenerator.FamilyName, GivenName = RandomNameGenerator.GivenName }; - PersonInfoType personInfo = new PersonInfoType { Name = name }; + var personInfo = new PersonInfoType { Name = name }; - StudentPersonal studentPersonal = new StudentPersonal + var studentPersonal = new StudentPersonal { RefId = Guid.NewGuid().ToString(), - LocalId = random.Next(10000, 99999).ToString(), + LocalId = Random.Next(10000, 99999).ToString(), PersonInfo = personInfo }; @@ -90,9 +87,9 @@ private static StudentPersonal CreateStudent() private static List CreateStudents(int count) { - List students = new List(); + var students = new List(); - for (int i = 0; i < count; i++) + for (var i = 0; i < count; i++) { StudentPersonal studentPersonal = CreateStudent(); students.Add(studentPersonal); @@ -101,12 +98,23 @@ private static List CreateStudents(int count) return students; } - public override IHttpActionResult Delete(deleteRequestType deleteRequest, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Delete( + deleteRequestType deleteRequest, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return StatusCode(HttpStatusCode.MethodNotAllowed); } - public override IHttpActionResult Get(string object1, [FromUri(Name = "id1")] string refId1, string object2 = null, [FromUri(Name = "id2")] string refId2 = null, string object3 = null, [FromUri(Name = "id3")] string refId3 = null, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Get( + string object1, + [FromUri(Name = "id1")] string refId1, + string object2 = null, + [FromUri(Name = "id2")] string refId2 = null, + string object3 = null, + [FromUri(Name = "id3")] string refId3 = null, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return StatusCode(HttpStatusCode.MethodNotAllowed); } @@ -114,23 +122,22 @@ public override IHttpActionResult Get(string object1, [FromUri(Name = "id1")] st [Route("~/api/Queues/{queueId}/messages")] public IHttpActionResult Get(string queueId) { - if (availableMessageBatches == 0) { return StatusCode(HttpStatusCode.NoContent); } availableMessageBatches--; - List students = CreateStudents(random.Next(1, 5)); + List students = CreateStudents(Random.Next(1, 5)); IHttpActionResult result = Ok(students); - string eventActionValue = eventActionType[random.Next(eventActionType.Length)]; + string eventActionValue = EventActionType[Random.Next(EventActionType.Length)]; result = CreateCustomActionResult(result, "eventAction", eventActionValue); result = CreateCustomActionResult(result, "messageId", Guid.NewGuid().ToString()); result = CreateCustomActionResult(result, "minWaitTime", "10"); if ("UPDATE".Equals(eventActionValue)) { - string replacementValue = replacementType[random.Next(replacementType.Length)]; + string replacementValue = ReplacementType[Random.Next(ReplacementType.Length)]; result = CreateCustomActionResult(result, "Replacement", replacementValue); } @@ -140,34 +147,34 @@ public IHttpActionResult Get(string queueId) [Route("~/api/Queues/{queueId}/messages;deleteMessageId={deleteMessageId}")] public IHttpActionResult Get(string queueId, string deleteMessageId) { - if (availableMessageBatches == 0) { return StatusCode(HttpStatusCode.NoContent); } availableMessageBatches--; - List students = CreateStudents(random.Next(1, 5)); + List students = CreateStudents(Random.Next(1, 5)); IHttpActionResult result = Ok(students); - string eventActionValue = eventActionType[random.Next(eventActionType.Length)]; + string eventActionValue = EventActionType[Random.Next(EventActionType.Length)]; result = CreateCustomActionResult(result, "eventAction", eventActionValue); result = CreateCustomActionResult(result, "messageId", Guid.NewGuid().ToString()); result = CreateCustomActionResult(result, "minWaitTime", "10"); if ("UPDATE".Equals(eventActionValue)) { - string replacementValue = replacementType[random.Next(replacementType.Length)]; + string replacementValue = ReplacementType[Random.Next(ReplacementType.Length)]; result = CreateCustomActionResult(result, "Replacement", replacementValue); } return result; } - public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Get( + [FromUri(Name = "id")] string refId, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { - string sessionToken; - - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string _)) { return Unauthorized(); } @@ -179,14 +186,14 @@ public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [Matr if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) { - return BadRequest("Request failed for object " + typeof(Queue).Name + " as Zone and/or Context are invalid."); + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } IHttpActionResult result; try { - Queue obj = service.Retrieve(refId, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); + Queue obj = Service.Retrieve(refId, zoneId?[0], contextId?[0]); if (obj == null) { @@ -196,15 +203,14 @@ public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [Matr { result = Ok(obj); } - } catch (ArgumentException e) { - result = BadRequest("Invalid argument: id=" + refId + ".\n" + e.Message); + result = BadRequest($"Invalid argument: id={refId}.\n{e.Message}"); } catch (QueryException e) { - result = BadRequest("Request failed for object " + typeof(Queue).Name + " with ID of " + refId + ".\n " + e.Message); + result = BadRequest($"Request failed for object {TypeName} with ID of {refId}.\n{e.Message}"); } catch (Exception e) { @@ -214,29 +220,35 @@ public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [Matr return result; } - public override IHttpActionResult Head([MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Head( + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return StatusCode(HttpStatusCode.MethodNotAllowed); } [NonAction] - public override IHttpActionResult Post(List objs, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post( + List objs, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return StatusCode(HttpStatusCode.MethodNotAllowed); } - public override IHttpActionResult Post(Queue obj, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post( + Queue obj, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { - string sessionToken; - - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string _)) { return Unauthorized(); } if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) { - return BadRequest("Request failed for object " + typeof(Queue).Name + " as Zone and/or Context are invalid."); + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } IHttpActionResult result; @@ -246,28 +258,27 @@ public override IHttpActionResult Post(Queue obj, [MatrixParameter] string[] zon bool hasAdvisoryId = !string.IsNullOrWhiteSpace(obj.RefId); bool? mustUseAdvisory = HttpUtils.GetMustUseAdvisory(Request.Headers); - if (mustUseAdvisory.HasValue && mustUseAdvisory.Value == true) + if (mustUseAdvisory.HasValue) { - - if (hasAdvisoryId) + if (mustUseAdvisory.Value && !hasAdvisoryId) { - Queue createdObject = service.Create(obj, mustUseAdvisory, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); - result = Created(uri, createdObject); + result = BadRequest( + $"Request failed for object {TypeName} as object ID is not provided, but mustUseAdvisory is true."); } else { - result = BadRequest($"Request failed for object {TypeName} as object ID is not provided, but mustUseAdvisory is true."); + Queue createdObject = Service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0]); + string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); + result = Created(uri, createdObject); } - } else { - Queue createdObject = service.Create(obj, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - string uri = Url.Link("DefaultApi", new { controller = typeof(Queue).Name, id = createdObject.RefId }); + Queue createdObject = Service.Create(obj, null, zoneId?[0], contextId?[0]); + string uri = + Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); result = Created(uri, createdObject); } - } catch (AlreadyExistsException) { @@ -275,11 +286,11 @@ public override IHttpActionResult Post(Queue obj, [MatrixParameter] string[] zon } catch (ArgumentException e) { - result = BadRequest("Object to create of type " + typeof(Queue).Name + " is invalid.\n " + e.Message); + result = BadRequest($"Object to create of type {TypeName} is invalid.\n{e.Message}"); } catch (CreateException e) { - result = BadRequest("Request failed for object " + typeof(Queue).Name + ".\n " + e.Message); + result = BadRequest($"Request failed for object {TypeName}.\n{e.Message}"); } catch (RejectedException) { @@ -287,7 +298,7 @@ public override IHttpActionResult Post(Queue obj, [MatrixParameter] string[] zon } catch (QueryException e) { - result = BadRequest("Request failed for object " + typeof(Queue).Name + ".\n " + e.Message); + result = BadRequest($"Request failed for object {TypeName}.\n{e.Message}"); } catch (Exception e) { @@ -297,16 +308,21 @@ public override IHttpActionResult Post(Queue obj, [MatrixParameter] string[] zon return result; } - public override IHttpActionResult Put(List objs, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Put( + List objs, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return StatusCode(HttpStatusCode.MethodNotAllowed); } - public override IHttpActionResult Put([FromUri(Name = "id")] string refId, Queue obj, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Put( + [FromUri(Name = "id")] string refId, + Queue obj, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return StatusCode(HttpStatusCode.MethodNotAllowed); } - } - } \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/SubscriptionsProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/SubscriptionsProvider.cs index a45e90de..1ebe05c6 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/SubscriptionsProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Controllers/SubscriptionsProvider.cs @@ -1,12 +1,12 @@ /* - * Copyright 2018 Systemic Pty Ltd - * + * Copyright 2020 Systemic Pty Ltd + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,7 +18,6 @@ using Sif.Framework.Demo.Broker.Services; using Sif.Framework.Model.Exceptions; using Sif.Framework.Providers; -using Sif.Framework.Service.Providers; using Sif.Framework.Utils; using Sif.Framework.WebApi.ModelBinders; using System; @@ -28,15 +27,9 @@ namespace Sif.Framework.Demo.Broker.Controllers { - public class SubscriptionsProvider : BasicProvider { - - protected SubscriptionsProvider() : base(new SubscriptionService()) - { - } - - protected SubscriptionsProvider(IBasicProviderService service) : base(service) + public SubscriptionsProvider() : base(new SubscriptionService(), SettingsManager.ProviderSettings) { } @@ -46,11 +39,12 @@ public override IHttpActionResult BroadcastEvents(string zoneId = null, string c return base.BroadcastEvents(zoneId, contextId); } - public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Get( + [FromUri(Name = "id")] string refId, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { - string sessionToken; - - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string _)) { return Unauthorized(); } @@ -62,14 +56,14 @@ public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [Matr if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) { - return BadRequest("Request failed for object " + typeof(Subscription).Name + " as Zone and/or Context are invalid."); + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } IHttpActionResult result; try { - Subscription obj = service.Retrieve(refId, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); + Subscription obj = Service.Retrieve(refId, zoneId?[0], contextId?[0]); if (obj == null) { @@ -79,15 +73,14 @@ public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [Matr { result = Ok(obj); } - } catch (ArgumentException e) { - result = BadRequest("Invalid argument: id=" + refId + ".\n" + e.Message); + result = BadRequest($"Invalid argument: id={refId}.\n{e.Message}"); } catch (QueryException e) { - result = BadRequest("Request failed for object " + typeof(Subscription).Name + " with ID of " + refId + ".\n " + e.Message); + result = BadRequest($"Request failed for object {TypeName} with ID of {refId}.\n{e.Message}"); } catch (Exception e) { @@ -98,23 +91,27 @@ public override IHttpActionResult Get([FromUri(Name = "id")] string refId, [Matr } [NonAction] - public override IHttpActionResult Post(List objs, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post( + List objs, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { return base.Post(objs, zoneId, contextId); } - public override IHttpActionResult Post(Subscription obj, [MatrixParameter] string[] zoneId = null, [MatrixParameter] string[] contextId = null) + public override IHttpActionResult Post( + Subscription obj, + [MatrixParameter] string[] zoneId = null, + [MatrixParameter] string[] contextId = null) { - string sessionToken; - - if (!authenticationService.VerifyAuthenticationHeader(Request.Headers, out sessionToken)) + if (!AuthenticationService.VerifyAuthenticationHeader(Request.Headers, out string _)) { return Unauthorized(); } if ((zoneId != null && zoneId.Length != 1) || (contextId != null && contextId.Length != 1)) { - return BadRequest("Request failed for object " + typeof(Subscription).Name + " as Zone and/or Context are invalid."); + return BadRequest($"Request failed for object {TypeName} as Zone and/or Context are invalid."); } IHttpActionResult result; @@ -124,28 +121,26 @@ public override IHttpActionResult Post(Subscription obj, [MatrixParameter] strin bool hasAdvisoryId = !string.IsNullOrWhiteSpace(obj.RefId); bool? mustUseAdvisory = HttpUtils.GetMustUseAdvisory(Request.Headers); - if (mustUseAdvisory.HasValue && mustUseAdvisory.Value == true) + if (mustUseAdvisory.HasValue) { - - if (hasAdvisoryId) + if (mustUseAdvisory.Value && !hasAdvisoryId) { - Subscription createdObject = service.Create(obj, mustUseAdvisory, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); - result = Created(uri, createdObject); + result = BadRequest( + $"Request failed for object {TypeName} as object ID is not provided, but mustUseAdvisory is true."); } else { - result = BadRequest($"Request failed for object {TypeName} as object ID is not provided, but mustUseAdvisory is true."); + Subscription createdObject = Service.Create(obj, mustUseAdvisory, zoneId?[0], contextId?[0]); + string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); + result = Created(uri, createdObject); } - } else { - Subscription createdObject = service.Create(obj, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - string uri = Url.Link("DefaultApi", new { controller = typeof(Subscription).Name, id = createdObject.RefId }); + Subscription createdObject = Service.Create(obj, null, zoneId?[0], contextId?[0]); + string uri = Url.Link("DefaultApi", new { controller = TypeName, id = createdObject.RefId }); result = Created(uri, createdObject); } - } catch (AlreadyExistsException) { @@ -153,11 +148,11 @@ public override IHttpActionResult Post(Subscription obj, [MatrixParameter] strin } catch (ArgumentException e) { - result = BadRequest("Object to create of type " + typeof(Subscription).Name + " is invalid.\n " + e.Message); + result = BadRequest($"Object to create of type {TypeName} is invalid.\n{e.Message}"); } catch (CreateException e) { - result = BadRequest("Request failed for object " + typeof(Subscription).Name + ".\n " + e.Message); + result = BadRequest($"Request failed for object {TypeName}.\n{e.Message}"); } catch (RejectedException) { @@ -165,7 +160,7 @@ public override IHttpActionResult Post(Subscription obj, [MatrixParameter] strin } catch (QueryException e) { - result = BadRequest("Request failed for object " + typeof(Subscription).Name + ".\n " + e.Message); + result = BadRequest($"Request failed for object {TypeName}.\n{e.Message}"); } catch (Exception e) { @@ -174,7 +169,5 @@ public override IHttpActionResult Post(Subscription obj, [MatrixParameter] strin return result; } - } - } \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Sif.Framework.Demo.Broker.csproj b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Sif.Framework.Demo.Broker.csproj index de95e482..af1d51e0 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Sif.Framework.Demo.Broker.csproj +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/Sif.Framework.Demo.Broker.csproj @@ -72,9 +72,6 @@ ..\packages\Remotion.Linq.EagerFetching.2.2.0\lib\net45\Remotion.Linq.EagerFetching.dll - - ..\packages\Sif.Framework.3.2.1.14\lib\net461\Sif.Framework.dll - ..\packages\Sif.Specification.DataModel.Au.3.4.7\lib\netstandard2.0\Sif.Specification.DataModel.Au.dll @@ -167,6 +164,12 @@ + + + {3682c668-02cd-40d5-867d-f019c116bddb} + Sif.Framework + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/packages.config b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/packages.config index f1f94e1d..2543f180 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/packages.config +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Broker/packages.config @@ -14,7 +14,6 @@ - diff --git a/Data/Databases/SQLite/SifFrameworkDatabase.db b/Data/Databases/SQLite/SifFrameworkDatabase.db index d114678f70bf481c29309892a1f3d1c1b96599ab..d6ff5c08d9e8cea680f6866c76618f0083be8d72 100644 GIT binary patch delta 4051 zcmai03s6+&75>kE?mmEpusrs86z^fwcvUY?^g7dAF@zRa)2Ex8Ap@cij(y=M2>u6p_mC$Cw&4i!nH1V=Dge<`PbK^I4f zx%qQf_H}Mt>1*25v#zP6XL0A|<~8f5c6itJEiCTZykv37+LhkQ&D~GUlx|N>rUdRV zyoYy!X7}IGqC)`A5o2OvDPNA48Q#Rpl-!@NAO+nMa^lJ8j)_d-RGD6|)BtwkPw;Pe z6eaA(b6A5`v=UN~OBbhaaHbg11G8IN8XIb7w>LC5Eo*3++sti%cRVM_nlD;Gm%W7s@qHL4hq zht(URnsxf9W?;XIa`F_)Z$dXt)d_-0z&rN2v_07Eu|G9WY9S0jcT_}cJ>n}aYJ-7JaGMgBfrCVpH3w~+H|{4KtlKf!C+Y4`&i z0zW(kQ^6o*rfie1RPdraZ@IU)r+8JdXGQ7Ca!*-hagV3F+gsu(o8~Q_>aCpCQ`uYM zDU?e3ra*yQQpqjS^0j8jmoHTEbe`jq-d>vvdGhuOo+1CEk{8IgO29@gvC{cIldGtr ztfFUCX-TE0x3bqu=u?Y5-KE|NkGHJ6yJwoWbmfZ5Qct#mEFhq29d2mN;#oX}8{sb8fREt=I0uj7C@g?k;DubUK`gs3Z*jwOa+3#~^1N!8 zlc1J4DOBcud9?=~1(b)XVQIWc06UoLe2u<#-{T`iQ{eZI!r}z5LeioRU+a>!@x)!s z?#hNTa82iL^Amg@|2f~v`}k7c#H)D`RUiSrgPU*_F2HZ$7qAz82G776;#dGxP)Hp% zvb$940e^hJEdaNR?082@-RyQ>Vqh}q=^}f5Y%ENHLNZxJc1)#D2o#X&6xq>G_VIyy z4dRHFb9}(1>4$4ueFSL=V6TP`If?Xi2Ybaoj#5-Y9Bglh(n+e* z!S;+%Iy8*kVM@EEzZ|BtY4N*MN>jk9sCFi+aPa|);%#F)!x^NKo^I=6FOAC}MG3L7 z!B7Utq&jU(8p|L_!`Kndz^v)p!x?s2&r?zOT03S7!-KmM_+U#cHO3Vb)3NDd=mFKKguh$$hi#{7w}lTXLh}<%IFFqu^y}c$p!*j1XSBhL;u%Z&DafjDqLX@EjpLyNXvG zuqm!;LBr=XQ)?rSmqh&?D@gdvmOyHlFl9nSav)hHv?M8kT1UfyNddFGVF{-yC90>9 zXH~&j1B$GSZDVrb44C4Fi|`Hv;ULKH0z3`hr|Yu?=0GXrQH>4k8+Ma@#4fVmv6F0w z?PS~VU-&8hl|Jc5+I{RWT`^WJs;6SZbQRgTvqN1(ZIq&Ws22n~L{paT=gzUYWd~I_ zr`m5elt4cq+!>l#c0fbd&d2s^T8Lzy7N@20n!4rCMvA?vkZ{KXj#pG)hsLot!LN`w z!X$gN*bvEXO$(8{tOaT$yHv%lp~$MAEyTD}WwbqDd`b1SX}*K%scd0FsX&VjG49Z` z5aV_&P-7ezxjGYSK%gsokDO5ra*OIKhFFiQtl|UK*VSNAV?Cy_iec8HT4;#$i1IUF zV~vtwv^e4`U;rOcHU;ct)bU|_27~6DdI)BS-vQ4O>02QioYH^)GZ`Gx?K^2;m#&Rg zzEBTu)N{j!x{VatHewR-V_4Ek&rKxC+CtJyGM}WLWC4k?*GQu5EhL#o;v-S~=8`CJ p4J3+Pk+9D~xh@SCd&1j_`wWsU5h{s+gdB0vBD delta 2661 zcmcJRe@s(X6vyv*=e4gb?G%9)0inR4AT1OqzXXvVEmA2zEQoeXK4=H z^S$?c?z!ilUf4En+%|69ogBN5F?NP*oNO~=BicRoV%T?d#X-~p1{nr}u_+_SHG#NF zXga3jtt1aI93puq&KZChdu|r%v+0-~dPbH9KmF)(-A>aWrf*)jR6LlMB`(d&7a!zl zDC$1L`@z`3TNq1QA?o!8`VDxK;Z2gSVSF6g^-~$gTw31T3D}8m;LkXMA`aqdJdYN% zPzFIxJU8!!WN%ADD;KXp2ekQHJH74RR(zc$Bm$Ozcr-g+9H=xES!lBu@Ou|Fb_7tz zVFGlwwsf}0!O;OXa1B6NKF9JbyI6P zM=rd8y$o;QMLdaza5rwjUOIx0ju34Jtq@h#Xrs!!CaR2dtSHr?tKjXC=1Gfm4;Rnd zb<_L7&GQ0>qYNidjEz4Ow5DjWBSSvFZR$AwV%i%0qiYJ~ z!f-go@CuGmISyla25+}byU<5tinw%IGA+;GWNTsyGzX3A?`%pmppW72l<`>{#Sd{9 zcTg8EM;~qBMA7%-D7Et{QTVBV1P6+%uJ0$ISrmSe1q+JK9!=1HV?Qr=w`(awfAHQd zE&r5>h88v`SK>3=BR=(4u9y*D5gM$4-FWQIU9>c9r4^0UoN}lu^pmyWExZz(dH*ch zJRKgM6rYiY*%0gY_(*t;ghh&=ulIXuJ3KB^5Z>Z>6BaZ47C*tA_$(GvPU*BIw$yNLJL$wA!O0k zM)rXHA#HWS4r!tqYWNvEq)FBVV3XDs!ZXtMRu~Mqir{m|Qxj7&Ej6K?zRtH9Jq3p_ zfL(AKIqnB;jC+^c$kkJd7eKo0fJAAif-~C+dW%c?R#ud(ajfj^t#G)CR##gW(7h@Hz$Uv#85>Dq*DRN+f;h*$=eS>G{u8!aV+)MA- z7F>@jupJw)9POAQ>8c=~0$+pB#C)iMNGT-gyF%~=4Dc134gCzhgcI;FybmJ03NJ!G zP7?VN_cV^<7#^kvX)o@=mvJ3+m>)gFp8NO@^grga4BDU$N+FxB$OMc{GBGe}3DAQb z0+V_Nb;^a9)K005;lTo?T6eRzrAC=BE@^X93oVc@6pZal>e}o5-a1dUve3AAiO1hH z-^4>Q7?nrc?Wt13RCuN8sPK7eOszXW^a^DrMx~c4^q2^}Oj#MD&`TA1OqgDxhN*Oy z>ZtT$HAYFjNSQFG@InP{h`^mO0r`*yg1Y4<><(lg2V4RjHD z2Kkpkr_j@Bd>(XRx|O_Bpi@&%Bj-5i)YMbS83CP=`Wza+2LVB)r%)fP0U<(9CchH| zg`Py?MIeOfv&pLhL8T{>QviZWr$5M$0fIs|)7T7J6`p_xSsQ30@ObiTKr6!oU2){N zKpUpdA}<@XL|1OZ6qf6i3-}+}G|=gNqCWl4Hht38l;3y+{ diff --git a/Documentation/Developer Guides/Configuring the Event Consumer demo.md b/Documentation/Developer Guides/Configuring the Event Consumer demo.md new file mode 100644 index 00000000..78d33bb4 --- /dev/null +++ b/Documentation/Developer Guides/Configuring the Event Consumer demo.md @@ -0,0 +1,17 @@ +Configuring the Event Consumer demo +----------------------------------- + +1. In the demo Consumer project: + + + Configure the consumer.environment.url app setting to reference the BROKERED environment endpoint. + + Configure the EventConsumerApp to be the Startup object for the project. + +1. In the demo Provider project: + + + Configure the provider.environment.url app setting to reference the BROKERED environment endpoint. + +1. Run the demo Broker instead of the EnvironmentProvider. + +1. Run the demo Provider. + +1. Run the demo Consumer. From 4c63489ad35638083e9ef604371b359f1c638b5a Mon Sep 17 00:00:00 2001 From: rafidzal Date: Mon, 14 Dec 2020 15:11:42 +0800 Subject: [PATCH 07/16] Modified the constructors of the functional service classes to include an IFrameworkSettings parameter. --- .../Sif.Framework/Consumers/BasicConsumer.cs | 2 +- .../Sif.Framework/Consumers/Consumer.cs | 8 +-- .../Sif.Framework/Consumers/EventConsumer.cs | 6 +- .../Consumers/FunctionalServiceConsumer.cs | 26 +++++++-- .../Providers/FunctionalServiceProvider.cs | 54 ++++++++++++------ .../FunctionalServiceProviderFactory.cs | 39 +++++++------ .../Sif.Framework/Providers/Provider.cs | 2 +- .../Sif.Framework.Demo.Hits.Consumer.csproj | 9 ++- .../packages.config | 1 - .../Sif.Framework.Demo.Uk.Consumer.csproj | 9 ++- .../packages.config | 1 - .../Sif.Framework.Demo.Uk.Provider.csproj | 9 ++- .../packages.config | 1 - .../Sif.Framework.Demo.Us.Consumer.csproj | 9 ++- .../packages.config | 1 - .../Sif.Framework.Demo.Us.Provider.csproj | 9 ++- .../packages.config | 1 - Data/Databases/SQLite/SifFrameworkDatabase.db | Bin 205824 -> 205824 bytes 18 files changed, 113 insertions(+), 74 deletions(-) diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs index 8b2f9c15..984146e8 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/BasicConsumer.cs @@ -33,7 +33,7 @@ public class BasicConsumer : Consumer, string>, IBasicConsumer /// /// Consumer /// - public BasicConsumer(Environment environment, IFrameworkSettings settings = null) : base(environment, settings) + protected BasicConsumer(Environment environment, IFrameworkSettings settings = null) : base(environment, settings) { } diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs index 4a3ec3cd..83abab6b 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/Consumer.cs @@ -84,7 +84,7 @@ public class Consumer : IConsumer /// Environment object. /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. - public Consumer(Model.Infrastructure.Environment environment, IFrameworkSettings settings = null) + protected Consumer(Model.Infrastructure.Environment environment, IFrameworkSettings settings = null) { ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; @@ -106,12 +106,8 @@ public Consumer( string userToken = null, string solutionId = null, IFrameworkSettings settings = null) + : this(new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId), settings) { - ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; - - var environment = new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId); - environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); - RegistrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs index c4ae3cfc..4fd2cfec 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/EventConsumer.cs @@ -123,12 +123,8 @@ protected EventConsumer( string userToken = null, string solutionId = null, IFrameworkSettings settings = null) + : this(new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId), settings) { - ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; - - var environment = new Model.Infrastructure.Environment(applicationKey, instanceId, userToken, solutionId); - Environment = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); - RegistrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// diff --git a/Code/Sif3Framework/Sif.Framework/Consumers/FunctionalServiceConsumer.cs b/Code/Sif3Framework/Sif.Framework/Consumers/FunctionalServiceConsumer.cs index 4b56a836..afa5880f 100644 --- a/Code/Sif3Framework/Sif.Framework/Consumers/FunctionalServiceConsumer.cs +++ b/Code/Sif3Framework/Sif.Framework/Consumers/FunctionalServiceConsumer.cs @@ -1,6 +1,6 @@ /* * Crown Copyright © Department for Education (UK) 2016 - * Copyright 2017 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ using Sif.Framework.Model.Infrastructure; using Sif.Framework.Model.Responses; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Mapper; using Sif.Framework.Service.Registration; using Sif.Framework.Service.Serialisation; @@ -42,6 +43,11 @@ public class FunctionalServiceConsumer private Environment environmentTemplate; private RegistrationService registrationService; + /// + /// Application settings associated with the Consumer. + /// + protected IFrameworkSettings ConsumerSettings { get; } + /// /// Consumer environment template /// @@ -62,10 +68,13 @@ protected IRegistrationService RegistrationService /// Create a Consumer instance based upon the Environment passed. /// /// Environment object. - public FunctionalServiceConsumer(Environment environment) + /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. + public FunctionalServiceConsumer(Environment environment, IFrameworkSettings settings = null) { - environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, SettingsManager.ConsumerSettings); - registrationService = new RegistrationService(SettingsManager.ConsumerSettings, SessionsManager.ConsumerSessionService); + ConsumerSettings = settings ?? SettingsManager.ConsumerSettings; + + environmentTemplate = EnvironmentUtils.MergeWithSettings(environment, ConsumerSettings); + registrationService = new RegistrationService(ConsumerSettings, SessionsManager.ConsumerSessionService); } /// @@ -75,7 +84,14 @@ public FunctionalServiceConsumer(Environment environment) /// Instance ID. /// User token. /// Solution ID. - public FunctionalServiceConsumer(string applicationKey, string instanceId = null, string userToken = null, string solutionId = null): this(new Environment(applicationKey, instanceId, userToken, solutionId)) + /// Consumer settings. If null, Consumer settings will be read from the SifFramework.config file. + public FunctionalServiceConsumer( + string applicationKey, + string instanceId = null, + string userToken = null, + string solutionId = null, + IFrameworkSettings settings = null) + : this(new Environment(applicationKey, instanceId, userToken, solutionId), settings) { } diff --git a/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProvider.cs b/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProvider.cs index d2a43b2e..0ce58e26 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProvider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProvider.cs @@ -1,6 +1,6 @@ /* * Crown Copyright © Department for Education (UK) 2016 - * Copyright 2017 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ using Sif.Framework.Model.Exceptions; using Sif.Framework.Model.Infrastructure; +using Sif.Framework.Model.Settings; using Sif.Framework.Service; using Sif.Framework.Service.Authentication; using Sif.Framework.Service.Functional; @@ -49,16 +50,31 @@ public class FunctionalServiceProvider : ApiController /// protected IAuthenticationService authService; + /// + /// Application settings associated with the Provider. + /// + protected IFrameworkSettings ProviderSettings { get; } + + /// + /// Create an instance. + /// + public FunctionalServiceProvider() : this(null) + { + } + /// /// Create an instance. /// - public FunctionalServiceProvider() + /// Provider settings. If null, Provider settings will be read from the SifFramework.config file. + protected FunctionalServiceProvider(IFrameworkSettings settings = null) { - if (EnvironmentType.DIRECT.Equals(SettingsManager.ProviderSettings.EnvironmentType)) + ProviderSettings = settings ?? SettingsManager.ProviderSettings; + + if (EnvironmentType.DIRECT.Equals(ProviderSettings.EnvironmentType)) { authService = new DirectAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); } - else if (EnvironmentType.BROKERED.Equals(SettingsManager.ProviderSettings.EnvironmentType)) + else if (EnvironmentType.BROKERED.Equals(ProviderSettings.EnvironmentType)) { authService = new BrokeredAuthenticationService(new ApplicationRegisterService(), new EnvironmentService()); } @@ -98,7 +114,7 @@ public virtual HttpResponseMessage Post([FromUri] string serviceName, [FromUri] Guid id = service.Create(item, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - if (SettingsManager.ProviderSettings.JobBinding) + if (ProviderSettings.JobBinding) { service.Bind(id, getOwnerId(sessionToken)); } @@ -162,7 +178,7 @@ public virtual HttpResponseMessage Post([FromUri] string serviceName, [FromBody] } Guid id = service.Create(job, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - if (SettingsManager.ProviderSettings.JobBinding) + if (ProviderSettings.JobBinding) { service.Bind(id, getOwnerId(sessionToken)); } @@ -238,7 +254,7 @@ public virtual ICollection Get([FromUri] string serviceName, [MatrixPar ICollection jobs = service.Retrieve(zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); foreach (jobType job in jobs) { - if (!SettingsManager.ProviderSettings.JobBinding + if (!ProviderSettings.JobBinding || service.IsBound(Guid.Parse(job.id), getOwnerId(sessionToken))) { items.Add(job); @@ -277,7 +293,7 @@ public virtual HttpResponseMessage Get([FromUri] string serviceName, [FromUri] G IFunctionalService service = getService(serviceName); item = service.Retrieve(id, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(Guid.Parse(item.id), getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as one or more jobs referred to in this request do not belong to this consumer."); @@ -337,7 +353,7 @@ public virtual HttpResponseMessage Delete([FromUri] string serviceName, [FromUri { IFunctionalService service = getService(serviceName); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(id, getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as one or more jobs referred to in this request do not belong to this consumer."); @@ -345,7 +361,7 @@ public virtual HttpResponseMessage Delete([FromUri] string serviceName, [FromUri service.Delete(id, zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - if (SettingsManager.ProviderSettings.JobBinding) + if (ProviderSettings.JobBinding) { service.Unbind(id); } @@ -377,7 +393,7 @@ public virtual HttpResponseMessage Delete([FromUri] string serviceName, [FromBod { try { - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(Guid.Parse(deleteId.id), getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as job does not belong to this consumer."); @@ -385,7 +401,7 @@ public virtual HttpResponseMessage Delete([FromUri] string serviceName, [FromBod service.Delete(Guid.Parse(deleteId.id), zoneId: (zoneId == null ? null : zoneId[0]), contextId: (contextId == null ? null : contextId[0])); - if (SettingsManager.ProviderSettings.JobBinding) + if (ProviderSettings.JobBinding) { service.Unbind(Guid.Parse(deleteId.id)); } @@ -437,7 +453,7 @@ public virtual HttpResponseMessage Post([FromUri] string serviceName, [FromUri] try { IFunctionalService service = getService(serviceName); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(id, getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as the job referred to in this request does not belong to this consumer."); @@ -478,7 +494,7 @@ public virtual HttpResponseMessage Get([FromUri] string serviceName, [FromUri] G try { IFunctionalService service = getService(serviceName); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(id, getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as the job referred to in this request does not belong to this consumer."); @@ -517,7 +533,7 @@ public virtual HttpResponseMessage Put([FromUri] string serviceName, [FromUri] G try { IFunctionalService service = getService(serviceName); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(id, getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as the job referred to in this request does not belong to this consumer."); @@ -558,7 +574,7 @@ public virtual HttpResponseMessage Delete([FromUri] string serviceName, [FromUri try { IFunctionalService service = getService(serviceName); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(id, getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as the job referred to in this request does not belong to this consumer."); @@ -602,7 +618,7 @@ public virtual HttpResponseMessage Post([FromUri] string serviceName, [FromUri] try { IFunctionalService service = getService(serviceName); - if (SettingsManager.ProviderSettings.JobBinding + if (ProviderSettings.JobBinding && !service.IsBound(id, getOwnerId(sessionToken))) { throw new InvalidSessionException("Request failed as the job referred to in this request does not belong to this consumer."); @@ -645,7 +661,7 @@ protected virtual IFunctionalService getService(string serviceName) throw new InvalidOperationException("Found a functional service to support messages to " + serviceName + ", but its name isn't a plural (doesn't end in 's'). This will not work in the current framework."); } - IService service = FunctionalServiceProviderFactory.GetInstance().GetProvider(serviceName); + IService service = FunctionalServiceProviderFactory.GetInstance(ProviderSettings).GetProvider(serviceName); if (service == null) { @@ -783,7 +799,7 @@ private string getOwnerId(string sessionToken) { string ownerId = null; - switch (SettingsManager.ProviderSettings.EnvironmentType) + switch (ProviderSettings.EnvironmentType) { case EnvironmentType.DIRECT: // Application key is either in header or in session token diff --git a/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProviderFactory.cs b/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProviderFactory.cs index 6a751680..39d9f44e 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProviderFactory.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/FunctionalServiceProviderFactory.cs @@ -1,6 +1,6 @@ /* * Crown Copyright © Department for Education (UK) 2016 - * Copyright 2017 Systemic Pty Ltd + * Copyright 2020 Systemic Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,11 @@ public class FunctionalServiceProviderFactory private Timer eventTimer = null; private Timer timeoutTimer = null; + /// + /// Application settings associated with the Provider. + /// + private IFrameworkSettings ProviderSettings { get; } + // Active Providers for event publishing. These providers run in the background as an independent thread. private Dictionary providers = new Dictionary(); @@ -59,7 +64,7 @@ private Type[] Classes return classes; } - string classesStr = SettingsManager.ProviderSettings.JobClasses; + string classesStr = ProviderSettings.JobClasses; log.Debug("Attempting to load named providers: " + classesStr); @@ -107,7 +112,7 @@ where ProviderUtils.isFunctionalService(type) /// Creates and configures the factory singleton instance. /// /// The factory singleton - public static FunctionalServiceProviderFactory CreateFactory() + public static FunctionalServiceProviderFactory CreateFactory(IFrameworkSettings settings = null) { lock (locked) { @@ -116,7 +121,7 @@ public static FunctionalServiceProviderFactory CreateFactory() { try { - factory = new FunctionalServiceProviderFactory(); + factory = new FunctionalServiceProviderFactory(settings); } catch (Exception ex) { @@ -193,11 +198,11 @@ public static void Shutdown() * * @return See Desc. */ - public static FunctionalServiceProviderFactory GetInstance() + public static FunctionalServiceProviderFactory GetInstance(IFrameworkSettings settings = null) { if (factory == null) { - return CreateFactory(); + return CreateFactory(settings); } return factory; } @@ -235,22 +240,22 @@ public IService GetProvider(string name) /*---------------------*/ /*-- Private Methods --*/ /*---------------------*/ - private FunctionalServiceProviderFactory() + private FunctionalServiceProviderFactory(IFrameworkSettings settings = null) { - ProviderSettings settings = SettingsManager.ProviderSettings as ProviderSettings; - InitialiseProviders(settings); - StartProviders(settings); - StartEventing(settings); - StartTimeout(settings); + ProviderSettings = settings ?? SettingsManager.ProviderSettings; + InitialiseProviders(); + StartProviders(ProviderSettings); + StartEventing(); + StartTimeout(ProviderSettings); } - private void InitialiseProviders(ProviderSettings settings) + private void InitialiseProviders() { log.Debug("Initialising ProviderFactory (currently only supports Functional Services)"); // settings.Classes only returns functional services at the moment, but can easily be extended to other types of services. foreach (Type type in Classes) { - log.Debug("Provider class to initialse: " + type.FullName); + log.Debug("Provider class to initialise: " + type.FullName); try { ServiceClassInfo providerClassInfo = new ServiceClassInfo(type, Type.EmptyTypes); @@ -285,7 +290,7 @@ private void InitialiseProviders(ProviderSettings settings) } } - private void StartProviders(ProviderSettings settings) + private void StartProviders(IFrameworkSettings settings) { int delay = settings.StartupDelay; //delay between threads in seconds log.Debug("Start up delay between providers is: " + delay + " seconds"); @@ -301,7 +306,7 @@ private void StartProviders(ProviderSettings settings) } } - private void StartEventing(ProviderSettings settings) + private void StartEventing() { // Incomplete and removed from current version of framework /* @@ -332,7 +337,7 @@ private void StartEventing(ProviderSettings settings) */ } - private void StartTimeout(ProviderSettings settings) + private void StartTimeout(IFrameworkSettings settings) { log.Info("Setting up job timeout..."); if (!settings.JobTimeoutEnabled) diff --git a/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs b/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs index 741e586a..a929baf8 100644 --- a/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs +++ b/Code/Sif3Framework/Sif.Framework/Providers/Provider.cs @@ -94,7 +94,7 @@ public abstract class Provider protected Provider(IProviderService service, IFrameworkSettings settings = null) { Service = service; - ProviderSettings = settings ?? SettingsManager.ConsumerSettings; + ProviderSettings = settings ?? SettingsManager.ProviderSettings; if (EnvironmentType.DIRECT.Equals(ProviderSettings.EnvironmentType)) { diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Hits.Consumer/Sif.Framework.Demo.Hits.Consumer.csproj b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Hits.Consumer/Sif.Framework.Demo.Hits.Consumer.csproj index d5d88cfd..37ccd2d6 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Hits.Consumer/Sif.Framework.Demo.Hits.Consumer.csproj +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Hits.Consumer/Sif.Framework.Demo.Hits.Consumer.csproj @@ -60,9 +60,6 @@ ..\packages\Remotion.Linq.EagerFetching.2.2.0\lib\net45\Remotion.Linq.EagerFetching.dll - - ..\packages\Sif.Framework.3.2.1.14\lib\net461\Sif.Framework.dll - ..\packages\Sif.Specification.DataModel.Au.3.4.7\lib\netstandard2.0\Sif.Specification.DataModel.Au.dll @@ -125,6 +122,12 @@ Always + + + {3682c668-02cd-40d5-867d-f019c116bddb} + Sif.Framework + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs index 2c71d82d..209225e7 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/ConsumerApp.cs @@ -19,25 +19,30 @@ using Sif.Framework.Demo.Au.Consumer.Utils; using Sif.Framework.Model.Query; using Sif.Framework.Model.Responses; +using Sif.Framework.Model.Settings; +using Sif.Framework.Settings; using Sif.Framework.Utils; using Sif.Specification.DataModel.Au; using System; using System.Collections.Generic; using System.Linq; +using Tardigrade.Framework.Configurations; +using Tardigrade.Framework.EntityFramework.Configurations; namespace Sif.Framework.Demo.Au.Consumer { internal class ConsumerApp { - private static readonly slf4net.ILogger log = slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static readonly slf4net.ILogger Log = slf4net.LoggerFactory.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static readonly Random Random = new Random(); - private static Random random = new Random(); + private enum SettingsSource { Database, File } private static StudentPersonal CreateStudent() { NameOfRecordType name = new NameOfRecordType { Type = NameOfRecordTypeType.LGL, FamilyName = RandomNameGenerator.FamilyName, GivenName = RandomNameGenerator.GivenName }; PersonInfoType personInfo = new PersonInfoType { Name = name }; - StudentPersonal studentPersonal = new StudentPersonal { LocalId = random.Next(10000, 99999).ToString(), PersonInfo = personInfo }; + StudentPersonal studentPersonal = new StudentPersonal { LocalId = Random.Next(10000, 99999).ToString(), PersonInfo = personInfo }; return studentPersonal; } @@ -54,16 +59,37 @@ private static List CreateStudents(int count) return studentPersonalsCache; } - private void RunStudentPersonalConsumer() + private static IFrameworkSettings GetSettings(SettingsSource source) { - StudentPersonalConsumer studentPersonalConsumer = new StudentPersonalConsumer( - SettingsManager.ConsumerSettings.ApplicationKey, - SettingsManager.ConsumerSettings.InstanceId, - SettingsManager.ConsumerSettings.UserToken, - SettingsManager.ConsumerSettings.SolutionId, - SettingsManager.ConsumerSettings); + IFrameworkSettings settings; + + switch (source) + { + case SettingsSource.Database: + settings = new ConsumerSettings(new ApplicationConfiguration(new AppSettingsConfigurationSource("name=SettingsDb"))); + break; + + case SettingsSource.File: + settings = SettingsManager.ConsumerSettings; + break; + + default: + settings = SettingsManager.ConsumerSettings; + break; + } + return settings; + } + + private static void RunStudentPersonalConsumer(IFrameworkSettings settings) + { + var studentPersonalConsumer = new StudentPersonalConsumer( + settings.ApplicationKey, + settings.InstanceId, + settings.UserToken, + settings.SolutionId, + settings); studentPersonalConsumer.Register(); - if (log.IsInfoEnabled) log.Info("Registered the Consumer."); + if (Log.IsInfoEnabled) Log.Info("Registered the Consumer."); try { @@ -71,11 +97,11 @@ private void RunStudentPersonalConsumer() foreach (StudentPersonal student in queriedStudents) { - if (log.IsInfoEnabled) log.Info("Queried student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Queried student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); } // Retrieve Bart Simpson using QBE. - if (log.IsInfoEnabled) log.Info("*** Retrieve Bart Simpson using QBE."); + if (Log.IsInfoEnabled) Log.Info("*** Retrieve Bart Simpson using QBE."); NameOfRecordType name = new NameOfRecordType { FamilyName = "Simpson", GivenName = "Bart" }; PersonInfoType personInfo = new PersonInfoType { Name = name }; StudentPersonal studentPersonal = new StudentPersonal { PersonInfo = personInfo }; @@ -83,11 +109,11 @@ private void RunStudentPersonalConsumer() foreach (StudentPersonal student in filteredStudents) { - if (log.IsInfoEnabled) log.Info("Filtered student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Filtered student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); } // Create a new student. - if (log.IsInfoEnabled) log.Info("*** Create a new student."); + if (Log.IsInfoEnabled) Log.Info("*** Create a new student."); string[] text = new string[] { @" @@ -109,15 +135,15 @@ private void RunStudentPersonalConsumer() try { StudentPersonal retrievedNewStudent = studentPersonalConsumer.Create(newStudent, true); - if (log.IsInfoEnabled) log.Info($"Created new student {newStudent.PersonInfo.Name.GivenName} {newStudent.PersonInfo.Name.FamilyName} with ID of {studentID}."); + if (Log.IsInfoEnabled) Log.Info($"Created new student {newStudent.PersonInfo.Name.GivenName} {newStudent.PersonInfo.Name.FamilyName} with ID of {studentID}."); } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to create a new student is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to create a new student is rejected."); } // Create multiple new students. - if (log.IsInfoEnabled) log.Info("*** Create multiple new students."); + if (Log.IsInfoEnabled) Log.Info("*** Create multiple new students."); List newStudents = CreateStudents(5); try @@ -127,12 +153,12 @@ private void RunStudentPersonalConsumer() foreach (CreateStatus status in multipleCreateResponse.StatusRecords) { - if (log.IsInfoEnabled) log.Info("Create status code is " + status.StatusCode); + if (Log.IsInfoEnabled) Log.Info("Create status code is " + status.StatusCode); newStudents[count++].RefId = status.Id; } // Update multiple students. - if (log.IsInfoEnabled) log.Info("*** Update multiple students."); + if (Log.IsInfoEnabled) Log.Info("*** Update multiple students."); foreach (StudentPersonal student in newStudents) { student.PersonInfo.Name.GivenName += "o"; @@ -144,16 +170,16 @@ private void RunStudentPersonalConsumer() foreach (UpdateStatus status in multipleUpdateResponse.StatusRecords) { - if (log.IsInfoEnabled) log.Info("Update status code is " + status.StatusCode); + if (Log.IsInfoEnabled) Log.Info("Update status code is " + status.StatusCode); } } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to update multiple students is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to update multiple students is rejected."); } // Delete multiple students. - if (log.IsInfoEnabled) log.Info("*** Delete multiple students."); + if (Log.IsInfoEnabled) Log.Info("*** Delete multiple students."); ICollection refIds = new List(); foreach (CreateStatus status in multipleCreateResponse.StatusRecords) @@ -167,38 +193,38 @@ private void RunStudentPersonalConsumer() foreach (DeleteStatus status in multipleDeleteResponse.StatusRecords) { - if (log.IsInfoEnabled) log.Info("Delete status code is " + status.StatusCode); + if (Log.IsInfoEnabled) Log.Info("Delete status code is " + status.StatusCode); } } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to delete multiple students is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to delete multiple students is rejected."); } } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to create multiple new students is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to create multiple new students is rejected."); } // Retrieve all students from zone "Gov" and context "Curr". - if (log.IsInfoEnabled) log.Info("*** Retrieve all students from zone \"Gov\" and context \"Curr\"."); + if (Log.IsInfoEnabled) Log.Info("*** Retrieve all students from zone \"Gov\" and context \"Curr\"."); IEnumerable students = studentPersonalConsumer.Query(zoneId: "Gov", contextId: "Curr"); foreach (StudentPersonal student in students) { - if (log.IsInfoEnabled) log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); } if (students.Count() > 1) { // Retrieve a single student. - if (log.IsInfoEnabled) log.Info("*** Retrieve a single student."); + if (Log.IsInfoEnabled) Log.Info("*** Retrieve a single student."); string studentId = students.ElementAt(1).RefId; StudentPersonal secondStudent = studentPersonalConsumer.Query(studentId); - if (log.IsInfoEnabled) log.Info("Name of second student is " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Name of second student is " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName); // Update that student and confirm. - if (log.IsInfoEnabled) log.Info("*** Update that student and confirm."); + if (Log.IsInfoEnabled) Log.Info("*** Update that student and confirm."); secondStudent.PersonInfo.Name.GivenName = "Homer"; secondStudent.PersonInfo.Name.FamilyName = "Simpson"; @@ -206,15 +232,15 @@ private void RunStudentPersonalConsumer() { studentPersonalConsumer.Update(secondStudent); secondStudent = studentPersonalConsumer.Query(studentId); - if (log.IsInfoEnabled) log.Info("Name of second student has been changed to " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Name of second student has been changed to " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName); } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to update a student is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to update a student is rejected."); } // Delete that student and confirm. - if (log.IsInfoEnabled) log.Info("*** Delete that student and confirm."); + if (Log.IsInfoEnabled) Log.Info("*** Delete that student and confirm."); try { @@ -224,21 +250,21 @@ private void RunStudentPersonalConsumer() if (studentDeleted) { - if (log.IsInfoEnabled) log.Info("Student " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName + " was successfully deleted."); + if (Log.IsInfoEnabled) Log.Info("Student " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName + " was successfully deleted."); } else { - if (log.IsInfoEnabled) log.Info("Student " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName + " was NOT deleted."); + if (Log.IsInfoEnabled) Log.Info("Student " + secondStudent.PersonInfo.Name.GivenName + " " + secondStudent.PersonInfo.Name.FamilyName + " was NOT deleted."); } } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to delete a student is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to delete a student is rejected."); } } // Retrieve students based on Teaching Group using Service Paths. - if (log.IsInfoEnabled) log.Info("*** Retrieve students based on Teaching Group using Service Paths."); + if (Log.IsInfoEnabled) Log.Info("*** Retrieve students based on Teaching Group using Service Paths."); EqualCondition condition = new EqualCondition() { Left = "TeachingGroups", Right = "597ad3fe-47e7-4b2c-b919-a93c564d19d0" }; IList conditions = new List { @@ -251,7 +277,7 @@ private void RunStudentPersonalConsumer() foreach (StudentPersonal student in teachingGroupStudents) { - if (log.IsInfoEnabled) log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); if (student.SIF_ExtendedElements != null && student.SIF_ExtendedElements.Length > 0) { @@ -259,7 +285,7 @@ private void RunStudentPersonalConsumer() { foreach (string content in element.Text) { - if (log.IsInfoEnabled) log.Info("Extended element text is ...\n" + content); + if (Log.IsInfoEnabled) Log.Info("Extended element text is ...\n" + content); } } } @@ -267,87 +293,103 @@ private void RunStudentPersonalConsumer() } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info("Access to query students by Service Path TeachingGroups/{}/StudentPersonals is rejected."); + if (Log.IsInfoEnabled) Log.Info("Access to query students by Service Path TeachingGroups/{}/StudentPersonals is rejected."); } // Retrieve student changes since a particular point as defined by the Changes Since marker. - if (log.IsInfoEnabled) log.Info("*** Retrieve student changes since a particular point as defined by the Changes Since marker."); + if (Log.IsInfoEnabled) Log.Info("*** Retrieve student changes since a particular point as defined by the Changes Since marker."); string changesSinceMarker = studentPersonalConsumer.GetChangesSinceMarker(); IEnumerable changedStudents = studentPersonalConsumer.QueryChangesSince(changesSinceMarker, out string nextChangesSinceMarker); - if (log.IsInfoEnabled) log.Info("Iteration 1 - Student changes based on Changes Since marker - " + changesSinceMarker); + if (Log.IsInfoEnabled) Log.Info("Iteration 1 - Student changes based on Changes Since marker - " + changesSinceMarker); if (changedStudents == null || changedStudents.Count() == 0) { - if (log.IsInfoEnabled) log.Info("No student changes"); + if (Log.IsInfoEnabled) Log.Info("No student changes"); } else { foreach (StudentPersonal student in changedStudents) { - if (log.IsInfoEnabled) log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); } } changesSinceMarker = nextChangesSinceMarker; nextChangesSinceMarker = null; changedStudents = studentPersonalConsumer.QueryChangesSince(changesSinceMarker, out nextChangesSinceMarker); - if (log.IsInfoEnabled) log.Info("Iteration 2 - Student changes based on Changes Since marker - " + changesSinceMarker); + if (Log.IsInfoEnabled) Log.Info("Iteration 2 - Student changes based on Changes Since marker - " + changesSinceMarker); if (changedStudents == null || changedStudents.Count() == 0) { - if (log.IsInfoEnabled) log.Info("No student changes"); + if (Log.IsInfoEnabled) Log.Info("No student changes"); } else { foreach (StudentPersonal student in changedStudents) { - if (log.IsInfoEnabled) log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); } } changesSinceMarker = nextChangesSinceMarker; nextChangesSinceMarker = null; changedStudents = studentPersonalConsumer.QueryChangesSince(changesSinceMarker, out nextChangesSinceMarker); - if (log.IsInfoEnabled) log.Info("Iteration 3 - Student changes based on Changes Since marker - " + changesSinceMarker); + if (Log.IsInfoEnabled) Log.Info("Iteration 3 - Student changes based on Changes Since marker - " + changesSinceMarker); if (changedStudents == null || changedStudents.Count() == 0) { - if (log.IsInfoEnabled) log.Info("No student changes"); + if (Log.IsInfoEnabled) Log.Info("No student changes"); } else { foreach (StudentPersonal student in changedStudents) { - if (log.IsInfoEnabled) log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); + if (Log.IsInfoEnabled) Log.Info("Student name is " + student.PersonInfo.Name.GivenName + " " + student.PersonInfo.Name.FamilyName); } } } catch (UnauthorizedAccessException) { - if (log.IsInfoEnabled) log.Info($"Access to query students is rejected."); + if (Log.IsInfoEnabled) Log.Info($"Access to query students is rejected."); } catch (Exception e) { - if (log.IsErrorEnabled) log.Error("Error running the StudentPersonal Consumer.\n" + ExceptionUtils.InferErrorResponseMessage(e), e); + if (Log.IsErrorEnabled) Log.Error("Error running the StudentPersonal Consumer.\n" + ExceptionUtils.InferErrorResponseMessage(e), e); } finally { studentPersonalConsumer.Unregister(); - if (log.IsInfoEnabled) log.Info("Unregistered the Consumer."); + if (Log.IsInfoEnabled) Log.Info("Unregistered the Consumer."); } } - private static void Main(string[] args) + private static SettingsSource SelectSettingsSource() { - ConsumerApp app = new ConsumerApp(); + Console.WriteLine(); + Console.Write("Would you like to read the application settings from the SifFramework.config (F)ile or from the SifFrameworkConfig.db (D)atabase? Pressing enter defaults to (F)ile. - "); + ConsoleKeyInfo info; + do + { + info = Console.ReadKey(); + } + while (info.Key != ConsoleKey.D && info.Key != ConsoleKey.F && info.Key != ConsoleKey.Enter); + + Console.WriteLine(); + Console.WriteLine(); + + return info.Key == ConsoleKey.D ? SettingsSource.Database : SettingsSource.File; + } + + private static void Main() + { try { - app.RunStudentPersonalConsumer(); + RunStudentPersonalConsumer(GetSettings(SelectSettingsSource())); } catch (Exception e) { - if (log.IsErrorEnabled) log.Error("Error running the Student Personal CRUD Consumer.\n" + ExceptionUtils.InferErrorResponseMessage(e), e); + if (Log.IsErrorEnabled) Log.Error("Error running the Student Personal CRUD Consumer.\n" + ExceptionUtils.InferErrorResponseMessage(e), e); } Console.WriteLine("Press any key to continue ..."); diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Sif.Framework.Demo.Au.Consumer.csproj b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Sif.Framework.Demo.Au.Consumer.csproj index a26613ab..a40cee2c 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Sif.Framework.Demo.Au.Consumer.csproj +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/Sif.Framework.Demo.Au.Consumer.csproj @@ -59,6 +59,9 @@ + + PreserveNewest + Always @@ -76,6 +79,12 @@ 1.1.0 + + 1.0.113.6 + + + 11.1.0 + diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/SifFrameworkConfig.db b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Consumer/SifFrameworkConfig.db new file mode 100644 index 0000000000000000000000000000000000000000..16c6f2b6ecf053ec416d93e90dc26b47d9c83638 GIT binary patch literal 12288 zcmeI0&rjQC7{{Hw{3f8ol$@5 z=OESv0YN|z5CjAPK|l}?1Ox#=KoAfF1cA3j;PivU@Wk|V;`D^!uN=tvei<0Ey&8=i zCi5jDS246o?$L&!r6Vh8?Y2Co@hx4j(ptrMR?&)EeBa&J(DGZwa;20j6f0VKdwsvl zYr9m~%$1&N>&EjtmjZj(sY6SH`^#f$!gNBiJqupZLx*?s`?$_X^E@iJpN*)8 zef>ztQ%(hvGJYnhf2u#IU#1jwdi+fJNBL1HDRW99RhEB|zfT47dFuVQMPJ-k5D)|e z0YN|z5CjAPK|m0=h6L0v@DOrslX$f5LZE}!umj?`;4z(n>pPf%ZefNui3Ls(yFh(x z!U1Fc{Y>WQ=t!q_6;nz~8#9}DItgl-(B2L0Gq|2v)bHj8(Ba(Gx8S|S0l%khHdQu( z9T2Nrc)b5)GnX$v$t^4`Po~g=ciSR9K6VJUbZna7vuB$d@_FL+Yy~LOcLPT+K@|e< zOwfxYe}DsQG6?9*$+sDc9C@K9mCvRB3Na1^uYn!gih5mMdf2`ek>NS>*IbOu8Ub1) z%y?x}mZNKg&7A1nZolUHxXqk|B0K`7H)XorPmLIN!}Zzm9$rz9QRrdCFEB{+rCyB9 zC685(ec&voWVAXF$aP+G+f1s=B6D|7KSvRvZUINDJo5;fk}>K<;`wdM=n#x*G0 z-@wxB7}|NKZ3hjW15|fy?7+Vn6jX5vU&h}Je7E=FX{_=_S0eX zayIs{+SNmeQx8j{V3qCa;^TnV&=Co~zBh>Q&8t0It6|x#flKn2Rl150e9~HsFInvS z&Sf#J!*O`ysDPeCTT`(DlotzFoO%H4;+y-;XA}dZspHQ=U?vs`KioGOhff{M`J!cMbn@MaY7HARq_`0)l`bAP5Ko zf`A}!y$IxZ_nC<8z&d^7mEGsa9rUuFK)dlAUPgy~jN=9{1M>*_xpnoK=wtL^G&ZW< zKJi2JprhSA&Pgf%N?y!#BRb1bxy|P>Ha+7Tg(udd7{kthMngvLlkg}QA4Y@|5oHps z#u;3ULu9T$*^aq8knD|HXea9WhB3%^m)RSqAY&h)m5y3;WWi@3qmpzNx$(>Goa&wA Y4e1E?acTt@jv)qbqOExI=;R>zKPFHD8~^|S literal 0 HcmV?d00001 diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/App_Data/SifFrameworkConfig.db b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/App_Data/SifFrameworkConfig.db new file mode 100644 index 0000000000000000000000000000000000000000..977027732b71d04b41e5a8f9d2de569c009a1502 GIT binary patch literal 12288 zcmeI0&u`mQ9Kc`l`n$0W8c+rlnY3dR4X0_hiM32!+GZ$fn{-J!I;K%Q?3dJF`?-EE z?MlU=C&Y~dCoV{wkS6|xNt`$!!Dauzj!4|uk+0i0aaFfD?$Bq;iGO^5y^p_NOW$wp z-l{FA-e7@Cgg%R2LFqKQqw5HvG#nU?XiLFKUvvTg;dQSqjf_u!RkRlCl4j*QgM-*W|I& z^is80s2BBmVR5ynXJb#Y`UlF04qLWlW%YV-v#ysbaBQru>PwY!tzIpZ%5^=vzOr>f zYrR@pD^wroE5!%b+6L|ur$r+hps$Qf-AE6Nl_pZi_AL6C?>NxSZ;_T@N7r$KTltvv zu&*Bqc`6wdWk#PMYpH*C+c9BbGr-llo$FZB==So?Wd|E{u)9F{-pd1L~R7D6^$) z5)f0+fKMKLo3q%S7ix0lIr^`ZpiuI5iDO%Ft@f=uoqI7ekTcJw63i?!%F9d?AKP3M z_%aid2L`BBG`zq&t2jY>-;c05%p}e><5>{Ce5UYnsajmB8!7zo^+XxqPX(=b8(u)0 z5CsiH0BxR%i>EP~%o9Mp4lw{r?QisB_ccYRP3HOm<-9>0PC;bn5@_+33t1D19KVe` zn0S8_-_tr_`J@Sbt>KYfyLt3p*GZGs>~H7|uru{)M~?175ZrKW?=xbHy6w^$1t%8I zPnU=B?PPGRz-gyr#7)fIoVhiV&k^6w#SruOMRBO_u)n*=m{>ROdCT`%AgERH8Uf*e z&lIhI-iK6zRG&3wjQq!g_|esF{7KcrnbQhOqh!_W#_ZhyYG{uIU*GD-wXij`1 zPAAz>dW@(OD5IE2d7*x%{Gt4yZfbujruMxyuKufjqW;#|-?)I^T)AXPKoXDyBmqf4 z5|9KW0ZBj-xL5?#1+)_ivUt4B zP3ySWm5LmKooFJWYQyN=&Z@cs$Kw#?9elg19*+qI6T{j(dMyeG#w15$ka4__tRP_g rqCp*$W6sVPoQ#54Z0>N@++?HxQ;sv7Mbo_=d3GJUJq(;44-WhfR@Vo3 literal 0 HcmV?d00001 diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs index 7e8a999f..0840042f 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/SchoolInfosProvider.cs @@ -17,14 +17,18 @@ using Sif.Framework.Demo.Au.Provider.Models; using Sif.Framework.Demo.Au.Provider.Services; using Sif.Framework.Providers; -using Sif.Framework.Utils; +using Sif.Framework.Settings; using System.Web.Http; +using Tardigrade.Framework.Configurations; +using Tardigrade.Framework.EntityFramework.Configurations; namespace Sif.Framework.Demo.Au.Provider.Controllers { public class SchoolInfosProvider : BasicProvider { - public SchoolInfosProvider() : base(new SchoolInfoService(), SettingsManager.ProviderSettings) + public SchoolInfosProvider() : base( + new SchoolInfoService(), + new ProviderSettings(new ApplicationConfiguration(new AppSettingsConfigurationSource("name=SettingsDb")))) { } diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs index b4140dcb..fd41f090 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentPersonalsProvider.cs @@ -17,15 +17,19 @@ using Sif.Framework.Demo.Au.Provider.Models; using Sif.Framework.Demo.Au.Provider.Services; using Sif.Framework.Providers; -using Sif.Framework.Utils; +using Sif.Framework.Settings; using Sif.Framework.WebApi.ModelBinders; using System.Web.Http; +using Tardigrade.Framework.Configurations; +using Tardigrade.Framework.EntityFramework.Configurations; namespace Sif.Framework.Demo.Au.Provider.Controllers { public class StudentPersonalsProvider : BasicProvider { - public StudentPersonalsProvider() : base(new StudentPersonalService(), SettingsManager.ProviderSettings) + public StudentPersonalsProvider() : base( + new StudentPersonalService(), + new ProviderSettings(new ApplicationConfiguration(new AppSettingsConfigurationSource("name=SettingsDb")))) { } diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs index c8f5036e..e82e6f73 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Controllers/StudentSchoolEnrollmentsProvider.cs @@ -17,15 +17,18 @@ using Sif.Framework.Demo.Au.Provider.Models; using Sif.Framework.Demo.Au.Provider.Services; using Sif.Framework.Providers; -using Sif.Framework.Utils; +using Sif.Framework.Settings; using System.Web.Http; +using Tardigrade.Framework.Configurations; +using Tardigrade.Framework.EntityFramework.Configurations; namespace Sif.Framework.Demo.Au.Provider.Controllers { public class StudentSchoolEnrollmentsProvider : BasicProvider { - public StudentSchoolEnrollmentsProvider() - : base(new StudentSchoolEnrollmentService(), SettingsManager.ProviderSettings) + public StudentSchoolEnrollmentsProvider() : base( + new StudentSchoolEnrollmentService(), + new ProviderSettings(new ApplicationConfiguration(new AppSettingsConfigurationSource("name=SettingsDb")))) { } diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Global.asax.cs b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Global.asax.cs index 7564298d..66512983 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Global.asax.cs +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Global.asax.cs @@ -1,15 +1,20 @@ using Sif.Framework.Demo.Au.Provider.Models; +using Sif.Framework.Model.Settings; using Sif.Framework.Service.Registration; using Sif.Framework.Service.Serialisation; +using Sif.Framework.Settings; using Sif.Framework.Utils; using Sif.Framework.WebApi; using Sif.Framework.WebApi.MediaTypeFormatters; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http.Formatting; using System.Web.Http; using System.Web.Http.ExceptionHandling; using System.Xml.Serialization; +using Tardigrade.Framework.Configurations; +using Tardigrade.Framework.EntityFramework.Configurations; namespace Sif.Framework.Demo.Au.Provider { @@ -21,6 +26,8 @@ protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); + IFrameworkSettings settings = GetSettings(); + // URL Postfix Extension: Update the configuration to recognise postfix extensions and map known // extensions to MIME Types. Additional changes to WebApiConfig.cs are required to fully enable this // feature. @@ -36,19 +43,19 @@ protected void Application_Start() // XML Serialisation: For each SIF Data Model Object used by each SIF Provider, the following entries are // required to define the root element for each collection object. var schoolInfosXmlRootAttribute = new XmlRootAttribute("SchoolInfos") - { Namespace = SettingsManager.ProviderSettings.DataModelNamespace, IsNullable = false }; + { Namespace = settings.DataModelNamespace, IsNullable = false }; ISerialiser> schoolInfosSerialiser = SerialiserFactory.GetXmlSerialiser>(schoolInfosXmlRootAttribute); xmlFormatter.SetSerializer>((XmlSerializer)schoolInfosSerialiser); var studentPersonalsXmlRootAttribute = new XmlRootAttribute("StudentPersonals") - { Namespace = SettingsManager.ProviderSettings.DataModelNamespace, IsNullable = false }; + { Namespace = settings.DataModelNamespace, IsNullable = false }; ISerialiser> studentPersonalsSerialiser = SerialiserFactory.GetXmlSerialiser>(studentPersonalsXmlRootAttribute); xmlFormatter.SetSerializer>((XmlSerializer)studentPersonalsSerialiser); var studentSchoolEnrollmentsXmlRootAttribute = new XmlRootAttribute("StudentSchoolEnrollments") - { Namespace = SettingsManager.ProviderSettings.DataModelNamespace, IsNullable = false }; + { Namespace = settings.DataModelNamespace, IsNullable = false }; ISerialiser> studentSchoolEnrollmentsSerialiser = SerialiserFactory.GetXmlSerialiser>( studentSchoolEnrollmentsXmlRootAttribute); @@ -68,14 +75,14 @@ protected void Application_Start() // Alternative 1. //var xmlRootAttribute = new XmlRootAttribute("StudentPersonals") - //{ Namespace = SettingsManager.ProviderSettings.DataModelNamespace, IsNullable = false }; + //{ Namespace = settings.DataModelNamespace, IsNullable = false }; //xmlFormatter.SetSerializer>( // new XmlSerializer(typeof(List), xmlRootAttribute)); // Alternative 2. //var attributes = new XmlAttributes(); //attributes.XmlRoot = new XmlRootAttribute("StudentPersonals") - //{ Namespace = SettingsManager.ProviderSettings.DataModelNamespace, IsNullable = false }; + //{ Namespace = settings.DataModelNamespace, IsNullable = false }; //var overrides = new XmlAttributeOverrides(); //overrides.Add(typeof(List), attributes); //xmlFormatter @@ -89,23 +96,44 @@ protected void Application_Start() .Replace(typeof(IExceptionHandler), new GlobalUnexpectedExceptionHandler()); Trace.TraceInformation("********** Application_Start **********"); - Register(); + Register(settings); } - protected void Application_End(object sender, System.EventArgs e) + protected void Application_End(object sender, EventArgs e) { Trace.TraceInformation("********** Application_End **********"); Unregister(); } + private IFrameworkSettings GetSettings() + { + IFrameworkSettings settings; + string settingsSource = System.Configuration.ConfigurationManager.AppSettings["demo.settingsSource"]; + + if ("Database".Equals(settingsSource, StringComparison.InvariantCultureIgnoreCase)) + { + settings = new ProviderSettings(new ApplicationConfiguration(new AppSettingsConfigurationSource("name=SettingsDb"))); + } + else if ("File".Equals(settingsSource, StringComparison.InvariantCultureIgnoreCase)) + { + settings = SettingsManager.ProviderSettings; + } + else + { + settings = SettingsManager.ProviderSettings; + } + + return settings; + } + /// /// Register this SIF Provider with the EnvironmentProvider based upon settings defined in the SIF 3.0 /// Framework configuration, e.g. SifFramework.config. /// - private void Register() + private void Register(IFrameworkSettings settings) { registrationService = RegistrationManager.GetProviderRegistrationService( - SettingsManager.ProviderSettings, + settings, SessionsManager.ProviderSessionService); registrationService.Register(); } diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Sif.Framework.Demo.Au.Provider.csproj b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Sif.Framework.Demo.Au.Provider.csproj index f13168ce..f9423a1c 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Sif.Framework.Demo.Au.Provider.csproj +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/Sif.Framework.Demo.Au.Provider.csproj @@ -1,5 +1,6 @@  + Debug @@ -53,13 +54,55 @@ ..\packages\AutoMapper.10.1.1\lib\net461\AutoMapper.dll + + ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + ..\packages\Iesi.Collections.4.0.4\lib\net461\Iesi.Collections.dll ..\packages\log4net.2.0.12\lib\net45\log4net.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Microsoft.Extensions.Configuration.5.0.0\lib\net461\Microsoft.Extensions.Configuration.dll + + + ..\packages\Microsoft.Extensions.Configuration.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.5.0.0\lib\net461\Microsoft.Extensions.Configuration.EnvironmentVariables.dll + + + ..\packages\Microsoft.Extensions.Configuration.FileExtensions.5.0.0\lib\net461\Microsoft.Extensions.Configuration.FileExtensions.dll + + + ..\packages\Microsoft.Extensions.Configuration.Json.5.0.0\lib\net461\Microsoft.Extensions.Configuration.Json.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.5.0.1\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\packages\Microsoft.Extensions.FileProviders.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.FileProviders.Abstractions.dll + + + ..\packages\Microsoft.Extensions.FileProviders.Physical.5.0.0\lib\net461\Microsoft.Extensions.FileProviders.Physical.dll + + + ..\packages\Microsoft.Extensions.FileSystemGlobbing.5.0.0\lib\net461\Microsoft.Extensions.FileSystemGlobbing.dll + + + ..\packages\Microsoft.Extensions.Primitives.5.0.0\lib\net461\Microsoft.Extensions.Primitives.dll + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll @@ -84,16 +127,76 @@ ..\packages\slf4net.log4net.1.1.0\lib\net40\slf4net.log4net.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\packages\System.ComponentModel.Annotations.5.0.0\lib\net461\System.ComponentModel.Annotations.dll + + + ..\packages\System.Configuration.ConfigurationManager.5.0.0\lib\net461\System.Configuration.ConfigurationManager.dll + + ..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.113.3\lib\net46\System.Data.SQLite.dll + + ..\packages\System.Data.SQLite.EF6.1.0.113.0\lib\net46\System.Data.SQLite.EF6.dll + + + ..\packages\System.Data.SQLite.Linq.1.0.113.0\lib\net46\System.Data.SQLite.Linq.dll + + + ..\packages\System.Linq.Dynamic.Core.1.2.6\lib\net46\System.Linq.Dynamic.Core.dll + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\packages\System.Security.AccessControl.5.0.0\lib\net461\System.Security.AccessControl.dll + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\packages\System.Security.Permissions.5.0.0\lib\net461\System.Security.Permissions.dll + + + ..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll + + + + ..\packages\System.Text.Encodings.Web.5.0.0\lib\net461\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.5.0.0\lib\net461\System.Text.Json.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll @@ -118,6 +221,7 @@ + @@ -152,6 +256,9 @@ Always + + PreserveNewest + Designer PreserveNewest @@ -163,10 +270,16 @@ Web.config + - - - + + {a34e197f-c68d-473d-85a5-6f81c7c01582} + Tardigrade.Framework.EntityFramework + + + {951c9c09-16fc-4aa9-bb59-9fda374c6cbd} + Tardigrade.Framework + {3682c668-02cd-40d5-867d-f019c116bddb} Sif.Framework @@ -197,13 +310,16 @@ - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/packages.config b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/packages.config index 18ea19ef..851019b5 100644 --- a/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/packages.config +++ b/Code/Sif3FrameworkDemo/Sif.Framework.Demo.Au.Provider/packages.config @@ -50,4 +50,6 @@ + + \ No newline at end of file diff --git a/Code/Sif3FrameworkDemo/Sif3FrameworkDemo.sln b/Code/Sif3FrameworkDemo/Sif3FrameworkDemo.sln index 577c0132..8bea673d 100644 --- a/Code/Sif3FrameworkDemo/Sif3FrameworkDemo.sln +++ b/Code/Sif3FrameworkDemo/Sif3FrameworkDemo.sln @@ -23,10 +23,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sif.Framework.Demo.Broker", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sif.Framework", "..\Sif3Framework\Sif.Framework\Sif.Framework.csproj", "{3682C668-02CD-40D5-867D-F019C116BDDB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tardigrade.Framework", "..\..\..\tardigrade-framework\Code\Tardigrade.Framework\Tardigrade.Framework\Tardigrade.Framework.csproj", "{951C9C09-16FC-4AA9-BB59-9FDA374C6CBD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tardigrade.Framework.EntityFramework", "..\..\..\tardigrade-framework\Code\Tardigrade.Framework\Tardigrade.Framework.EntityFramework\Tardigrade.Framework.EntityFramework.csproj", "{A34E197F-C68D-473D-85A5-6F81C7C01582}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,14 +69,6 @@ Global {3682C668-02CD-40D5-867D-F019C116BDDB}.Debug|Any CPU.Build.0 = Debug|Any CPU {3682C668-02CD-40D5-867D-F019C116BDDB}.Release|Any CPU.ActiveCfg = Release|Any CPU {3682C668-02CD-40D5-867D-F019C116BDDB}.Release|Any CPU.Build.0 = Release|Any CPU - {951C9C09-16FC-4AA9-BB59-9FDA374C6CBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {951C9C09-16FC-4AA9-BB59-9FDA374C6CBD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {951C9C09-16FC-4AA9-BB59-9FDA374C6CBD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {951C9C09-16FC-4AA9-BB59-9FDA374C6CBD}.Release|Any CPU.Build.0 = Release|Any CPU - {A34E197F-C68D-473D-85A5-6F81C7C01582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A34E197F-C68D-473D-85A5-6F81C7C01582}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A34E197F-C68D-473D-85A5-6F81C7C01582}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A34E197F-C68D-473D-85A5-6F81C7C01582}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Data/Databases/SQLite/SifFrameworkDatabase.db b/Data/Databases/SQLite/SifFrameworkDatabase.db index 3722cbfdf1ae00225a1c82456981f2f180fefc77..038678ae9016b4bf75c3b142d68c4ddb4666c0da 100644 GIT binary patch delta 771 zcmZoT!P9VpXM(ige+CAIlR$g|h$|Qv*49nbF=qU~F~LS#K=pUYL&p z__cYBwhIS_=q8f{?s{~k%4}k6EIN#g=;BJOVyxK26dx}G*@tDnz2i2ZhlmLUaFB2$Ybj0YBqoJKF4f~E{dX&Ns&cI z9mB@WpZz6d7=1VM5S@ZS9SKd;6%p!Ybo zGior(F{xP^nwz908JX&un41{rnph-T>LwZ*rRbWQSQw?I7^kFIq$TPqPd3ce+g_~2 z*vr^v!nnHe0Aep72FdvXF-V;^5W54h xD-eU!xdAaqpAQgcLQ#(TPp9CNrLOd6!z28iu|7^EF!1=!f_d*qm1SOFp(0F3|u delta 772 zcmZoT!P9VpXM(g~6axdpNgzG}#1#w-YaUJ1F=mX~m|&wV5T={PeeLys&n*X)b@CV8 z`?-0IwhIS_=q8f{?s{~k%4}k6EIN#g=;BJOVyxK26dx}G*@tDnz2i2ZhlmLUaFB2$Ybj0YBqoJKF4f~E{dX&Ns&cI z9mB@WpZz6d7`-?1ZzC0|9l8k~bu0F0It{K1t;j{Vke_oAk28{Ad zY6eMWW=1KdX1b|KDQ3DRmT76aNhZmLx<xv?7|8FlcfUa diff --git a/Documentation/Backward incompatible changes.md b/Documentation/Backward incompatible changes.md index 7fd5c443..215af8f3 100644 --- a/Documentation/Backward incompatible changes.md +++ b/Documentation/Backward incompatible changes.md @@ -3,12 +3,13 @@ ### **3.2.1.14 -> 4.0.0** -- BasicConsumer constructors - - - Renamed the LegacyConfigurationProvider class to LegacySettingsConfigurationProvider. - - Renamed the LegacyConfigurationSource class to LegacySettingsConfigurationSource. - - Updated the signature of the ApplicationConfiguration constructor to accept multiple configuration sources. -- Tardigrade.Framework.AspNetCore - - Updated the project from supporting both .NET Core 2.2 and 3.0 to just 3.1. -- Tardigrade.Framework.EntityFrameworkCore - - Updated the project from .NET Core 3.0 to 3.1. +- The public Consumer(Environment) constructor has been made protected. +- The public BasicConsumer(Environment) constructor has been made protected. +- The public BasicEventConsumer(Environment) constructor has been made protected. +- The IBasicProvider interface has been removed. +- Extend the ObjectProvider class rather than the Provider class when creating SIF Providers whose TMultiple generic type is not a list of the TSingle generic type. +- Implement the IObjectProviderService interface rather than the IProviderService interface when creating SIF Provider services whose TMultiple generic type is not a list of the TSingle generic type. +- The empty default constructor of the abstract Provider class has been removed. +- The empty default constructor of the AuthorisationService class has been removed. +- The Sif.Framework project only targets .NET Standard 2.0, .NET Framework 4.7.2 and .NET Framework 4.6.1. It no longer targets .NET Frameworks 4.6.2, 4.7 and 4.7.1. +- The ConsumerRegistrationService and ProviderRegistrationService static properties of the static RegistrationManager class have been made obsolete. diff --git a/Documentation/Reading application settings from a database.md b/Documentation/Reading application settings from a database.md new file mode 100644 index 00000000..ce1435e8 --- /dev/null +++ b/Documentation/Reading application settings from a database.md @@ -0,0 +1,52 @@ +# Reading application settings from a database + +Both SIF Providers and Consumers now support the passing of SIF Framework application settings through a constructor parameter. This allows application settings to be read from any source and not just from the SifFramework.config file (which is used by default if no application settings are specified). This includes application settings stored in a database. + +## SIF Consumer + +The following modifications were required to allow the Demo AU Consumer to read appliations settings from a database: + +> 1. Installed the System.Data.SQLite NuGet package (not to be used for a production1system). +> 1. Installed the Tardigrade.Framework.EntityFramework NuGet package. +> 1. Added an SQLite database file where the application settings are stored in the AppSettings database table. Ensure that the `Build Action` is `None` and that the `Copy to Output Directory` is `Copy if newer`. An appropriate SQL script for the AppSettings databaes table can be found in the `Scripts\SQL\Application settings table` directory. +> 1. Configured the App.config file to support SQLite with EntityFramework 6, including defining the database file to be used. +> 1. Updated the Demo AU Consumers to implement the constructors that pass an IFrameworkSettings parameter. +> 1. In the ConsumerApp, read the application settings from the database and passed them to the constructor of the SIF Consumer (in this case, StudentPersonalConsumer). + +To read the application settings from a database, the following code is used: + +```cs +IFrameworkSettings settings = + new ConsumerSettings( + new ApplicationConfiguration( + new AppSettingsConfigurationSource("name=SettingsDb"))); +``` + +The AppSettingsConfigurationSource constructor takes a connection string name that has been configured in the App.config file. The database file is referenced by default from the `bin\Debug` directory with the `|DataDirectory|` substitution string. + +The AppSettingsConfigurationSource and ApplicationConfiguration classes are referenced from the Tardigrade.Framework.EntityFramework and Tardigrade.Framework NuGet packages respectively. + + +## SIF Provider + +The following modifications were required to allow the Demo AU Provider to read appliations settings from a database: + +> 1. Installed the System.Data.SQLite NuGet package (not to be used for a production1system). +> 1. Installed the Tardigrade.Framework.EntityFramework NuGet package. +> 1. Added an SQLite database file to the App_Data directory. The application settings are defined in the AppSettings database table. Ensure that the `Build Action` is `None` and that the `Copy to Output Directory` is `Copy if newer`. An appropriate SQL script for the AppSettings databaes table can be found in the `Scripts\SQL\Application settings table` directory. +> 1. Configured the Web.config file to support SQLite with EntityFramework 6, including defining the database file to be used. +> 1. Updated the Global.asax.cs file to read the application settings from the database and then passed them to the new `RegistrationManager.GetProviderRegistrationService(IFrameworkSettings, ISessionService)` method in the updated `Register(IFrameworkSettings)` method. All previous references to `SettingsManager.ProviderSettings` were replaced. +> 1. Updated the Demo AU Providers to implement the constructors that pass an IFrameworkSettings parameter. + +To read the application settings from a database, the following code is used: + +```cs +IFrameworkSettings settings = + new ProviderSettings( + new ApplicationConfiguration( + new AppSettingsConfigurationSource("name=SettingsDb"))); +``` + +The AppSettingsConfigurationSource constructor takes a connection string name that has been configured in the App.config file. The database file is referenced by default from the `App_Data` directory with the `|DataDirectory|` substitution string. + +The AppSettingsConfigurationSource and ApplicationConfiguration classes are referenced from the Tardigrade.Framework.EntityFramework and Tardigrade.Framework NuGet packages respectively. diff --git a/README.md b/README.md index eebf1952..c097607c 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,10 @@ See the [wiki associated with this repository](https://github.com/Access4Learnin ## Version control history -**Dec 28, 2020 - 4.0.0 Enable application settings to be read from a database** +**Dec 29, 2020 - 4.0.0 Enable application settings to be read from a database** - Added classes to enable application settings to be read from a database. +- Re-designed the Provider classes to better accommodate passing of application settings. - Updated the Consumer and Provider constructors to accept the application settings to be used. - Updated the business layer to reference the application settings passed rather than inherently read them from the SifFramework.config file. - Create a Solution to manage unit test projects. From efc8386749ec6da5a2acf8a96a653490f7425038 Mon Sep 17 00:00:00 2001 From: rafidzal Date: Tue, 29 Dec 2020 16:51:29 +0800 Subject: [PATCH 15/16] Include recently updated third-party NuGet packages. --- .../Sif.Framework.EntityFramework.Tests.csproj | 2 +- .../Sif.Framework.EnvironmentProvider/Web.config | 2 +- .../Sif.Framework.EnvironmentProvider/packages.config | 2 +- Code/Sif3Framework/Sif.Framework.Tests/packages.config | 2 +- .../Sif.Framework.Demo.Au.Consumer.csproj | 2 +- .../Sif.Framework.Demo.Au.Provider.csproj | 4 ++-- .../Sif.Framework.Demo.Au.Provider/packages.config | 6 +++--- .../Sif.Framework.Demo.Broker/packages.config | 2 +- .../Sif.Framework.Demo.Setup/packages.config | 2 +- .../Sif.Framework.Demo.Uk.Provider/packages.config | 2 +- .../Sif.Framework.Demo.Us.Provider/packages.config | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj index 2a362189..56d43b4a 100644 --- a/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj +++ b/Code/Sif.Framework.Tests/Sif.Framework.EntityFramework.Tests/Sif.Framework.EntityFramework.Tests.csproj @@ -49,7 +49,7 @@ 5.0.0 - 1.0.113.6 + 1.0.113.7 11.1.0 diff --git a/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Web.config b/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Web.config index 997a6eee..ce57c6ab 100644 --- a/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Web.config +++ b/Code/Sif3Framework/Sif.Framework.EnvironmentProvider/Web.config @@ -1,4 +1,4 @@ - +