using RestSharp;
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
namespace UptimeSharp
{
///
/// UptimeClient
///
public partial class UptimeClient
{
///
/// REST client used for the API communication
///
protected readonly RestClient _restClient;
///
/// The base URL for the UptimeRobot API
///
protected static Uri baseUri = new Uri("http://api.uptimerobot.com/");
///
/// Accessor for the UptimeRebot API key
/// see: http://http://www.uptimerobot.com/api.asp
///
public string ApiKey { get; set; }
///
/// Returns all associated data from the last request
///
public IRestResponse LastRequestData { get; private set; }
///
/// Initializes a new instance of the class.
///
/// The API key
public UptimeClient(string apiKey)
{
// assign public properties
ApiKey = apiKey;
// initialize REST client
_restClient = new RestClient(baseUri.ToString());
// add default parameters to each request
_restClient.AddDefaultParameter("apiKey", ApiKey);
// defines the response format (according to the UptimeRobot docs)
_restClient.AddDefaultParameter("format", "json");
// UptimeRobot returns by default JSON-P when json-formatting is set
// with this param it can return raw JSON
_restClient.AddDefaultParameter("noJsonCallback", "1");
// custom JSON deserializer (ServiceStack.Text)
_restClient.AddHandler("application/json", new JsonDeserializer());
// add custom deserialization lambdas
JsonDeserializer.AddCustomDeserialization();
}
///
/// Makes a typed HTTP REST request to the API
///
///
/// The request.
///
protected T Request(RestRequest request) where T : new()
{
// fix content type if wrong determined by RestSharp
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
IRestResponse response = _restClient.Execute(request);
LastRequestData = response;
ValidateResponse(response);
return response.Data;
}
///
/// Fetches a typed resource
///
///
/// Requested resource
/// Additional GET parameters
///
protected T Get(string resource, List parameters = null) where T : class, new()
{
// UptimeRobot uses GET for all of its endpoints
var request = new RestRequest(resource, Method.GET);
// enumeration for params
if (parameters != null)
{
parameters.ForEach(
param => {
if(param.Value != null)
{
request.AddParameter(param);
}
}
);
}
// do the request
return Request(request);
}
///
/// Fetches a typed resource
///
///
/// Requested resource
/// The parameters.
///
protected T Get(string resource, params Parameter[] parameters) where T : class, new()
{
List parameterList = new List();
parameterList.AddRange(parameters);
return Get(resource, parameterList);
}
///
/// Creates a RestSharp.Parameter instance.
///
/// The name.
/// The value.
///
internal static Parameter Parameter(string name, object value)
{
return new Parameter()
{
Name = name,
Value = value,
Type = ParameterType.GetOrPost
};
}
///
/// Validates the response.
///
/// The response.
///
///
/// Error retrieving response
///
protected void ValidateResponse(IRestResponse response) where T : new()
{
Type responseType = response.Data.GetType();
// get status property from ResponseBase POCO
PropertyInfo statusProp = responseType.GetProperty("Status");
object status = statusProp.GetValue(response.Data, null);
// Error from UptimeSharp
if (status.Equals(false))
{
// get error properties from response
PropertyInfo errorProp = responseType.GetProperty("ErrorMessage");
object error = errorProp.GetValue(response.Data, null);
PropertyInfo errorCodeProp = responseType.GetProperty("ErrorCode");
object errorCode = errorCodeProp.GetValue(response.Data, null);
// create exception
UptimeSharpException exception = new UptimeSharpException(
"UptimeRobot Exception: {0} (Code: {1})\n{2}",
response.ErrorException,
error,
errorCode,
"http://uptimerobot.com/api.asp#errorMessages"
);
// add custom pocket fields
exception.Error = error.ToString();
exception.ErrorCode = Convert.ToInt32(errorCode);
// add to generic exception data
exception.Data.Add("Error", error);
exception.Data.Add("ErrorCode", errorCode);
throw exception;
}
// HTTP Request Error
else if (response.StatusCode != HttpStatusCode.OK)
{
throw new UptimeSharpException(
"Request Exception: {0} (Code: {1})",
response.ErrorException,
response.ErrorMessage,
response.StatusCode
);
}
// Exception by RestSharp
else if (response.ErrorException != null)
{
throw new UptimeSharpException("Error retrieving response", response.ErrorException);
}
}
}
}