|
|
|
|
@ -10,329 +10,295 @@
|
|
|
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UServerJiraAPI::UServerJiraAPI()
|
|
|
|
|
void UServerJiraAPI::Initialize()
|
|
|
|
|
{
|
|
|
|
|
this->FullURL = UServerAPI::URLBuilder(
|
|
|
|
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer,
|
|
|
|
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraRESTURI
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
|
|
|
|
|
// Get board data
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> BoardRequest = HttpModule.CreateRequest();
|
|
|
|
|
BoardRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
BoardRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
BoardRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
BoardRequest->SetURL(this->FullURL + "agile/1.0/board");
|
|
|
|
|
BoardRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfBoardsResponse);
|
|
|
|
|
BoardRequest->ProcessRequest();
|
|
|
|
|
|
|
|
|
|
// Get custom field data
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> FieldsRequest = HttpModule.CreateRequest();
|
|
|
|
|
FieldsRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
FieldsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
FieldsRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
FieldsRequest->SetURL(this->FullURL + "api/2/field");
|
|
|
|
|
FieldsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfFieldsResponse);
|
|
|
|
|
FieldsRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
void UServerJiraAPI::ListOfBoardsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
const FString &JSONResponse = Response->GetContentAsString();
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &BoardsArray = JSON->GetArrayField("values");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &BoardValue : BoardsArray)
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Board = BoardValue->AsObject();
|
|
|
|
|
const TSharedPtr<FJsonObject> &Location = Board->GetObjectField("location");
|
|
|
|
|
if (Location->GetStringField("projectName") == GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName)
|
|
|
|
|
{
|
|
|
|
|
this->BoardID = Board->GetIntegerField("id");
|
|
|
|
|
this->ProjectID = Location->GetIntegerField("projectId");
|
|
|
|
|
this->ProjectKey = Location->GetStringField("projectKey");
|
|
|
|
|
this->ProjectAvatarURI = Location->GetStringField("avatarURI");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("Could not retrieve board data.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("Could not retrieve board data.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void UServerJiraAPI::ListOfFieldsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
const FString &JSONResponse = "{\"fields\":" + Response->GetContentAsString() + "}";
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &FieldArray = JSON->GetArrayField("fields");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &FieldValue : FieldArray)
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Field = FieldValue->AsObject();
|
|
|
|
|
const FString &Name = Field->GetStringField("name");
|
|
|
|
|
const FString &Key = Field->GetStringField("key");
|
|
|
|
|
if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraMapNameField)
|
|
|
|
|
{
|
|
|
|
|
this->MapNameCustomField = Key;
|
|
|
|
|
}
|
|
|
|
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraMarkerLocationField)
|
|
|
|
|
{
|
|
|
|
|
this->MarkerLocationCustomField = Key;
|
|
|
|
|
}
|
|
|
|
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraDepartmentField)
|
|
|
|
|
{
|
|
|
|
|
this->DepartmentCustomField = Key;
|
|
|
|
|
}
|
|
|
|
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraSeverityField)
|
|
|
|
|
{
|
|
|
|
|
this->SeverityCustomField = Key;
|
|
|
|
|
}
|
|
|
|
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraPlatformField)
|
|
|
|
|
{
|
|
|
|
|
this->PlatformCustomField = Key;
|
|
|
|
|
}
|
|
|
|
|
else if (Name == GetDefault<UUnrealzillaGlobalSettings>()->JiraVersionField)
|
|
|
|
|
{
|
|
|
|
|
this->VersionCustomField = Key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!this->MapNameCustomField.IsEmpty() &&
|
|
|
|
|
!this->MarkerLocationCustomField.IsEmpty() &&
|
|
|
|
|
!this->DepartmentCustomField.IsEmpty() &&
|
|
|
|
|
!this->SeverityCustomField.IsEmpty() &&
|
|
|
|
|
!this->PlatformCustomField.IsEmpty() &&
|
|
|
|
|
!this->VersionCustomField.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("Could not deserialise JSON.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ReturnListOfBugs()
|
|
|
|
|
{
|
|
|
|
|
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
|
|
|
|
|
|
|
|
TArray<FString> StatusQueries;
|
|
|
|
|
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs)
|
|
|
|
|
{
|
|
|
|
|
for (const FString Unresolved : GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses)
|
|
|
|
|
{
|
|
|
|
|
StatusQueries.Add("status=" + Unresolved);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs)
|
|
|
|
|
{
|
|
|
|
|
for (const FString InProgress : GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses)
|
|
|
|
|
{
|
|
|
|
|
StatusQueries.Add("status=" + InProgress);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs)
|
|
|
|
|
{
|
|
|
|
|
for (const FString Resolved : GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses)
|
|
|
|
|
{
|
|
|
|
|
StatusQueries.Add("status=" + Resolved);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
StatusQueries.Add("cf_mapname=" + this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
|
|
|
|
|
StatusQueries.Add("api_key=" + GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
|
|
|
const FString QueryString = FString::Join(StatusQueries, TEXT("&"));
|
|
|
|
|
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
|
|
|
|
SeverityRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
SeverityRequest->SetURL(FullURL + "/bug" + "?" + QueryString);
|
|
|
|
|
SeverityRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
SeverityRequest->SetURL(this->FullURL + "agile/1.0/board/" + FString::FromInt(this->BoardID) + "/issue?expand=names&fields=summary,description,issuetype,status,priority" + (this->MapNameCustomField.IsEmpty()?"":(","+this->MapNameCustomField)) + (this->MarkerLocationCustomField.IsEmpty()?"":(","+this->MarkerLocationCustomField)));
|
|
|
|
|
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ListOfBugsResponse);
|
|
|
|
|
SeverityRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONBugResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
|
|
|
|
|
if (!ResponseData.error)
|
|
|
|
|
{
|
|
|
|
|
TArray<FUnrealzillaBugData> BugData;
|
|
|
|
|
for (const FBugzillaJSONBugData &BugzillaData : ResponseData.bugs)
|
|
|
|
|
|
|
|
|
|
const FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &IssuesArray = JSON->GetArrayField("issues");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &IssueValue : IssuesArray)
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Issue = IssueValue->AsObject();
|
|
|
|
|
const TSharedPtr<FJsonObject> &Fields = Issue->GetObjectField("fields");
|
|
|
|
|
const TSharedPtr<FJsonObject> &Status = Fields->GetObjectField("status");
|
|
|
|
|
const FString StatusName = Status->GetStringField("name");
|
|
|
|
|
|
|
|
|
|
if ((GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs && GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses.Contains(StatusName)) ||
|
|
|
|
|
(GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs && GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses.Contains(StatusName)) ||
|
|
|
|
|
(GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs && GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses.Contains(StatusName)))
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Priority = Fields->GetObjectField("priority");
|
|
|
|
|
|
|
|
|
|
FUnrealzillaBugData Bug;
|
|
|
|
|
Bug.ID = BugzillaData.id;
|
|
|
|
|
Bug.Summary = BugzillaData.summary;
|
|
|
|
|
Bug.Component = BugzillaData.component;
|
|
|
|
|
Bug.MapName = BugzillaData.cf_mapname;
|
|
|
|
|
Bug.MapLocation = BugzillaData.cf_location;
|
|
|
|
|
Bug.Platform = BugzillaData.platform;
|
|
|
|
|
Bug.OperatingSystem = BugzillaData.op_sys;
|
|
|
|
|
Bug.Severity = BugzillaData.severity;
|
|
|
|
|
Bug.Status = BugzillaData.status;
|
|
|
|
|
Bug.Resolution = BugzillaData.resolution;
|
|
|
|
|
Bug.DuplicateOf = BugzillaData.dupe_of;
|
|
|
|
|
Bug.bIsOpen = BugzillaData.is_open;
|
|
|
|
|
Bug.ID = Issue->GetNumberField("id");
|
|
|
|
|
Bug.Status = StatusName;
|
|
|
|
|
Bug.Summary = Fields->GetStringField("summary");
|
|
|
|
|
Bug.Severity = Priority->GetStringField("name");
|
|
|
|
|
//Bug.Component = BugzillaData.component;
|
|
|
|
|
//Bug.Platform = BugzillaData.platform;
|
|
|
|
|
//Bug.OperatingSystem = BugzillaData.op_sys;
|
|
|
|
|
//Bug.Resolution = BugzillaData.resolution;
|
|
|
|
|
//Bug.DuplicateOf = BugzillaData.dupe_of;
|
|
|
|
|
//Bug.bIsOpen = BugzillaData.is_open;
|
|
|
|
|
if (!this->MapNameCustomField.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
Bug.MapName = Fields->GetStringField(this->MapNameCustomField);
|
|
|
|
|
}
|
|
|
|
|
if (!this->MarkerLocationCustomField.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
Bug.MarkerLocation = Fields->GetStringField(this->MarkerLocationCustomField);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BugData.Add(Bug);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("Could not deserialise JSON.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->BugDataResponse.Execute(BugData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::PrepareForm()
|
|
|
|
|
{
|
|
|
|
|
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
|
|
|
|
|
|
|
|
// Assemble query data into key:value pairs
|
|
|
|
|
TMap<FString, FString> QueryData;
|
|
|
|
|
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
|
|
|
QueryData.Add("issuetypeNames", GetDefault<UUnrealzillaGlobalSettings>()->JiraBugIssueType);
|
|
|
|
|
QueryData.Add("expand", "projects.issuetypes.fields");
|
|
|
|
|
const FString QueryString = UServerAPI::FormatQueryString(QueryData);
|
|
|
|
|
|
|
|
|
|
// Query the server for information about the current product
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> ProductRequest = HttpModule.CreateRequest();
|
|
|
|
|
ProductRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
ProductRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
ProductRequest->SetURL(FullURL + "/product/" + GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName + "?" + QueryString);
|
|
|
|
|
ProductRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerProductInfoResponse);
|
|
|
|
|
ProductRequest->ProcessRequest();
|
|
|
|
|
|
|
|
|
|
// Send a second query to retrieve severity options
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
|
|
|
|
SeverityRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
SeverityRequest->SetURL(FullURL + "/field/bug/bug_severity" + "?" + QueryString);
|
|
|
|
|
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerSeverityInfoResponse);
|
|
|
|
|
SeverityRequest->ProcessRequest();
|
|
|
|
|
|
|
|
|
|
// Send a third query to retrieve platform options
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> PlatformsRequest = HttpModule.CreateRequest();
|
|
|
|
|
PlatformsRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
PlatformsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
PlatformsRequest->SetURL(FullURL + "/field/bug/rep_platform" + "?" + QueryString);
|
|
|
|
|
PlatformsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPlatformInfoResponse);
|
|
|
|
|
PlatformsRequest->ProcessRequest();
|
|
|
|
|
|
|
|
|
|
// Send a final query to retrieve OS options
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> OSRequest = HttpModule.CreateRequest();
|
|
|
|
|
OSRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
OSRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
OSRequest->SetURL(FullURL + "/field/bug/op_sys" + "?" + QueryString);
|
|
|
|
|
OSRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerOSInfoResponse);
|
|
|
|
|
OSRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::SendFormData(const FUnrealzillaPostData &PostData)
|
|
|
|
|
{
|
|
|
|
|
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
|
|
|
const FString RequestURL = "/bug";
|
|
|
|
|
|
|
|
|
|
// Assemble query data into key:value pairs
|
|
|
|
|
TMap<FString, FString> QueryData;
|
|
|
|
|
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
|
|
|
|
|
|
|
|
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->DefaultStatus;
|
|
|
|
|
|
|
|
|
|
FBugzillaJSONPostBug PostDataJSON;
|
|
|
|
|
PostDataJSON.product = GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName;
|
|
|
|
|
PostDataJSON.version = PostData.Version;
|
|
|
|
|
PostDataJSON.platform = PostData.Platform;
|
|
|
|
|
PostDataJSON.op_sys = PostData.OS;
|
|
|
|
|
PostDataJSON.component = PostData.Component;
|
|
|
|
|
PostDataJSON.severity = PostData.Severity;
|
|
|
|
|
PostDataJSON.cf_mapname = PostData.MapName;
|
|
|
|
|
PostDataJSON.cf_location = PostData.MapLocation;
|
|
|
|
|
PostDataJSON.summary = PostData.Summary;
|
|
|
|
|
PostDataJSON.description = PostData.Comment;
|
|
|
|
|
if (!DefaultStatus.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
PostDataJSON.status = DefaultStatus;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (PostDataJSON.version.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("You must select a version number.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (PostDataJSON.platform.IsEmpty() || PostDataJSON.op_sys.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
PostDataJSON.platform = "All";
|
|
|
|
|
PostDataJSON.op_sys = "All";
|
|
|
|
|
}
|
|
|
|
|
if (PostDataJSON.component.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("You must select a component.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (PostDataJSON.severity.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("You must select a severity level.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (PostDataJSON.summary.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("You must provide a summary.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FString PostJsonString;
|
|
|
|
|
FJsonObjectConverter::UStructToJsonObjectString(PostDataJSON, PostJsonString);
|
|
|
|
|
// Keep track of how many of these tasks have completed so we can check their completion status later.
|
|
|
|
|
this->FieldListsCompletion = 0;
|
|
|
|
|
this->FieldListsCompletionMax = 2;
|
|
|
|
|
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = HttpModule.CreateRequest();
|
|
|
|
|
Request->SetVerb(TEXT("POST"));
|
|
|
|
|
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
Request->SetURL(FullURL + RequestURL + "?" + UServerAPI::FormatQueryString(QueryData));
|
|
|
|
|
Request->SetContentAsString(PostJsonString);
|
|
|
|
|
Request->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTResponse);
|
|
|
|
|
Request->ProcessRequest();
|
|
|
|
|
|
|
|
|
|
// Send a query to retrieve field options
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> FieldsRequest = HttpModule.CreateRequest();
|
|
|
|
|
FieldsRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
FieldsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
FieldsRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
FieldsRequest->SetURL(this->FullURL + "api/2/issue/createmeta?" + QueryString);
|
|
|
|
|
FieldsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerFieldOptionsResponse);
|
|
|
|
|
FieldsRequest->ProcessRequest();
|
|
|
|
|
|
|
|
|
|
// Send a second query to retrieve version numbers
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> VersionsRequest = HttpModule.CreateRequest();
|
|
|
|
|
VersionsRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
VersionsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
VersionsRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
VersionsRequest->SetURL(this->FullURL + "api/2/project/" + FString::FromInt(this->ProjectID) + "/version");
|
|
|
|
|
VersionsRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerVersionsResponse);
|
|
|
|
|
VersionsRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
void UServerJiraAPI::ServerFieldOptionsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONPostResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
const FString &JSONResponse = Response->GetContentAsString();
|
|
|
|
|
|
|
|
|
|
if (ResponseData.error)
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
this->CreateError(EErrorVerb::POST, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &ProjectsArray = JSON->GetArrayField("projects");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &ProjectValue : ProjectsArray)
|
|
|
|
|
{
|
|
|
|
|
// Use the response's bug ID to get the info from the newly filed bug report and update its marker
|
|
|
|
|
const TSharedPtr<FJsonObject> &Project = ProjectValue->AsObject();
|
|
|
|
|
if (Project->GetStringField("name") == GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName)
|
|
|
|
|
{
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &IssueTypes = Project->GetArrayField("issuetypes");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &IssueTypeValue : IssueTypes)
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &IssueType = IssueTypeValue->AsObject();
|
|
|
|
|
const TSharedPtr<FJsonObject> &Fields = IssueType->GetObjectField("fields");
|
|
|
|
|
|
|
|
|
|
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->JiraSubmissionServer + "/rest";
|
|
|
|
|
// After all that boilerplate code, finally get all available field options here
|
|
|
|
|
{
|
|
|
|
|
// Components
|
|
|
|
|
const TSharedPtr<FJsonObject> &Department = Fields->GetObjectField(this->DepartmentCustomField);
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &AllowedDepartmentsArray = Department->GetArrayField("allowedValues");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &AllowedDepartmentsValue : AllowedDepartmentsArray)
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Value = AllowedDepartmentsValue->AsObject();
|
|
|
|
|
this->ComponentsList.Add(Value->GetStringField("value"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TArray<FString> StatusQueries;
|
|
|
|
|
StatusQueries.Add("id=" + FString::FromInt(ResponseData.id));
|
|
|
|
|
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs)
|
|
|
|
|
// Bug severity
|
|
|
|
|
const TSharedPtr<FJsonObject> &Severity = Fields->GetObjectField(this->SeverityCustomField);
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &AllowedSeveritiesArray = Severity->GetArrayField("allowedValues");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &AllowedSeveritiesValue : AllowedSeveritiesArray)
|
|
|
|
|
{
|
|
|
|
|
for (const FString Unresolved : GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses)
|
|
|
|
|
{
|
|
|
|
|
StatusQueries.Add("status=" + Unresolved);
|
|
|
|
|
const TSharedPtr<FJsonObject> &Value = AllowedSeveritiesValue->AsObject();
|
|
|
|
|
this->SeverityList.Add(Value->GetStringField("value"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs)
|
|
|
|
|
{
|
|
|
|
|
for (const FString InProgress : GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses)
|
|
|
|
|
{
|
|
|
|
|
StatusQueries.Add("status=" + InProgress);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs)
|
|
|
|
|
{
|
|
|
|
|
for (const FString Resolved : GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses)
|
|
|
|
|
{
|
|
|
|
|
StatusQueries.Add("status=" + Resolved);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
StatusQueries.Add("cf_mapname=" + this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
|
|
|
|
|
StatusQueries.Add("api_key=" + GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey);
|
|
|
|
|
const FString QueryString = FString::Join(StatusQueries, TEXT("&"));
|
|
|
|
|
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
|
|
|
|
|
SeverityRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
SeverityRequest->SetURL(FullURL + "/bug" + "?" + QueryString);
|
|
|
|
|
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTUpdateMarkerResponse);
|
|
|
|
|
SeverityRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
// Platform
|
|
|
|
|
const TSharedPtr<FJsonObject> &Platform = Fields->GetObjectField(this->PlatformCustomField);
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &PlatformsArray = Platform->GetArrayField("allowedValues");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &PlatformsValue : PlatformsArray)
|
|
|
|
|
{
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
const TSharedPtr<FJsonObject> &Value = PlatformsValue->AsObject();
|
|
|
|
|
this->PlatformsList.Add(Value->GetStringField("value"));
|
|
|
|
|
|
|
|
|
|
// Also get children and add them to the OS list here
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &ChildrenArray = Value->GetArrayField("children");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &ChildValue : ChildrenArray)
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Child = ChildValue->AsObject();
|
|
|
|
|
this->OSList.AddUnique(Child->GetStringField("value"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONBugResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
|
|
|
|
|
if (ResponseData.error)
|
|
|
|
|
{
|
|
|
|
|
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ResponseData.bugs.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
TArray<FUnrealzillaBugData> BugData;
|
|
|
|
|
FUnrealzillaBugData Bug;
|
|
|
|
|
Bug.ID = ResponseData.bugs[0].id;
|
|
|
|
|
Bug.Summary = ResponseData.bugs[0].summary;
|
|
|
|
|
Bug.Component = ResponseData.bugs[0].component;
|
|
|
|
|
Bug.MapName = ResponseData.bugs[0].cf_mapname;
|
|
|
|
|
Bug.MapLocation = ResponseData.bugs[0].cf_location;
|
|
|
|
|
Bug.Platform = ResponseData.bugs[0].platform;
|
|
|
|
|
Bug.OperatingSystem = ResponseData.bugs[0].op_sys;
|
|
|
|
|
Bug.Severity = ResponseData.bugs[0].severity;
|
|
|
|
|
Bug.Status = ResponseData.bugs[0].status;
|
|
|
|
|
Bug.Resolution = ResponseData.bugs[0].resolution;
|
|
|
|
|
Bug.DuplicateOf = ResponseData.bugs[0].dupe_of;
|
|
|
|
|
Bug.bIsOpen = ResponseData.bugs[0].is_open;
|
|
|
|
|
BugData.Add(Bug);
|
|
|
|
|
this->BugDataResponse.Execute(BugData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONProductResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
|
|
|
|
|
if (ResponseData.error)
|
|
|
|
|
{
|
|
|
|
|
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
|
|
|
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ResponseData.products.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
const FBugzillaJSONProductData &ProductData = ResponseData.products[0];
|
|
|
|
|
if (ProductData.name == GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName)
|
|
|
|
|
{
|
|
|
|
|
for (const FBugzillaJSONComponentData &ComponentData : ProductData.components)
|
|
|
|
|
{
|
|
|
|
|
this->ComponentsList.Add(ComponentData.name);
|
|
|
|
|
}
|
|
|
|
|
for (const FBugzillaJSONVersionData &VersionData : ProductData.versions)
|
|
|
|
|
{
|
|
|
|
|
this->VersionsList.Add(VersionData.name);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -340,11 +306,7 @@ void UServerJiraAPI::ServerProductInfoResponse(FHttpRequestPtr Request, FHttpRes
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
FStringFormatOrderedArguments Args;
|
|
|
|
|
Args.Add(FStringFormatArg(GetDefault<UUnrealzillaGlobalSettings>()->JiraProjectName));
|
|
|
|
|
//this->ShowProcessingOverlayMessage(FString::Format(TEXT("Could not find data for a product called {0}"), Args), true);
|
|
|
|
|
this->CreateError(FString::Format(TEXT("Could not find data for a product called {0}"), Args));
|
|
|
|
|
}
|
|
|
|
|
this->CreateError("Could not deserialise JSON.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@ -352,63 +314,28 @@ void UServerJiraAPI::ServerProductInfoResponse(FHttpRequestPtr Request, FHttpRes
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerSeverityInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
void UServerJiraAPI::ServerVersionsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONFieldResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
const FString &JSONResponse = Response->GetContentAsString();
|
|
|
|
|
|
|
|
|
|
if (ResponseData.error)
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
|
|
|
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &ValuesArray = JSON->GetArrayField("values");
|
|
|
|
|
for (const TSharedPtr<FJsonValue> &ValueObject : ValuesArray)
|
|
|
|
|
{
|
|
|
|
|
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "bug_severity")
|
|
|
|
|
{
|
|
|
|
|
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
|
|
|
|
|
{
|
|
|
|
|
this->SeverityList.Add(FieldValue.name);
|
|
|
|
|
}
|
|
|
|
|
const TSharedPtr<FJsonObject> &Value = ValueObject->AsObject();
|
|
|
|
|
this->VersionsList.Add(Value->GetStringField("name"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->CheckIfAllFormResponsesAreIn();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONFieldResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
|
|
|
|
|
if (ResponseData.error)
|
|
|
|
|
{
|
|
|
|
|
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
|
|
|
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "rep_platform")
|
|
|
|
|
{
|
|
|
|
|
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
|
|
|
|
|
{
|
|
|
|
|
this->PlatformsList.Add(FieldValue.name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->CheckIfAllFormResponsesAreIn();
|
|
|
|
|
this->CreateError("Could not deserialise JSON.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@ -416,44 +343,14 @@ void UServerJiraAPI::ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpRe
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
FBugzillaJSONFieldResponse ResponseData;
|
|
|
|
|
FString JSONResponse = Response->GetContentAsString();
|
|
|
|
|
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
|
|
|
|
|
|
|
|
|
|
if (ResponseData.error)
|
|
|
|
|
{
|
|
|
|
|
//this->ShowProcessingOverlayMessage(ResponseData.message);
|
|
|
|
|
this->CreateError(EErrorVerb::GET, ResponseData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "op_sys")
|
|
|
|
|
{
|
|
|
|
|
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
|
|
|
|
|
{
|
|
|
|
|
this->OSList.Add(FieldValue.name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->CheckIfAllFormResponsesAreIn();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
|
|
|
|
{
|
|
|
|
|
if (!this->ComponentsList.IsEmpty() && !this->VersionsList.IsEmpty() && !this->SeverityList.IsEmpty() &&
|
|
|
|
|
!this->PlatformsList.IsEmpty() && !this->OSList.IsEmpty())
|
|
|
|
|
this->FieldListsCompletion++;
|
|
|
|
|
|
|
|
|
|
if (this->FieldListsCompletion == this->FieldListsCompletionMax)
|
|
|
|
|
{
|
|
|
|
|
this->FieldListsCompletion = this->FieldListsCompletionMax = 0;
|
|
|
|
|
|
|
|
|
|
FUnrealzillaFormPrepData Data;
|
|
|
|
|
|
|
|
|
|
Data.ComponentsList = this->ComponentsList;
|
|
|
|
|
@ -468,10 +365,6 @@ void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
|
|
|
|
{
|
|
|
|
|
Data.DetectedVersion = GameVersion;
|
|
|
|
|
}
|
|
|
|
|
else if (this->VersionsList.Contains("unspecified"))
|
|
|
|
|
{
|
|
|
|
|
Data.DetectedVersion = "unspecified";
|
|
|
|
|
}
|
|
|
|
|
else if (this->VersionsList.Contains("Latest"))
|
|
|
|
|
{
|
|
|
|
|
Data.DetectedVersion = "Latest";
|
|
|
|
|
@ -526,3 +419,196 @@ void UServerJiraAPI::CheckIfAllFormResponsesAreIn()
|
|
|
|
|
this->OSList.Empty();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::SendFormData(const FUnrealzillaPostData &PostData)
|
|
|
|
|
{
|
|
|
|
|
if (PostData.Summary.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("You must provide a summary.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSONPostFields = MakeShareable(new FJsonObject());
|
|
|
|
|
JSONPostFields->SetStringField("summary", PostData.Summary);
|
|
|
|
|
JSONPostFields->SetStringField("description", PostData.Comment);
|
|
|
|
|
JSONPostFields->SetStringField(this->MapNameCustomField, PostData.MapName);
|
|
|
|
|
JSONPostFields->SetStringField(this->MarkerLocationCustomField, PostData.MarkerLocation);
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> Project = MakeShareable(new FJsonObject());
|
|
|
|
|
Project->SetStringField("key", this->ProjectKey);
|
|
|
|
|
JSONPostFields->SetObjectField("project", Project);
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> IssueType = MakeShareable(new FJsonObject());
|
|
|
|
|
IssueType->SetStringField("name", GetDefault<UUnrealzillaGlobalSettings>()->JiraBugIssueType);
|
|
|
|
|
JSONPostFields->SetObjectField("issuetype", IssueType);
|
|
|
|
|
|
|
|
|
|
//const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->JiraDefaultStatus;
|
|
|
|
|
//if (!DefaultStatus.IsEmpty())
|
|
|
|
|
//{
|
|
|
|
|
// TSharedPtr<FJsonObject> Status = MakeShareable(new FJsonObject());
|
|
|
|
|
// Status->SetStringField("name", DefaultStatus);
|
|
|
|
|
// JSONPostFields->SetObjectField("status", Status);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraVersionField.IsEmpty() && !PostData.Version.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<FJsonObject> Version = MakeShareable(new FJsonObject());
|
|
|
|
|
Version->SetStringField("name", PostData.Version);
|
|
|
|
|
JSONPostFields->SetObjectField(this->VersionCustomField, Version);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraPlatformField.IsEmpty() && !PostData.Platform.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<FJsonObject> PlatformCascade = MakeShareable(new FJsonObject());
|
|
|
|
|
TSharedPtr<FJsonObject> OSCascade = MakeShareable(new FJsonObject());
|
|
|
|
|
PlatformCascade->SetStringField("value", PostData.Platform);
|
|
|
|
|
if (!PostData.OS.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
OSCascade->SetStringField("value", PostData.OS);
|
|
|
|
|
PlatformCascade->SetObjectField("child", OSCascade);
|
|
|
|
|
}
|
|
|
|
|
JSONPostFields->SetObjectField(this->PlatformCustomField, PlatformCascade);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraDepartmentField.IsEmpty() && !PostData.Component.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<FJsonObject> Category = MakeShareable(new FJsonObject());
|
|
|
|
|
Category->SetStringField("value", PostData.Component);
|
|
|
|
|
JSONPostFields->SetObjectField(this->DepartmentCustomField, Category);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!GetDefault<UUnrealzillaGlobalSettings>()->JiraSeverityField.IsEmpty() && !PostData.Severity.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
TSharedPtr<FJsonObject> Severity = MakeShareable(new FJsonObject());
|
|
|
|
|
Severity->SetStringField("value", PostData.Severity);
|
|
|
|
|
JSONPostFields->SetObjectField(this->SeverityCustomField, Severity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSONPostObject = MakeShareable(new FJsonObject());
|
|
|
|
|
JSONPostObject->SetObjectField("fields", JSONPostFields);
|
|
|
|
|
FString PostJsonString;
|
|
|
|
|
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&PostJsonString);
|
|
|
|
|
FJsonSerializer::Serialize(JSONPostObject.ToSharedRef(), Writer);
|
|
|
|
|
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> PostRequest = HttpModule.CreateRequest();
|
|
|
|
|
PostRequest->SetVerb(TEXT("POST"));
|
|
|
|
|
PostRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
PostRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
PostRequest->SetURL(this->FullURL + "api/2/issue");
|
|
|
|
|
PostRequest->SetContentAsString(PostJsonString);
|
|
|
|
|
PostRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTResponse);
|
|
|
|
|
PostRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
const FString &JSONResponse = Response->GetContentAsString();
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
// I'm not sure what is meant to show up in the "errorMessages" array, but this is where we handle that.
|
|
|
|
|
const TArray<TSharedPtr<FJsonValue>> &ErrorMessageArray = JSON->GetArrayField("errorMessages");
|
|
|
|
|
if (!ErrorMessageArray.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
// Handle error messages here
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const TSharedPtr<FJsonObject> &Errors = JSON->GetObjectField("errors");
|
|
|
|
|
TArray<FString> ErrorStringBuilder;
|
|
|
|
|
TArray<FString> ErrorKeys;
|
|
|
|
|
Errors->Values.GenerateKeyArray(ErrorKeys);
|
|
|
|
|
for (const FString &ErrorKey : ErrorKeys)
|
|
|
|
|
{
|
|
|
|
|
FStringFormatOrderedArguments Args;
|
|
|
|
|
Args.Add(FStringFormatArg(ErrorKey));
|
|
|
|
|
Args.Add(FStringFormatArg(Errors->GetStringField(ErrorKey)));
|
|
|
|
|
ErrorStringBuilder.Add(FString::Format(TEXT("{0}: {1}"), Args));
|
|
|
|
|
}
|
|
|
|
|
const FString &ErrorString = FString::Join(ErrorStringBuilder, TEXT("\n"));
|
|
|
|
|
if (!ErrorString.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
this->CreateError(ErrorString);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//const int32 &NewBugID = FCString::Atoi(*JSON->GetStringField("id"));
|
|
|
|
|
//const FString &NewBugKey = JSON->GetStringField("key");
|
|
|
|
|
const FString &NewBugURI = JSON->GetStringField("self");
|
|
|
|
|
|
|
|
|
|
FHttpModule &HttpModule = FHttpModule::Get();
|
|
|
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> NewBugRequest = HttpModule.CreateRequest();
|
|
|
|
|
NewBugRequest->SetVerb(TEXT("GET"));
|
|
|
|
|
NewBugRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
|
|
|
|
NewBugRequest->AppendToHeader(TEXT("Authorization"), TEXT("Basic ") + this->GenerateAuthString());
|
|
|
|
|
NewBugRequest->SetURL(NewBugURI);
|
|
|
|
|
NewBugRequest->OnProcessRequestComplete().BindUObject(this, &UServerJiraAPI::ServerPOSTUpdateMarkerResponse);
|
|
|
|
|
NewBugRequest->ProcessRequest();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("Could not deserialise JSON.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UServerJiraAPI::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
|
|
|
|
|
{
|
|
|
|
|
if (Success)
|
|
|
|
|
{
|
|
|
|
|
const FString &JSONResponse = Response->GetContentAsString();
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FJsonObject> JSON = MakeShareable(new FJsonObject);
|
|
|
|
|
const TSharedRef<TJsonReader<>> &Reader = TJsonReaderFactory<>::Create(JSONResponse);
|
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JSON))
|
|
|
|
|
{
|
|
|
|
|
if (JSON->HasTypedField<EJson::Object>("fields"))
|
|
|
|
|
{
|
|
|
|
|
const TSharedPtr<FJsonObject> &Fields = JSON->GetObjectField("fields");
|
|
|
|
|
const TSharedPtr<FJsonObject> &PlatformFields = Fields->GetObjectField(this->PlatformCustomField);
|
|
|
|
|
|
|
|
|
|
TArray<FUnrealzillaBugData> BugData;
|
|
|
|
|
FUnrealzillaBugData Bug;
|
|
|
|
|
Bug.ID = JSON->GetIntegerField("id");
|
|
|
|
|
Bug.Summary = Fields->GetStringField("summary");
|
|
|
|
|
Bug.Component = Fields->GetObjectField(this->DepartmentCustomField)->GetStringField("value");
|
|
|
|
|
Bug.MapName = Fields->GetStringField(this->MapNameCustomField);
|
|
|
|
|
Bug.MarkerLocation = Fields->GetStringField(this->MarkerLocationCustomField);
|
|
|
|
|
Bug.Platform = PlatformFields->GetStringField("value");
|
|
|
|
|
Bug.OperatingSystem = PlatformFields->GetObjectField("child")->GetStringField("value");
|
|
|
|
|
Bug.Severity = Fields->GetObjectField(this->SeverityCustomField)->GetStringField("value");
|
|
|
|
|
Bug.Status = Fields->GetObjectField("status")->GetStringField("name");
|
|
|
|
|
Bug.Resolution = Fields->GetStringField("resolution");
|
|
|
|
|
BugData.Add(Bug);
|
|
|
|
|
this->BugDataResponse.Execute(BugData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->CreateError("Could not deserialise JSON.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->ServerConnectionError(Request->GetStatus());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const FString UServerJiraAPI::GenerateAuthString() const
|
|
|
|
|
{
|
|
|
|
|
return FBase64::Encode(
|
|
|
|
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraUsername +
|
|
|
|
|
":" +
|
|
|
|
|
GetDefault<UUnrealzillaGlobalSettings>()->JiraAPIKey
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|