SEBWIN-301: Changed service procedure so that the service initiates a system configuration update on command from the runtime. Added functionality to terminate the application on service connection loss.
This commit is contained in:
parent
39b63218fb
commit
6f0b0d0fb2
21 changed files with 327 additions and 126 deletions
|
@ -18,7 +18,7 @@ namespace SafeExamBrowser.Client.Communication
|
|||
{
|
||||
internal class ClientHost : BaseHost, IClientHost
|
||||
{
|
||||
private bool allowConnection = true;
|
||||
private bool allowConnection;
|
||||
private int processId;
|
||||
|
||||
public Guid AuthenticationToken { private get; set; }
|
||||
|
@ -37,6 +37,7 @@ namespace SafeExamBrowser.Client.Communication
|
|||
int processId,
|
||||
int timeout_ms) : base(address, factory, logger, timeout_ms)
|
||||
{
|
||||
this.allowConnection = true;
|
||||
this.processId = processId;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Communication.Data;
|
||||
using SafeExamBrowser.Contracts.Communication.Proxies;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Communication.Proxies;
|
||||
using SafeExamBrowser.Contracts.Communication;
|
||||
using SafeExamBrowser.Contracts.Communication.Data;
|
||||
using SafeExamBrowser.Contracts.Communication.Proxies;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
namespace SafeExamBrowser.Communication.UnitTests.Proxies
|
||||
{
|
||||
|
@ -39,18 +39,19 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies
|
|||
proxyObjectFactory = new Mock<IProxyObjectFactory>();
|
||||
proxy = new Mock<IProxyObject>();
|
||||
|
||||
proxy.Setup(p => p.Connect(It.IsAny<Guid>())).Returns(response);
|
||||
proxy.Setup(o => o.State).Returns(CommunicationState.Opened);
|
||||
proxy.Setup(p => p.Connect(null)).Returns(response);
|
||||
proxy.Setup(o => o.State).Returns(System.ServiceModel.CommunicationState.Opened);
|
||||
proxyObjectFactory.Setup(f => f.CreateObject(It.IsAny<string>())).Returns(proxy.Object);
|
||||
|
||||
sut = new ServiceProxy("net.pipe://random/address/here", proxyObjectFactory.Object, logger.Object, default(Interlocutor));
|
||||
sut.Connect();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustIgnoreConnectIfUnavailable()
|
||||
{
|
||||
sut.Ignore = true;
|
||||
sut.Connect(Guid.NewGuid());
|
||||
sut.Connect();
|
||||
|
||||
proxy.Verify(p => p.Connect(It.IsAny<Guid>()), Times.Never);
|
||||
}
|
||||
|
@ -64,6 +65,61 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies
|
|||
proxy.Verify(p => p.Disconnect(It.IsAny<DisconnectionMessage>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlySendSystemConfigurationUpdate()
|
||||
{
|
||||
proxy.Setup(p => p.Send(It.Is<SimpleMessage>(m => m.Purport == SimpleMessagePurport.UpdateSystemConfiguration))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
|
||||
|
||||
var communication = sut.RunSystemConfigurationUpdate();
|
||||
|
||||
proxy.Verify(p => p.Send(It.Is<SimpleMessage>(m => m.Purport == SimpleMessagePurport.UpdateSystemConfiguration)), Times.Once);
|
||||
|
||||
Assert.IsTrue(communication.Success);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustFailIfSystemConfigurationUpdateNotAcknowledged()
|
||||
{
|
||||
proxy.Setup(p => p.Send(It.Is<SimpleMessage>(m => m.Purport == SimpleMessagePurport.UpdateSystemConfiguration))).Returns<Response>(null);
|
||||
|
||||
var communication = sut.RunSystemConfigurationUpdate();
|
||||
|
||||
Assert.IsFalse(communication.Success);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustIgnoreSystemConfigurationUpdateIfUnavailable()
|
||||
{
|
||||
sut.Ignore = true;
|
||||
sut.RunSystemConfigurationUpdate();
|
||||
|
||||
proxy.Verify(p => p.Send(It.IsAny<Message>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlyStartSession()
|
||||
{
|
||||
var configuration = new ServiceConfiguration { SessionId = Guid.NewGuid() };
|
||||
|
||||
proxy.Setup(p => p.Send(It.IsAny<SessionStartMessage>())).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
|
||||
|
||||
var communication = sut.StartSession(configuration);
|
||||
|
||||
proxy.Verify(p => p.Send(It.Is<SessionStartMessage>(m => m.Configuration.SessionId == configuration.SessionId)), Times.Once);
|
||||
|
||||
Assert.IsTrue(communication.Success);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustFailIfSessionStartNotAcknowledged()
|
||||
{
|
||||
proxy.Setup(p => p.Send(It.IsAny<SessionStartMessage>())).Returns<Response>(null);
|
||||
|
||||
var communication = sut.StartSession(new ServiceConfiguration());
|
||||
|
||||
Assert.IsFalse(communication.Success);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustIgnoreStartSessionIfUnavaiable()
|
||||
{
|
||||
|
@ -75,6 +131,30 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies
|
|||
proxy.Verify(p => p.Send(It.IsAny<Message>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlyStopSession()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
|
||||
proxy.Setup(p => p.Send(It.IsAny<SessionStopMessage>())).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
|
||||
|
||||
var communication = sut.StopSession(sessionId);
|
||||
|
||||
proxy.Verify(p => p.Send(It.Is<SessionStopMessage>(m => m.SessionId == sessionId)), Times.Once);
|
||||
|
||||
Assert.IsTrue(communication.Success);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustFailIfSessionStopNotAcknowledged()
|
||||
{
|
||||
proxy.Setup(p => p.Send(It.IsAny<SessionStopMessage>())).Returns<Response>(null);
|
||||
|
||||
var communication = sut.StopSession(Guid.Empty);
|
||||
|
||||
Assert.IsFalse(communication.Success);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustIgnoreStopSessionIfUnavaiable()
|
||||
{
|
||||
|
|
|
@ -46,6 +46,37 @@ namespace SafeExamBrowser.Communication.Proxies
|
|||
return base.Disconnect();
|
||||
}
|
||||
|
||||
public CommunicationResult RunSystemConfigurationUpdate()
|
||||
{
|
||||
if (IgnoreOperation(nameof(RunSystemConfigurationUpdate)))
|
||||
{
|
||||
return new CommunicationResult(true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var response = Send(SimpleMessagePurport.UpdateSystemConfiguration);
|
||||
var success = IsAcknowledged(response);
|
||||
|
||||
if (success)
|
||||
{
|
||||
Logger.Debug("Service acknowledged system configuration update.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error($"Service did not acknowledge system configuration update! Received: {ToString(response)}.");
|
||||
}
|
||||
|
||||
return new CommunicationResult(success);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Failed to perform '{nameof(RunSystemConfigurationUpdate)}'", e);
|
||||
|
||||
return new CommunicationResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
public CommunicationResult StartSession(ServiceConfiguration configuration)
|
||||
{
|
||||
if (IgnoreOperation(nameof(StartSession)))
|
||||
|
|
|
@ -44,6 +44,11 @@ namespace SafeExamBrowser.Contracts.Communication.Data
|
|||
/// <summary>
|
||||
/// Sent form the runtime to the client to command the latter to shut itself down.
|
||||
/// </summary>
|
||||
Shutdown
|
||||
Shutdown,
|
||||
|
||||
/// <summary>
|
||||
/// Sent from the runtime to the service to command the latter to update the system configuration.
|
||||
/// </summary>
|
||||
UpdateSystemConfiguration
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,6 @@ namespace SafeExamBrowser.Contracts.Communication.Hosts
|
|||
/// </summary>
|
||||
public interface IServiceHost : ICommunicationHost
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether another application component may establish a connection with the host.
|
||||
/// </summary>
|
||||
bool AllowConnection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the runtime requested to start a new session.
|
||||
/// </summary>
|
||||
|
@ -29,5 +24,10 @@ namespace SafeExamBrowser.Contracts.Communication.Hosts
|
|||
/// Event fired when the runtime requested to stop a running session.
|
||||
/// </summary>
|
||||
event CommunicationEventHandler<SessionStopEventArgs> SessionStopRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the runtime requested to update the system configuration.
|
||||
/// </summary>
|
||||
event CommunicationEventHandler SystemConfigurationUpdateRequested;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies
|
|||
/// </summary>
|
||||
bool Ignore { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Instructs the service to start a system configuration update.
|
||||
/// </summary>
|
||||
CommunicationResult RunSystemConfigurationUpdate();
|
||||
|
||||
/// <summary>
|
||||
/// Instructs the service to start a new session according to the given configuration.
|
||||
/// </summary>
|
||||
|
|
|
@ -91,7 +91,6 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
OperationStatus_StopWindowMonitoring,
|
||||
OperationStatus_TerminateBrowser,
|
||||
OperationStatus_TerminateShell,
|
||||
OperationStatus_UpdateSystemConfiguration,
|
||||
OperationStatus_WaitExplorerStartup,
|
||||
OperationStatus_WaitExplorerTermination,
|
||||
OperationStatus_WaitRuntimeDisconnection,
|
||||
|
|
|
@ -231,9 +231,6 @@
|
|||
<Entry key="OperationStatus_TerminateShell">
|
||||
Terminating user interface
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_UpdateSystemConfiguration">
|
||||
Updating system configuration
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_WaitExplorerStartup">
|
||||
Waiting for Windows explorer to start up
|
||||
</Entry>
|
||||
|
|
|
@ -15,7 +15,6 @@ using SafeExamBrowser.Contracts.Communication.Proxies;
|
|||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Lockdown;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.SystemComponents;
|
||||
using SafeExamBrowser.Contracts.UserInterface.MessageBox;
|
||||
|
@ -35,7 +34,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
private Settings settings;
|
||||
private Mock<ISystemConfigurationUpdate> systemConfigurationUpdate;
|
||||
private Mock<IUserInfo> userInfo;
|
||||
private ServiceOperation sut;
|
||||
|
||||
|
@ -52,7 +50,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
settings = new Settings();
|
||||
systemConfigurationUpdate = new Mock<ISystemConfigurationUpdate>();
|
||||
userInfo = new Mock<IUserInfo>();
|
||||
|
||||
appConfig.ServiceEventName = serviceEventName;
|
||||
|
@ -63,7 +60,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
session.Settings = settings;
|
||||
settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, systemConfigurationUpdate.Object, 0, userInfo.Object);
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, 0, userInfo.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -92,7 +89,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
systemConfigurationUpdate.Verify(u => u.Execute(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
userInfo.Verify(u => u.GetUserName(), Times.Once);
|
||||
userInfo.Verify(u => u.GetUserSid(), Times.Once);
|
||||
|
||||
|
@ -125,7 +122,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true));
|
||||
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, systemConfigurationUpdate.Object, TIMEOUT, userInfo.Object);
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, TIMEOUT, userInfo.Object);
|
||||
|
||||
before = DateTime.Now;
|
||||
var result = sut.Perform();
|
||||
|
@ -158,7 +155,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
systemConfigurationUpdate.Verify(u => u.Execute(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
@ -213,7 +209,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
PerformNormally();
|
||||
systemConfigurationUpdate.Reset();
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
|
@ -221,7 +216,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Exactly(2));
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
systemConfigurationUpdate.Verify(u => u.Execute(), Times.Exactly(2));
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
@ -268,7 +263,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var before = default(DateTime);
|
||||
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true));
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, systemConfigurationUpdate.Object, TIMEOUT, userInfo.Object);
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, TIMEOUT, userInfo.Object);
|
||||
|
||||
PerformNormally();
|
||||
|
||||
|
@ -288,6 +283,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
service.Setup(s => s.Disconnect()).Returns(true);
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(true));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
|
@ -303,14 +299,15 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
service.Setup(s => s.Disconnect()).Returns(true);
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(true));
|
||||
|
||||
PerformNormally();
|
||||
systemConfigurationUpdate.Reset();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
systemConfigurationUpdate.Verify(u => u.Execute(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
@ -319,14 +316,31 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
public void Revert_MustHandleCommunicationFailureWhenStoppingSession()
|
||||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(false));
|
||||
|
||||
PerformNormally();
|
||||
systemConfigurationUpdate.Reset();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
systemConfigurationUpdate.Verify(u => u.Execute(), Times.Never);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustHandleCommunicationFailureWhenInitiatingSystemConfigurationUpdate()
|
||||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(false));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
@ -340,6 +354,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
|
@ -352,7 +368,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var before = default(DateTime);
|
||||
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true));
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, systemConfigurationUpdate.Object, TIMEOUT, userInfo.Object);
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, TIMEOUT, userInfo.Object);
|
||||
|
||||
PerformNormally();
|
||||
|
||||
|
@ -362,6 +378,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(after - before >= new TimeSpan(0, 0, 0, 0, TIMEOUT));
|
||||
|
|
|
@ -389,6 +389,42 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
runtimeWindow.Verify(s => s.UpdateStatus(It.Is<TextKey>(k => k == key), It.IsAny<bool>()), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ServiceProxy_MustShutdownWhenConnectionLostAndMandatory()
|
||||
{
|
||||
currentSettings.Service.Policy = ServicePolicy.Mandatory;
|
||||
|
||||
StartSession();
|
||||
service.Raise(c => c.ConnectionLost += null);
|
||||
|
||||
messageBox.Verify(m => m.Show(
|
||||
It.IsAny<TextKey>(),
|
||||
It.IsAny<TextKey>(),
|
||||
It.IsAny<MessageBoxAction>(),
|
||||
It.Is<MessageBoxIcon>(i => i == MessageBoxIcon.Error),
|
||||
It.IsAny<IWindow>()), Times.Once);
|
||||
sessionSequence.Verify(s => s.TryRevert(), Times.Once);
|
||||
shutdown.Verify(s => s(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ServiceProxy_MustNotShutdownWhenConnectionLostAndNotMandatory()
|
||||
{
|
||||
currentSettings.Service.Policy = ServicePolicy.Optional;
|
||||
|
||||
StartSession();
|
||||
service.Raise(c => c.ConnectionLost += null);
|
||||
|
||||
messageBox.Verify(m => m.Show(
|
||||
It.IsAny<TextKey>(),
|
||||
It.IsAny<TextKey>(),
|
||||
It.IsAny<MessageBoxAction>(),
|
||||
It.Is<MessageBoxIcon>(i => i == MessageBoxIcon.Error),
|
||||
It.IsAny<IWindow>()), Times.Never);
|
||||
sessionSequence.Verify(s => s.TryRevert(), Times.Never);
|
||||
shutdown.Verify(s => s(), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Shutdown_MustRevertSessionThenBootstrapSequence()
|
||||
{
|
||||
|
|
|
@ -27,7 +27,6 @@ using SafeExamBrowser.Contracts.SystemComponents;
|
|||
using SafeExamBrowser.Core.OperationModel;
|
||||
using SafeExamBrowser.Core.Operations;
|
||||
using SafeExamBrowser.I18n;
|
||||
using SafeExamBrowser.Lockdown;
|
||||
using SafeExamBrowser.Logging;
|
||||
using SafeExamBrowser.Runtime.Communication;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
|
@ -71,7 +70,6 @@ namespace SafeExamBrowser.Runtime
|
|||
var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, new HostObjectFactory(), ModuleLogger(nameof(RuntimeHost)), FIVE_SECONDS);
|
||||
var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), ModuleLogger(nameof(ServiceProxy)), Interlocutor.Runtime);
|
||||
var sessionContext = new SessionContext();
|
||||
var systemConfigurationUpdate = new SystemConfigurationUpdate(ModuleLogger(nameof(SystemConfigurationUpdate)));
|
||||
var uiFactory = new UserInterfaceFactory(text);
|
||||
var userInfo = new UserInfo();
|
||||
|
||||
|
@ -83,7 +81,7 @@ namespace SafeExamBrowser.Runtime
|
|||
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost, sessionContext));
|
||||
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new HashAlgorithm(), logger, sessionContext));
|
||||
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, systemConfigurationUpdate, THIRTY_SECONDS, userInfo));
|
||||
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, THIRTY_SECONDS, userInfo));
|
||||
sessionOperations.Enqueue(new ClientTerminationOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
|
||||
sessionOperations.Enqueue(new KioskModeOperation(desktopFactory, explorerShell, logger, processFactory, sessionContext));
|
||||
sessionOperations.Enqueue(new ClientOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
|
||||
|
|
|
@ -16,7 +16,6 @@ using SafeExamBrowser.Contracts.Configuration.Settings;
|
|||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Lockdown;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.SystemComponents;
|
||||
using SafeExamBrowser.Contracts.UserInterface.MessageBox;
|
||||
|
@ -29,7 +28,6 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
private ILogger logger;
|
||||
private IRuntimeHost runtimeHost;
|
||||
private IServiceProxy service;
|
||||
private ISystemConfigurationUpdate systemConfigurationUpdate;
|
||||
private int timeout_ms;
|
||||
private IUserInfo userInfo;
|
||||
|
||||
|
@ -41,14 +39,12 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
IRuntimeHost runtimeHost,
|
||||
IServiceProxy service,
|
||||
SessionContext sessionContext,
|
||||
ISystemConfigurationUpdate systemConfigurationUpdate,
|
||||
int timeout_ms,
|
||||
IUserInfo userInfo) : base(sessionContext)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.runtimeHost = runtimeHost;
|
||||
this.service = service;
|
||||
this.systemConfigurationUpdate = systemConfigurationUpdate;
|
||||
this.timeout_ms = timeout_ms;
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
|
@ -103,7 +99,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
{
|
||||
if (Context.Current != null)
|
||||
{
|
||||
success &= TryStopSession();
|
||||
success &= TryStopSession(true);
|
||||
}
|
||||
|
||||
success &= TryTerminateConnection();
|
||||
|
@ -192,21 +188,18 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
{
|
||||
logger.Error($"Failed to start new service session within {timeout_ms / 1000} seconds!");
|
||||
}
|
||||
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_UpdateSystemConfiguration);
|
||||
systemConfigurationUpdate.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to communicate session start to service!");
|
||||
logger.Error("Failed to communicate session start command to service!");
|
||||
}
|
||||
|
||||
return started;
|
||||
}
|
||||
|
||||
private bool TryStopSession()
|
||||
private bool TryStopSession(bool isFinalSession = false)
|
||||
{
|
||||
var stopped = false;
|
||||
var success = false;
|
||||
|
||||
logger.Info("Stopping current service session...");
|
||||
|
||||
|
@ -214,9 +207,9 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
|
||||
if (communication.Success)
|
||||
{
|
||||
stopped = TryWaitForServiceEvent(Context.Current.AppConfig.ServiceEventName);
|
||||
success = TryWaitForServiceEvent(Context.Current.AppConfig.ServiceEventName);
|
||||
|
||||
if (stopped)
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Successfully stopped service session.");
|
||||
}
|
||||
|
@ -224,16 +217,28 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
{
|
||||
logger.Error($"Failed to stop service session within {timeout_ms / 1000} seconds!");
|
||||
}
|
||||
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_UpdateSystemConfiguration);
|
||||
systemConfigurationUpdate.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to communicate session stop to service!");
|
||||
logger.Error("Failed to communicate session stop command to service!");
|
||||
}
|
||||
|
||||
return stopped;
|
||||
if (success && isFinalSession)
|
||||
{
|
||||
communication = service.RunSystemConfigurationUpdate();
|
||||
success = communication.Success;
|
||||
|
||||
if (communication.Success)
|
||||
{
|
||||
logger.Info("Instructed service to perform system configuration update.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to communicate system configuration update command to service!");
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private bool TryWaitForServiceEvent(string eventName)
|
||||
|
|
|
@ -260,6 +260,7 @@ namespace SafeExamBrowser.Runtime
|
|||
runtimeHost.ClientConfigurationNeeded += RuntimeHost_ClientConfigurationNeeded;
|
||||
runtimeHost.ReconfigurationRequested += RuntimeHost_ReconfigurationRequested;
|
||||
runtimeHost.ShutdownRequested += RuntimeHost_ShutdownRequested;
|
||||
service.ConnectionLost += ServiceProxy_ConnectionLost;
|
||||
}
|
||||
|
||||
private void DeregisterEvents()
|
||||
|
@ -267,6 +268,7 @@ namespace SafeExamBrowser.Runtime
|
|||
runtimeHost.ClientConfigurationNeeded -= RuntimeHost_ClientConfigurationNeeded;
|
||||
runtimeHost.ReconfigurationRequested -= RuntimeHost_ReconfigurationRequested;
|
||||
runtimeHost.ShutdownRequested -= RuntimeHost_ShutdownRequested;
|
||||
service.ConnectionLost -= ServiceProxy_ConnectionLost;
|
||||
}
|
||||
|
||||
private void RegisterSessionEvents()
|
||||
|
@ -358,6 +360,21 @@ namespace SafeExamBrowser.Runtime
|
|||
shutdown.Invoke();
|
||||
}
|
||||
|
||||
private void ServiceProxy_ConnectionLost()
|
||||
{
|
||||
if (SessionIsRunning && Session.Settings.Service.Policy == ServicePolicy.Mandatory)
|
||||
{
|
||||
logger.Error("Lost connection to the service component!");
|
||||
StopSession();
|
||||
messageBox.Show(TextKey.MessageBox_ApplicationError, TextKey.MessageBox_ApplicationErrorTitle, icon: MessageBoxIcon.Error, parent: runtimeWindow);
|
||||
shutdown.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn("Lost connection to the service component!");
|
||||
}
|
||||
}
|
||||
|
||||
private void SessionSequence_ActionRequired(ActionRequiredEventArgs args)
|
||||
{
|
||||
switch (args)
|
||||
|
|
|
@ -155,10 +155,6 @@
|
|||
<Project>{10c62628-8e6a-45aa-9d97-339b119ad21d}</Project>
|
||||
<Name>SafeExamBrowser.I18n</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Lockdown\SafeExamBrowser.Lockdown.csproj">
|
||||
<Project>{386b6042-3e12-4753-9fc6-c88ea4f97030}</Project>
|
||||
<Name>SafeExamBrowser.Lockdown</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Logging\SafeExamBrowser.Logging.csproj">
|
||||
<Project>{e107026c-2011-4552-a7d8-3a0d37881df6}</Project>
|
||||
<Name>SafeExamBrowser.Logging</Name>
|
||||
|
|
|
@ -48,7 +48,6 @@ namespace SafeExamBrowser.Service.UnitTests.Communication
|
|||
var response3 = sut.Connect();
|
||||
|
||||
Assert.IsTrue(response.ConnectionEstablished);
|
||||
Assert.IsFalse(sut.AllowConnection);
|
||||
Assert.IsFalse(response2.ConnectionEstablished);
|
||||
Assert.IsFalse(response3.ConnectionEstablished);
|
||||
}
|
||||
|
@ -59,15 +58,33 @@ namespace SafeExamBrowser.Service.UnitTests.Communication
|
|||
var connect = sut.Connect();
|
||||
var disconnect = sut.Disconnect(new DisconnectionMessage { CommunicationToken = connect.CommunicationToken.Value, Interlocutor = Interlocutor.Runtime });
|
||||
|
||||
Assert.IsTrue(sut.AllowConnection);
|
||||
Assert.IsTrue(disconnect.ConnectionTerminated);
|
||||
|
||||
var connect2 = sut.Connect();
|
||||
|
||||
Assert.IsFalse(sut.AllowConnection);
|
||||
Assert.IsTrue(connect2.ConnectionEstablished);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Send_MustHandleSystemConfigurationUpdate()
|
||||
{
|
||||
var sync = new AutoResetEvent(false);
|
||||
var systemConfigurationUpdateRequested = false;
|
||||
|
||||
sut.SystemConfigurationUpdateRequested += () => { systemConfigurationUpdateRequested = true; sync.Set(); };
|
||||
|
||||
var token = sut.Connect().CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.UpdateSystemConfiguration) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
sync.WaitOne();
|
||||
|
||||
Assert.IsTrue(systemConfigurationUpdateRequested);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Send_MustHandleSessionStartRequest()
|
||||
{
|
||||
|
|
|
@ -11,7 +11,6 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
|
@ -26,7 +25,6 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
|||
{
|
||||
private Mock<IAutoRestoreMechanism> autoRestoreMechanism;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IServiceHost> serviceHost;
|
||||
private Mock<Func<string, EventWaitHandle>> serviceEventFactory;
|
||||
private SessionContext sessionContext;
|
||||
private SessionInitializationOperation sut;
|
||||
|
@ -36,7 +34,6 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
|||
{
|
||||
autoRestoreMechanism = new Mock<IAutoRestoreMechanism>();
|
||||
logger = new Mock<ILogger>();
|
||||
serviceHost = new Mock<IServiceHost>();
|
||||
serviceEventFactory = new Mock<Func<string, EventWaitHandle>>();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
|
@ -48,17 +45,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
|||
Settings = new Settings()
|
||||
};
|
||||
|
||||
sut = new SessionInitializationOperation(logger.Object, serviceEventFactory.Object, serviceHost.Object, sessionContext);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustDisableNewConnections()
|
||||
{
|
||||
var result = sut.Perform();
|
||||
|
||||
serviceHost.VerifySet(h => h.AllowConnection = false, Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
sut = new SessionInitializationOperation(logger.Object, serviceEventFactory.Object, sessionContext);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -97,17 +84,6 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
|||
Assert.IsNull(sessionContext.Configuration);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustEnableNewConnections()
|
||||
{
|
||||
sessionContext.ServiceEvent = new EventStub();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
serviceHost.VerifySet(h => h.AllowConnection = true, Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustSetServiceEvent()
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Communication.Events;
|
||||
|
@ -14,6 +15,7 @@ using SafeExamBrowser.Contracts.Communication.Hosts;
|
|||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Lockdown;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
namespace SafeExamBrowser.Service.UnitTests
|
||||
|
@ -27,6 +29,7 @@ namespace SafeExamBrowser.Service.UnitTests
|
|||
private SessionContext sessionContext;
|
||||
private Mock<IOperationSequence> sessionSequence;
|
||||
private Mock<IServiceHost> serviceHost;
|
||||
private Mock<ISystemConfigurationUpdate> systemConfigurationUpdate;
|
||||
private ServiceController sut;
|
||||
|
||||
[TestInitialize]
|
||||
|
@ -38,10 +41,18 @@ namespace SafeExamBrowser.Service.UnitTests
|
|||
sessionContext = new SessionContext();
|
||||
sessionSequence = new Mock<IOperationSequence>();
|
||||
serviceHost = new Mock<IServiceHost>();
|
||||
systemConfigurationUpdate = new Mock<ISystemConfigurationUpdate>();
|
||||
|
||||
logWriterFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new Mock<ILogObserver>().Object);
|
||||
|
||||
sut = new ServiceController(logger.Object, logWriterFactory.Object, bootstrapSequence.Object, sessionSequence.Object, serviceHost.Object, sessionContext);
|
||||
sut = new ServiceController(
|
||||
logger.Object,
|
||||
logWriterFactory.Object,
|
||||
bootstrapSequence.Object,
|
||||
sessionSequence.Object,
|
||||
serviceHost.Object,
|
||||
sessionContext,
|
||||
systemConfigurationUpdate.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -160,6 +171,23 @@ namespace SafeExamBrowser.Service.UnitTests
|
|||
sessionSequence.Verify(s => s.TryRevert(), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Communication_MustStartSystemConfigurationUpdate()
|
||||
{
|
||||
var sync = new AutoResetEvent(false);
|
||||
|
||||
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
|
||||
systemConfigurationUpdate.Setup(u => u.ExecuteAsync()).Callback(() => sync.Set());
|
||||
|
||||
sut.TryStart();
|
||||
serviceHost.Raise(h => h.SystemConfigurationUpdateRequested += null);
|
||||
|
||||
sync.WaitOne();
|
||||
|
||||
systemConfigurationUpdate.Verify(u => u.Execute(), Times.Never);
|
||||
systemConfigurationUpdate.Verify(u => u.ExecuteAsync(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Start_MustOnlyPerformBootstrapSequence()
|
||||
{
|
||||
|
|
|
@ -18,47 +18,34 @@ namespace SafeExamBrowser.Service.Communication
|
|||
{
|
||||
internal class ServiceHost : BaseHost, IServiceHost
|
||||
{
|
||||
private readonly object @lock = new object();
|
||||
|
||||
private bool allowConnection;
|
||||
|
||||
public bool AllowConnection
|
||||
{
|
||||
get { lock (@lock) { return allowConnection; } }
|
||||
set { lock (@lock) { allowConnection = value; } }
|
||||
}
|
||||
|
||||
public event CommunicationEventHandler<SessionStartEventArgs> SessionStartRequested;
|
||||
public event CommunicationEventHandler<SessionStopEventArgs> SessionStopRequested;
|
||||
public event CommunicationEventHandler SystemConfigurationUpdateRequested;
|
||||
|
||||
internal ServiceHost(string address, IHostObjectFactory factory, ILogger logger, int timeout_ms) : base(address, factory, logger, timeout_ms)
|
||||
{
|
||||
AllowConnection = true;
|
||||
allowConnection = true;
|
||||
}
|
||||
|
||||
protected override bool OnConnect(Guid? token)
|
||||
{
|
||||
lock (@lock)
|
||||
var allow = allowConnection;
|
||||
|
||||
if (allow)
|
||||
{
|
||||
var allow = AllowConnection;
|
||||
|
||||
if (allow)
|
||||
{
|
||||
AllowConnection = false;
|
||||
}
|
||||
|
||||
return allow;
|
||||
allowConnection = false;
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
|
||||
protected override void OnDisconnect(Interlocutor interlocutor)
|
||||
{
|
||||
if (interlocutor == Interlocutor.Runtime)
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
AllowConnection = true;
|
||||
}
|
||||
allowConnection = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +66,13 @@ namespace SafeExamBrowser.Service.Communication
|
|||
|
||||
protected override Response OnReceive(SimpleMessagePurport message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case SimpleMessagePurport.UpdateSystemConfiguration:
|
||||
SystemConfigurationUpdateRequested?.InvokeAsync();
|
||||
return new SimpleResponse(SimpleResponsePurport.Acknowledged);
|
||||
}
|
||||
|
||||
return new SimpleResponse(SimpleResponsePurport.UnknownMessage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,14 +57,14 @@ namespace SafeExamBrowser.Service
|
|||
bootstrapOperations.Enqueue(new CommunicationHostOperation(serviceHost, logger));
|
||||
bootstrapOperations.Enqueue(new ServiceEventCleanupOperation(logger, sessionContext));
|
||||
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(logger, ServiceEventFactory, serviceHost, sessionContext));
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(logger, ServiceEventFactory, sessionContext));
|
||||
sessionOperations.Enqueue(new LockdownOperation(featureBackup, featureFactory, logger, sessionContext));
|
||||
sessionOperations.Enqueue(new SessionActivationOperation(logger, sessionContext));
|
||||
|
||||
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
|
||||
var sessionSequence = new OperationSequence(logger, sessionOperations);
|
||||
|
||||
ServiceController = new ServiceController(logger, LogWriterFactory, bootstrapSequence, sessionSequence, serviceHost, sessionContext);
|
||||
ServiceController = new ServiceController(logger, LogWriterFactory, bootstrapSequence, sessionSequence, serviceHost, sessionContext, systemConfigurationUpdate);
|
||||
}
|
||||
|
||||
private string BuildBackupFilePath()
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
|
@ -18,17 +17,11 @@ namespace SafeExamBrowser.Service.Operations
|
|||
{
|
||||
private ILogger logger;
|
||||
private Func<string, EventWaitHandle> serviceEventFactory;
|
||||
private IServiceHost serviceHost;
|
||||
|
||||
public SessionInitializationOperation(
|
||||
ILogger logger,
|
||||
Func<string, EventWaitHandle> serviceEventFactory,
|
||||
IServiceHost serviceHost,
|
||||
SessionContext sessionContext) : base(sessionContext)
|
||||
public SessionInitializationOperation(ILogger logger, Func<string, EventWaitHandle> serviceEventFactory, SessionContext sessionContext) : base(sessionContext)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.serviceEventFactory = serviceEventFactory;
|
||||
this.serviceHost = serviceHost;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
|
@ -41,9 +34,6 @@ namespace SafeExamBrowser.Service.Operations
|
|||
logger.Info("Stopping auto-restore mechanism...");
|
||||
Context.AutoRestoreMechanism.Stop();
|
||||
|
||||
logger.Info("Disabling service host...");
|
||||
serviceHost.AllowConnection = false;
|
||||
|
||||
InitializeServiceEvent();
|
||||
|
||||
return OperationResult.Success;
|
||||
|
@ -72,9 +62,6 @@ namespace SafeExamBrowser.Service.Operations
|
|||
logger.Info("Starting auto-restore mechanism...");
|
||||
Context.AutoRestoreMechanism.Start();
|
||||
|
||||
logger.Info("Enabling service host...");
|
||||
serviceHost.AllowConnection = true;
|
||||
|
||||
logger.Info("Clearing session data...");
|
||||
Context.Configuration = null;
|
||||
Context.IsRunning = false;
|
||||
|
|
|
@ -11,6 +11,7 @@ using SafeExamBrowser.Contracts.Communication.Events;
|
|||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Lockdown;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Service;
|
||||
|
||||
|
@ -24,6 +25,7 @@ namespace SafeExamBrowser.Service
|
|||
private IOperationSequence sessionSequence;
|
||||
private IServiceHost serviceHost;
|
||||
private SessionContext sessionContext;
|
||||
private ISystemConfigurationUpdate systemConfigurationUpdate;
|
||||
private ILogObserver sessionWriter;
|
||||
|
||||
private ServiceConfiguration Session
|
||||
|
@ -42,7 +44,8 @@ namespace SafeExamBrowser.Service
|
|||
IOperationSequence bootstrapSequence,
|
||||
IOperationSequence sessionSequence,
|
||||
IServiceHost serviceHost,
|
||||
SessionContext sessionContext)
|
||||
SessionContext sessionContext,
|
||||
ISystemConfigurationUpdate systemConfigurationUpdate)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.logWriterFactory = logWriterFactory;
|
||||
|
@ -50,6 +53,7 @@ namespace SafeExamBrowser.Service
|
|||
this.sessionSequence = sessionSequence;
|
||||
this.serviceHost = serviceHost;
|
||||
this.sessionContext = sessionContext;
|
||||
this.systemConfigurationUpdate = systemConfigurationUpdate;
|
||||
}
|
||||
|
||||
public bool TryStart()
|
||||
|
@ -141,12 +145,14 @@ namespace SafeExamBrowser.Service
|
|||
{
|
||||
serviceHost.SessionStartRequested += ServiceHost_SessionStartRequested;
|
||||
serviceHost.SessionStopRequested += ServiceHost_SessionStopRequested;
|
||||
serviceHost.SystemConfigurationUpdateRequested += ServiceHost_SystemConfigurationUpdateRequested;
|
||||
}
|
||||
|
||||
private void DeregisterEvents()
|
||||
{
|
||||
serviceHost.SessionStartRequested -= ServiceHost_SessionStartRequested;
|
||||
serviceHost.SessionStopRequested -= ServiceHost_SessionStopRequested;
|
||||
serviceHost.SystemConfigurationUpdateRequested -= ServiceHost_SystemConfigurationUpdateRequested;
|
||||
}
|
||||
|
||||
private void ServiceHost_SessionStartRequested(SessionStartEventArgs args)
|
||||
|
@ -182,6 +188,12 @@ namespace SafeExamBrowser.Service
|
|||
}
|
||||
}
|
||||
|
||||
private void ServiceHost_SystemConfigurationUpdateRequested()
|
||||
{
|
||||
logger.Info("Received request to initiate system configuration update.");
|
||||
systemConfigurationUpdate.ExecuteAsync();
|
||||
}
|
||||
|
||||
private string AppendDivider(string message)
|
||||
{
|
||||
var dashesLeft = new String('-', 48 - message.Length / 2 - message.Length % 2);
|
||||
|
|
Loading…
Reference in a new issue