Commit fe48c30b authored by Marcel Nellesen's avatar Marcel Nellesen
Browse files

Merge branch 'Product/917-maintenanceFunctionality' into 'Sprint/2021-06'

Product/917 maintenance functionality

See merge request !16
parents 9cd66aca 99190f95
using Coscine.Api.Notices.ReturnObjects;
using Coscine.Api.Notices.Services;
using Coscine.Api.Notices.Utils;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Coscine.Api.Notices.Controllers
......@@ -10,6 +14,9 @@ namespace Coscine.Api.Notices.Controllers
public class NoticeController : Controller
{
private readonly INoticeService _noticeService;
private readonly MaintenanceHelper _maintenanceHelper;
// url to rss feed from consul variable
private readonly string _rssUrl;
/// <summary>
/// NoticeController constructor
......@@ -18,6 +25,14 @@ namespace Coscine.Api.Notices.Controllers
public NoticeController(INoticeService noticeService)
{
_noticeService = noticeService;
var undefinedString = "-NotDefined-";
_maintenanceHelper = new MaintenanceHelper
{
RelevanceList = new List<string> { "Strung", "Teilstrung", "Unterbrechung", "eingeschrnkt betriebsfhig", "Wartung", "Teilwartung", "nderung", "Warnung", undefinedString, "Hinweis" },
UndefinedString = undefinedString,
};
_rssUrl = Program.Configuration.GetStringAndWait($"coscine/global/rss/url");
}
/// <summary>
......@@ -31,16 +46,47 @@ namespace Coscine.Api.Notices.Controllers
public async Task<IActionResult> GetNotice(string documentSlug, [FromQuery] string language = "en")
{
var url = await Program.Configuration.GetStringAsync($"coscine/local/documents/{documentSlug}/{language}", null);
if (url == null)
{
return BadRequest();
}
return Json(new {
data = new {
return Json(new
{
data = new
{
body = await _noticeService.GetNotice(url)
}
});
}
/// <summary>
/// Returns defined properties of the first entry of the rss feed
/// </summary>
/// <returns>Maintenance or 404 if no maintenance was found</returns>
[HttpGet("[controller]/getMaintenance")]
public ActionResult<MaintenanceReturnObject> GetMaintenance()
{
var maintenance = _maintenanceHelper.GetMaintenance(_rssUrl);
if (maintenance == null)
{
return NotFound("No maintenance was found.");
}
var maintenanceReturnObject = new MaintenanceReturnObject
{
Body = maintenance.Body,
DisplayName = maintenance.DisplayName,
EndsDate = maintenance.EndsDate != DateTime.MaxValue ? maintenance.EndsDate : null,
StartsDate = maintenance.StartsDate != DateTime.MinValue ? maintenance.StartsDate : null,
Type = maintenance.Type,
Url = maintenance.Url,
};
return Ok(maintenanceReturnObject);
}
}
}
......@@ -18,5 +18,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Coscine.ApiCommons" Version="2-*" />
<PackageReference Include="System.ServiceModel.Syndication" Version="5.0.0" />
</ItemGroup>
</Project>
\ No newline at end of file
using System;
namespace Coscine.Api.Notices.ReturnObjects
{
/// <summary>
/// This class represents a maintenance with its significant properties, which is returned from the api.
/// </summary>
public class MaintenanceReturnObject
{
/// <summary>
/// Maintenance title.
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// Maintenance url.
/// </summary>
public Uri Url { get; set; }
/// <summary>
/// Maintenance type.
/// </summary>
public string Type { get; set; }
/// <summary>
/// Maintenance description.
/// </summary>
public string Body { get; set; }
/// <summary>
/// Maintenance start.
/// </summary>
public DateTime? StartsDate { get; set; }
/// <summary>
/// Maintenance end.
/// </summary>
public DateTime? EndsDate { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Coscine.Api.Notices.Services
{
......
using System;
namespace Coscine.Api.Notices.Utils
{
/// <summary>
/// This class represents a maintenance with its significant properties.
/// </summary>
public class Maintenance
{
/// <summary>
/// Maintenance title.
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// Maintenance url.
/// </summary>
public Uri Url { get; set; }
/// <summary>
/// Maintenance type.
/// </summary>
public string Type { get; set; }
/// <summary>
/// Maintenance description.
/// </summary>
public string Body { get; set; }
/// <summary>
/// Maintenance start.
/// </summary>
public DateTime StartsDate { get; set; }
/// <summary>
/// Maintenance end.
/// </summary>
public DateTime EndsDate { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Xml;
namespace Coscine.Api.Notices.Utils
{
/// <summary>
/// This class helps to retrieve the relevant maintenance message for a certain service.
/// </summary>
public class MaintenanceHelper
{
/// <summary>
/// How the undefined string should look.
/// </summary>
public string UndefinedString { get; set; }
/// <summary>
/// Order of relevance to be used.
/// Only the most relevant (first in the list) maintenace message is later displayed.
/// All non listed "Störungen" are sorted as "-NotDefined-".
/// Use this list to adjust the order.
/// Types which are not part of the list, will be set to the UndefinedString property.
/// </summary>
public List<string> RelevanceList { get; set; }
/// <summary>
/// Get the most relevant maintenance from the rss feed
/// </summary>
/// <param name="feedUrl">Url of the rss feed</param>
/// <returns>The most relevant Maintenance</returns>
internal Maintenance GetMaintenance(string feedUrl)
{
return GetMaintenance(feedUrl, RelevanceList);
}
/// <summary>
/// Get the most relevant maintenance from the rss feed
/// </summary>
/// <param name="feedUrl">URL of the rss feed</param>
/// <param name="order">Order of Importance</param>
/// <returns>The most relevant Maintenance</returns>
internal Maintenance GetMaintenance(string feedUrl, List<string> order)
{
Maintenance result = null;
if (order.FindIndex(x => x.ToLower() == UndefinedString.ToLower()) == -1)
{
order.Add(UndefinedString);
}
int resultOrderPos = order.Count + 1;
var rssfeed = SyndicationFeed.Load(XmlReader.Create(feedUrl));
var syndicationItems = rssfeed.Items.OrderByDescending(x => x.PublishDate).ToList();
foreach (var syndicationItem in syndicationItems)
{
try
{
if (syndicationItem != null && syndicationItem.Summary != null && !string.IsNullOrWhiteSpace(syndicationItem.Summary.Text))
{
var current = new Maintenance
{
DisplayName = syndicationItem.Title.Text,
Url = syndicationItem.Links[0].Uri
};
string summary = syndicationItem.Summary.Text;
int splitter = summary.IndexOf('-');
if (splitter != -1)
{
current.Body = summary.Substring(splitter + 1, summary.Length - splitter - 1).Trim();
string firstPart = summary.Substring(0, splitter).Trim();
splitter = firstPart.IndexOf("von");
if (splitter != -1)
{
current.Type = firstPart.Substring(0, splitter).Trim();
string timespan = firstPart.Substring(splitter + 3, firstPart.Length - splitter - 3).Trim();
splitter = timespan.IndexOf("bis");
if (splitter != -1)
{
string startsString = timespan.Substring(0, splitter).Trim();
string endsString = timespan.Substring(splitter + 3, timespan.Length - splitter - 3).Trim();
var dayList = new List<string> { "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" };
foreach (var dayString in dayList)
{
startsString = startsString.Replace(dayString, "").Trim();
startsString = startsString.Replace(dayString.ToLower(), "").Trim();
}
foreach (var dayString in dayList)
{
endsString = endsString.Replace(dayString, "").Trim();
endsString = endsString.Replace(dayString.ToLower(), "").Trim();
}
if (startsString.ToLower() == "unbekannt")
{
current.StartsDate = DateTime.MinValue;
}
else
{
current.StartsDate = DateTime.ParseExact(startsString, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
}
if (endsString.ToLower() == "unbekannt")
{
current.EndsDate = DateTime.MaxValue;
}
else
{
current.EndsDate = DateTime.ParseExact(endsString, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
}
// still active message
if (current.EndsDate > DateTime.Now && current.StartsDate < DateTime.Now)
{
// first listed valid message
if (result == null)
{
result = current;
resultOrderPos = GetOrderPos(order, result.Type);
}
else
{
// check if the current message is higher ranged as the previosly result
int currentOrderPos = GetOrderPos(order, current.Type);
// higher rang of type
if (currentOrderPos < resultOrderPos)
{
result = current;
resultOrderPos = currentOrderPos;
// same type but longer active
}
else if (currentOrderPos < resultOrderPos && current.EndsDate > result.EndsDate)
{
result = current;
resultOrderPos = currentOrderPos;
}
}
}
}
}
}
}
}
catch (Exception)
{
// ignore not correct parsed messages
}
}
return result;
}
private int GetOrderPos(List<string> order, string type)
{
int res = order.FindIndex(x => x.ToLower() == type.ToLower());
if (res == -1)
{
res = order.FindIndex(x => x.ToLower() == UndefinedString.ToLower());
}
if (res == -1)
{
res = order.Count + 1;
}
return res;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment