2019-06-06 15:44:03 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-06-18 10:18:56 +02:00
|
|
|
|
using System;
|
|
|
|
|
using SafeExamBrowser.Contracts.Communication.Events;
|
2019-06-07 15:26:03 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Communication.Hosts;
|
2019-06-11 09:53:33 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Configuration;
|
2019-06-07 15:26:03 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Core.OperationModel;
|
2019-06-18 10:18:56 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Logging;
|
2019-06-06 15:44:03 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Service;
|
|
|
|
|
|
|
|
|
|
namespace SafeExamBrowser.Service
|
|
|
|
|
{
|
|
|
|
|
internal class ServiceController : IServiceController
|
|
|
|
|
{
|
2019-06-18 10:18:56 +02:00
|
|
|
|
private readonly ILogger logger;
|
2019-06-07 15:26:03 +02:00
|
|
|
|
private IOperationSequence bootstrapSequence;
|
2019-06-18 10:18:56 +02:00
|
|
|
|
private IOperationSequence sessionSequence;
|
2019-06-07 15:26:03 +02:00
|
|
|
|
private IServiceHost serviceHost;
|
|
|
|
|
private SessionContext sessionContext;
|
|
|
|
|
|
2019-06-11 09:53:33 +02:00
|
|
|
|
private ServiceConfiguration Session
|
2019-06-07 15:26:03 +02:00
|
|
|
|
{
|
2019-06-18 10:18:56 +02:00
|
|
|
|
get { return sessionContext.Configuration; }
|
2019-06-07 15:26:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool SessionIsRunning
|
|
|
|
|
{
|
|
|
|
|
get { return Session != null; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ServiceController(
|
2019-06-18 10:18:56 +02:00
|
|
|
|
ILogger logger,
|
2019-06-07 15:26:03 +02:00
|
|
|
|
IOperationSequence bootstrapSequence,
|
2019-06-18 10:18:56 +02:00
|
|
|
|
IOperationSequence sessionSequence,
|
2019-06-07 15:26:03 +02:00
|
|
|
|
IServiceHost serviceHost,
|
|
|
|
|
SessionContext sessionContext)
|
|
|
|
|
{
|
2019-06-18 10:18:56 +02:00
|
|
|
|
this.logger = logger;
|
2019-06-07 15:26:03 +02:00
|
|
|
|
this.bootstrapSequence = bootstrapSequence;
|
|
|
|
|
this.sessionSequence = sessionSequence;
|
|
|
|
|
this.serviceHost = serviceHost;
|
|
|
|
|
this.sessionContext = sessionContext;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-06 15:44:03 +02:00
|
|
|
|
public bool TryStart()
|
|
|
|
|
{
|
2019-06-18 10:18:56 +02:00
|
|
|
|
logger.Info("Initiating startup procedure...");
|
|
|
|
|
|
2019-06-07 15:26:03 +02:00
|
|
|
|
var result = bootstrapSequence.TryPerform();
|
|
|
|
|
var success = result == OperationResult.Success;
|
|
|
|
|
|
2019-06-18 10:18:56 +02:00
|
|
|
|
if (success)
|
|
|
|
|
{
|
|
|
|
|
RegisterEvents();
|
|
|
|
|
|
|
|
|
|
logger.Info("Service successfully initialized.");
|
|
|
|
|
logger.Log(string.Empty);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Service startup aborted!");
|
|
|
|
|
logger.Log(string.Empty);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-07 15:26:03 +02:00
|
|
|
|
return success;
|
2019-06-06 15:44:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Terminate()
|
|
|
|
|
{
|
2019-06-18 10:18:56 +02:00
|
|
|
|
DeregisterEvents();
|
|
|
|
|
|
2019-06-07 15:26:03 +02:00
|
|
|
|
if (SessionIsRunning)
|
|
|
|
|
{
|
2019-06-18 10:18:56 +02:00
|
|
|
|
StopSession();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Log(string.Empty);
|
|
|
|
|
logger.Info("Initiating termination procedure...");
|
|
|
|
|
|
|
|
|
|
var result = bootstrapSequence.TryRevert();
|
|
|
|
|
var success = result == OperationResult.Success;
|
|
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Service successfully terminated.");
|
|
|
|
|
logger.Log(string.Empty);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Service termination failed!");
|
|
|
|
|
logger.Log(string.Empty);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StartSession()
|
|
|
|
|
{
|
|
|
|
|
logger.Info(AppendDivider("Session Start Procedure"));
|
|
|
|
|
|
|
|
|
|
var result = sessionSequence.TryPerform();
|
|
|
|
|
|
|
|
|
|
if (result == OperationResult.Success)
|
|
|
|
|
{
|
|
|
|
|
logger.Info(AppendDivider("Session Running"));
|
2019-06-07 15:26:03 +02:00
|
|
|
|
}
|
2019-06-18 10:18:56 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Info(AppendDivider("Session Start Failed"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StopSession()
|
|
|
|
|
{
|
|
|
|
|
logger.Info(AppendDivider("Session Stop Procedure"));
|
|
|
|
|
|
|
|
|
|
var result = sessionSequence.TryRevert();
|
|
|
|
|
|
|
|
|
|
if (result == OperationResult.Success)
|
|
|
|
|
{
|
|
|
|
|
logger.Info(AppendDivider("Session Terminated"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Info(AppendDivider("Session Stop Failed"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RegisterEvents()
|
|
|
|
|
{
|
|
|
|
|
serviceHost.SessionStartRequested += ServiceHost_SessionStartRequested;
|
|
|
|
|
serviceHost.SessionStopRequested += ServiceHost_SessionStopRequested;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DeregisterEvents()
|
|
|
|
|
{
|
|
|
|
|
serviceHost.SessionStartRequested -= ServiceHost_SessionStartRequested;
|
|
|
|
|
serviceHost.SessionStopRequested -= ServiceHost_SessionStopRequested;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ServiceHost_SessionStartRequested(SessionStartEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
if (!SessionIsRunning)
|
|
|
|
|
{
|
|
|
|
|
sessionContext.Configuration = args.Configuration;
|
|
|
|
|
|
|
|
|
|
StartSession();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Warn("Received session start request, even though a session is already running!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ServiceHost_SessionStopRequested(SessionStopEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
if (SessionIsRunning)
|
|
|
|
|
{
|
2019-06-19 15:40:21 +02:00
|
|
|
|
if (Session.SessionId == args.SessionId)
|
|
|
|
|
{
|
|
|
|
|
StopSession();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Warn("Received session stop request with wrong session ID!");
|
|
|
|
|
}
|
2019-06-18 10:18:56 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Warn("Received session stop request, even though no session is currently running!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string AppendDivider(string message)
|
|
|
|
|
{
|
|
|
|
|
var dashesLeft = new String('-', 48 - message.Length / 2 - message.Length % 2);
|
|
|
|
|
var dashesRight = new String('-', 48 - message.Length / 2);
|
2019-06-07 15:26:03 +02:00
|
|
|
|
|
2019-06-18 10:18:56 +02:00
|
|
|
|
return $"### {dashesLeft} {message} {dashesRight} ###";
|
2019-06-06 15:44:03 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|