Skip to content

Commit

Permalink
Added REST proxy class
Browse files Browse the repository at this point in the history
  • Loading branch information
acenolaza committed Apr 15, 2015
1 parent fc1ca07 commit ae64087
Show file tree
Hide file tree
Showing 8 changed files with 399 additions and 44 deletions.
18 changes: 12 additions & 6 deletions VersionOne.JiraConnector/JiraConnectorFactory.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
/*(c) Copyright 2012, VersionOne, Inc. All rights reserved. (c)*/
using System;
using VersionOne.JiraConnector.Rest;
using VersionOne.JiraConnector.Soap;

namespace VersionOne.JiraConnector {
public class JiraConnectorFactory {
namespace VersionOne.JiraConnector
{
public class JiraConnectorFactory
{
public readonly JiraConnectorType ConnectorType;

public JiraConnectorFactory(JiraConnectorType connectorType) {
public JiraConnectorFactory(JiraConnectorType connectorType)
{
ConnectorType = connectorType;
}

public IJiraConnector Create(string url, string username, string password) {
switch (ConnectorType) {
public IJiraConnector Create(string url, string username, string password)
{
switch (ConnectorType)
{
case JiraConnectorType.Soap:
return new JiraSoapProxy(url, username, password);

case JiraConnectorType.Rest:
throw new NotImplementedException();
return new JiraRestProxy(url, username, password);

default:
throw new NotSupportedException();
Expand Down
298 changes: 298 additions & 0 deletions VersionOne.JiraConnector/Rest/JiraRestProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net;
using RestSharp;
using System.Web.Helpers;
using VersionOne.JiraConnector.Exceptions;

namespace VersionOne.JiraConnector.Rest
{
public class JiraRestProxy : IJiraConnector
{
private readonly RestClient client;

public JiraRestProxy(string baseUrl)
: this(baseUrl, string.Empty, string.Empty)
{
}

public JiraRestProxy(string baseUrl, string username, string password)
{
client = new RestClient(baseUrl);

if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
client.Authenticator = new HttpBasicAuthenticator(username, password);
}
}

public void Login()
{
//throw new NotImplementedException();
}

public void Logout()
{
//throw new NotImplementedException();
}

public Issue[] GetIssuesFromFilter(string issueFilterId)
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "search",
RequestFormat = DataFormat.Json
};
request.AddQueryParameter("jql", string.Format("filter={0}", issueFilterId));

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
{
dynamic data = Json.Decode(response.Content);
return ((IEnumerable<dynamic>)data.issues).Select(i => (Issue)CreateIssue(i)).ToArray();
}
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public Issue UpdateIssue(string issueKey, string fieldName, string fieldValue)
{
dynamic editMetadata = GetEditMetadata(issueKey);
dynamic fieldMeta = editMetadata.fields[fieldName];

if (fieldMeta == null)
throw new JiraException("Field metadata is missing", null);
if (fieldMeta.schema.type == null)
throw new JiraException("Field metadata is missing a type", null);

var request = new RestRequest
{
Method = Method.PUT,
Resource = "issue/{issueIdOrKey}",
RequestFormat = DataFormat.Json,
};
request.AddUrlSegment("issueIdOrKey", issueKey);

dynamic body;
if (fieldMeta.schema.type.Equals("array"))
{
dynamic operation = new ExpandoObject();
((IDictionary<string, object>)operation).Add(fieldName, new List<dynamic>
{
new
{
set = new List<string> { fieldValue }
}
});
body = new { update = operation };
}
else
{
dynamic field = new ExpandoObject();
((IDictionary<string, object>)field).Add(fieldName, fieldValue);
body = new { fields = field };
}
request.AddBody(body);

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.NoContent))
return GetIssue(issueKey);
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public IList<Item> GetPriorities()
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "priority",
RequestFormat = DataFormat.Json
};

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
{
dynamic data = Json.Decode(response.Content);
return ((IEnumerable<dynamic>)data).Select(i => new Item(i.id, i.name)).ToList();
}
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public IList<Item> GetProjects()
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "project",
RequestFormat = DataFormat.Json
};

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
{
dynamic data = Json.Decode(response.Content);
return ((IEnumerable<dynamic>)data).Select(i => new Item(i.id, i.name)).ToList();
}
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public void AddComment(string issueKey, string comment)
{
var request = new RestRequest
{
Method = Method.POST,
Resource = "issue/{issueIdOrKey}/comment",
RequestFormat = DataFormat.Json,
};
request.AddUrlSegment("issueIdOrKey", issueKey);

request.AddBody(new { body = comment });

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.Created))
return;
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public void ProgressWorkflow(string issueKey, string action, string assignee)
{
var request = new RestRequest
{
Method = Method.POST,
Resource = "issue/{issueIdOrKey}/transitions",
RequestFormat = DataFormat.Json,
};
request.AddUrlSegment("issueIdOrKey", issueKey);

dynamic body = new ExpandoObject();
((IDictionary<string, object>)body).Add("transition", new { id = action });
if (assignee != null)
((IDictionary<string, object>)body).Add("fields", new { assignee = new { name = assignee } });
request.AddBody(body);

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.NoContent))
return;
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public IEnumerable<Item> GetAvailableActions(string issueId)
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "issue/{issueIdOrKey}/transitions?expand=transitions.fields",
RequestFormat = DataFormat.Json
};
request.AddUrlSegment("issueIdOrKey", issueId);

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
{
dynamic data = Json.Decode(response.Content);
return ((IEnumerable<dynamic>)data.transitions).Select(i => new Item(i.id, i.name)).ToList();
}
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

public IEnumerable<Item> GetCustomFields()
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "field",
RequestFormat = DataFormat.Json
};

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
{
dynamic data = Json.Decode(response.Content);
return ((IEnumerable<dynamic>)data).Where(i => i.custom).Select(i => new Item(i.id, i.name)).ToList();
}
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

private dynamic GetEditMetadata(string issueIdOrKey)
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "issue/{issueIdOrKey}/editmeta",
RequestFormat = DataFormat.Json
};
request.AddUrlSegment("issueIdOrKey", issueIdOrKey);

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
return Json.Decode(response.Content);
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

private Issue GetIssue(string issueIdOrKey)
{
var request = new RestRequest
{
Method = Method.GET,
Resource = "issue/{issueIdOrKey}",
RequestFormat = DataFormat.Json
};
request.AddUrlSegment("issueIdOrKey", issueIdOrKey);

var response = client.Execute(request);

if (response.StatusCode.Equals(HttpStatusCode.OK))
{
dynamic data = Json.Decode(response.Content);
return CreateIssue(data);
}
if (response.StatusCode.Equals(HttpStatusCode.Unauthorized))
throw new JiraLoginException();
throw new JiraException(response.StatusDescription, new Exception(response.Content));
}

private Issue CreateIssue(dynamic data)
{
return new Issue
{
Id = data.id,
Key = data.key,
Summary = data.fields.summary,
Description = data.fields.description,
Project = data.fields.project != null ? data.fields.project.name : string.Empty,
IssueType = data.fields.issuetype != null ? data.fields.issuetype.name : string.Empty,
Assignee = data.fields.assignee != null ? data.fields.assignee.name : string.Empty,
Priority = data.fields.priority != null ? data.fields.priority.name : string.Empty
};
}
}
}
10 changes: 10 additions & 0 deletions VersionOne.JiraConnector/VersionOne.JiraConnector.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,20 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp">
<Private>False</Private>
</Reference>
<Reference Include="RestSharp, Version=105.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Xml" />
</ItemGroup>
Expand All @@ -91,6 +99,7 @@
<Compile Include="Item.cs" />
<Compile Include="JiraConnectorFactory.cs" />
<Compile Include="JiraConnectorType.cs" />
<Compile Include="Rest\JiraRestProxy.cs" />
<Compile Include="Soap\JiraSoapProxy.cs" />
<Compile Include="Soap\JiraSoapService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down Expand Up @@ -118,6 +127,7 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
4 changes: 4 additions & 0 deletions VersionOne.JiraConnector/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp" version="105.0.1" targetFramework="net451" />
</packages>
Loading

0 comments on commit ae64087

Please sign in to comment.