-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
64889a1
commit 1c057cb
Showing
23 changed files
with
1,170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.29424.173 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusPageClient", "StatusPageClient\StatusPageClient.csproj", "{7AB12D4C-5EB3-4B7C-AF8B-BDCF2B20DF48}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testbed", "Testbed\Testbed.csproj", "{62D7AAAB-4674-456A-A919-25FA235EB54E}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{7AB12D4C-5EB3-4B7C-AF8B-BDCF2B20DF48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{7AB12D4C-5EB3-4B7C-AF8B-BDCF2B20DF48}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{7AB12D4C-5EB3-4B7C-AF8B-BDCF2B20DF48}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{7AB12D4C-5EB3-4B7C-AF8B-BDCF2B20DF48}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{62D7AAAB-4674-456A-A919-25FA235EB54E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{62D7AAAB-4674-456A-A919-25FA235EB54E}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{62D7AAAB-4674-456A-A919-25FA235EB54E}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{62D7AAAB-4674-456A-A919-25FA235EB54E}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {D81DD7B4-4172-4406-ACA9-744E608812E6} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace StatusPageClient | ||
{ | ||
public static class Constants | ||
{ | ||
/// <summary> | ||
/// The version of the Statuspage.io API to use. | ||
/// </summary> | ||
public const string ApiVersion = "v2"; | ||
|
||
/// <summary> | ||
/// The user agent to be used by request to the Statuspage.io API. | ||
/// </summary> | ||
public const string UserAgent = "StatusPageClient programmatic access"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace StatusPageClient.Models | ||
{ | ||
/// <summary> | ||
/// A single component of the <see cref="StatusPage"/> which can have its own dependencies and status. | ||
/// </summary> | ||
public class Component : IEquatable<Component> | ||
{ | ||
private IEnumerable<string> _rawSubcomponents; | ||
|
||
/// <summary> | ||
/// The unique identifier for this <see cref="Component"/>. | ||
/// </summary> | ||
public string Id { get; private set; } | ||
|
||
/// <summary> | ||
/// The friendly name of this <see cref="Component"/>. | ||
/// </summary> | ||
public string Name { get; private set; } | ||
|
||
/// <summary> | ||
/// A human-readable description of this <see cref="Component"/>. | ||
/// </summary> | ||
public string Description { get; private set; } | ||
|
||
/// <summary> | ||
/// The order that this <see cref="Component"/> should appear in. | ||
/// </summary> | ||
public int DisplayPosition { get; private set; } | ||
|
||
/// <summary> | ||
/// Current status of this <see cref="Component"/> | ||
/// </summary> | ||
/// <remarks> | ||
/// Only the <see cref="StatusDescription.Indicator"/> property will be populated. | ||
/// </remarks> | ||
public StatusDescription Status { get; private set; } | ||
|
||
/// <summary> | ||
/// All child components of this <see cref="Component"/>. | ||
/// </summary> | ||
public IEnumerable<Component> Subcomponents { get; private set; } | ||
|
||
internal Component(ResponseObjects.Component respComponent) | ||
{ | ||
_rawSubcomponents = respComponent.SubcomponentIds ?? Enumerable.Empty<string>(); | ||
|
||
Id = respComponent.Id; | ||
Name = respComponent.Name; | ||
Description = respComponent.Description; | ||
DisplayPosition = respComponent.Position; | ||
Status = new StatusDescription(respComponent.Status, null); | ||
} | ||
|
||
internal void ProcessSubcomponents(IEnumerable<Component> processedComponents) | ||
{ | ||
var componentDictionary = processedComponents.ToDictionary(pc => pc.Id); | ||
|
||
Subcomponents = (from id in _rawSubcomponents | ||
where componentDictionary.ContainsKey(id) | ||
select componentDictionary[id]).ToArray(); | ||
} | ||
|
||
/// <summary> | ||
/// Returns true if the other <see cref="Component"/> instance has the same <see cref="Id"/> as this one. | ||
/// </summary> | ||
/// <param name="other">The other <see cref="Component"/> to compare.</param> | ||
/// <returns>True if the two objects match, false otherwise</returns> | ||
public bool Equals(Component other) | ||
{ | ||
return other != null && string.Equals(Id, other.Id, StringComparison.InvariantCultureIgnoreCase); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a string that represents the current object. | ||
/// </summary> | ||
/// <returns>A string that represents the current object.</returns> | ||
public override string ToString() | ||
{ | ||
return $"{Name} ({Id})"; | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether the specified object is equal to the current object. | ||
/// </summary> | ||
/// <param name="obj">The object to compare with the current object.</param> | ||
/// <returns>true if the specified object is equal to the current object; otherwise, false.</returns> | ||
public override bool Equals(object obj) | ||
{ | ||
return Equals(obj as Component); | ||
} | ||
|
||
/// <summary> | ||
/// Serves as the default hash function. | ||
/// </summary> | ||
/// <returns>A hash code for the current object.</returns> | ||
public override int GetHashCode() | ||
{ | ||
return Id.GetHashCode(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Linq; | ||
|
||
namespace StatusPageClient.Models | ||
{ | ||
/// <summary> | ||
/// A change in state for a <see cref="Component"/> associated with an <see cref="IncidentUpdate"/>. | ||
/// </summary> | ||
public class ComponentStatusChange : IEquatable<ComponentStatusChange> | ||
{ | ||
/// <summary> | ||
/// The <see cref="Component"/> whose status is changing. | ||
/// </summary> | ||
public Component Component { get; private set; } | ||
|
||
/// <summary> | ||
/// The friendly name of this status change. | ||
/// </summary> | ||
public string Name { get; private set; } | ||
|
||
/// <summary> | ||
/// The former status of this <see cref="Component"/>. | ||
/// </summary> | ||
public StatusDescription OldStatus { get; private set; } | ||
|
||
/// <summary> | ||
/// The status which this <see cref="Component"/> has transitioned to. | ||
/// </summary> | ||
public StatusDescription NewStatus { get; private set; } | ||
|
||
internal ComponentStatusChange(ResponseObjects.ComponentImpact respComponentImpact, IEnumerable<Component> componentsLookup) | ||
{ | ||
Name = respComponentImpact.Name; | ||
OldStatus = new StatusDescription(respComponentImpact.OldStatus, null); | ||
NewStatus = new StatusDescription(respComponentImpact.NewStatus, null); | ||
|
||
Component = componentsLookup.FirstOrDefault(c => string.Equals(c.Id, respComponentImpact.ComponentId, StringComparison.InvariantCultureIgnoreCase)); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a string that represents the current object. | ||
/// </summary> | ||
/// <returns>A string that represents the current object.</returns> | ||
public override string ToString() | ||
{ | ||
return $"{Component}: {OldStatus} -> {NewStatus}"; | ||
} | ||
|
||
/// <summary> | ||
/// Returns true if the other <see cref="ComponentStatusChange"/> instance has the same <see cref="Component"/>, <see cref="OldStatus"/> and <see cref="NewStatus"/> as this one. | ||
/// </summary> | ||
/// <param name="other">The other <see cref="ComponentStatusChange"/> to compare.</param> | ||
/// <returns>True if the two objects match, false otherwise</returns> | ||
public bool Equals(ComponentStatusChange other) | ||
{ | ||
return other != null && other.Component == Component && other.OldStatus == OldStatus && other.NewStatus == NewStatus; | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether the specified object is equal to the current object. | ||
/// </summary> | ||
/// <param name="obj">The object to compare with the current object.</param> | ||
/// <returns>true if the specified object is equal to the current object; otherwise, false.</returns> | ||
public override bool Equals(object obj) | ||
{ | ||
return Equals(obj as ComponentStatusChange); | ||
} | ||
|
||
/// <summary> | ||
/// Serves as the default hash function. | ||
/// </summary> | ||
/// <returns>A hash code for the current object.</returns> | ||
public override int GetHashCode() | ||
{ | ||
return ToString().GetHashCode(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Linq; | ||
|
||
namespace StatusPageClient.Models | ||
{ | ||
/// <summary> | ||
/// An event relating to a status page and/or its subcomponents. | ||
/// </summary> | ||
public class Incident : IEquatable<Incident> | ||
{ | ||
/// <summary> | ||
/// The unique identifier of this incident. | ||
/// </summary> | ||
public string Id { get; private set; } | ||
|
||
/// <summary> | ||
/// A friendly name for this incident. | ||
/// </summary> | ||
public string Name { get; private set; } | ||
|
||
/// <summary> | ||
/// The URL for this incident. | ||
/// </summary> | ||
public string Shortlink { get; private set; } | ||
|
||
/// <summary> | ||
/// The impact this incident had upon <see cref="ImpactedComponents"/>. | ||
/// </summary> | ||
public string Impact { get; private set; } | ||
|
||
/// <summary> | ||
/// UTC date that this incident was created. | ||
/// </summary> | ||
public DateTime CreatedOn { get; private set; } | ||
|
||
/// <summary> | ||
/// UTC date that this incident was last updated. | ||
/// </summary> | ||
public DateTime UpdatedOn { get; private set; } | ||
|
||
/// <summary> | ||
/// If present, the UTC date that this incident began to impact <see cref="ImpactedComponents"/>. | ||
/// </summary> | ||
public DateTime? StartedOn { get; private set; } | ||
|
||
/// <summary> | ||
/// If present, the UTC date that this incident was resolved. | ||
/// </summary> | ||
public DateTime? ResolvedOn { get; private set; } | ||
|
||
/// <summary> | ||
/// Current status of this incident. | ||
/// </summary> | ||
public StatusDescription Status { get; private set; } | ||
|
||
/// <summary> | ||
/// All updates/changes of status for this incident. | ||
/// </summary> | ||
public IEnumerable<IncidentUpdate> Updates { get; private set; } | ||
|
||
/// <summary> | ||
/// All components impacted by this incident. | ||
/// </summary> | ||
public IEnumerable<Component> ImpactedComponents { get; private set; } | ||
|
||
internal Incident(ResponseObjects.Incident respIncident, IEnumerable<Component> componentsLookup) | ||
{ | ||
Id = respIncident.Id; | ||
Name = respIncident.Name; | ||
Shortlink = respIncident.Shortlink; | ||
Impact = respIncident.Impact; | ||
|
||
CreatedOn = respIncident.CreatedOn.UtcDateTime; | ||
UpdatedOn = respIncident.UpdatedOn.UtcDateTime; | ||
|
||
if (respIncident.StartedOn.HasValue) | ||
{ | ||
StartedOn = respIncident.StartedOn.Value.UtcDateTime; | ||
} | ||
if (respIncident.ResolvedOn.HasValue) | ||
{ | ||
ResolvedOn = respIncident.ResolvedOn.Value.UtcDateTime; | ||
} | ||
|
||
Status = new StatusDescription(respIncident.Status, null); | ||
|
||
if (respIncident.ComponentImpacts != null) | ||
{ | ||
var componentDictionary = componentsLookup.ToDictionary(c => c.Id); | ||
|
||
ImpactedComponents = (from ic in respIncident.ComponentImpacts | ||
where componentDictionary.ContainsKey(ic.Id) | ||
select componentDictionary[ic.Id]).ToArray(); | ||
} | ||
|
||
if (respIncident.Updates != null) | ||
{ | ||
Updates = respIncident.Updates.Select(iu => new IncidentUpdate(iu, componentsLookup)).ToArray(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Returns a string that represents the current object. | ||
/// </summary> | ||
/// <returns>A string that represents the current object.</returns> | ||
public override string ToString() | ||
{ | ||
return $"{Name} ({Id})"; | ||
} | ||
|
||
/// <summary> | ||
/// Returns true if the other <see cref="Incident"/> instance has the same <see cref="Id"/> as this one. | ||
/// </summary> | ||
/// <param name="other">The other <see cref="Incident"/> to compare.</param> | ||
/// <returns>True if the two objects match, false otherwise</returns> | ||
public bool Equals(Incident other) | ||
{ | ||
return other != null && string.Equals(Id, other.Id, StringComparison.InvariantCultureIgnoreCase); | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether the specified object is equal to the current object. | ||
/// </summary> | ||
/// <param name="obj">The object to compare with the current object.</param> | ||
/// <returns>true if the specified object is equal to the current object; otherwise, false.</returns> | ||
public override bool Equals(object obj) | ||
{ | ||
return Equals(obj as Incident); | ||
} | ||
|
||
/// <summary> | ||
/// Serves as the default hash function. | ||
/// </summary> | ||
/// <returns>A hash code for the current object.</returns> | ||
public override int GetHashCode() | ||
{ | ||
return Id.GetHashCode(); | ||
} | ||
} | ||
} |
Oops, something went wrong.