Skip to content

Commit

Permalink
Added bridge support
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaliy-bezugly committed Mar 19, 2024
1 parent ec09052 commit 58fa01c
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 10 deletions.
6 changes: 6 additions & 0 deletions Apps.Lionbridge/ApplicationConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Apps.Lionbridge;

public class ApplicationConstants
{
public const string BlackbirdToken = "#{APP_LIONBRIDGE_BLACKBIRD_TOKEN}#"; // bridge validates this token
}
2 changes: 2 additions & 0 deletions Apps.Lionbridge/Constants/ApiEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public static class ApiEndpoints
public const string SupportAssets = "/supportassets";
public const string TranslationMemories = "/tmupdates";
public const string Retrieve = "/retrieve";
public const string StatusUpdates = "/statusupdates";
public const string Listeners = StatusUpdates + "/listeners";
}
38 changes: 38 additions & 0 deletions Apps.Lionbridge/Webhooks/Bridge/BridgeService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Apps.Lionbridge.Webhooks.Bridge.Models;
using Blackbird.Applications.Sdk.Common.Authentication;
using RestSharp;

namespace Apps.Lionbridge.Webhooks.Bridge;

public class BridgeService
{
private string BridgeServiceUrl { get; set; }

public BridgeService(IEnumerable<AuthenticationCredentialsProvider> authenticationCredentialsProviders, string bridgeServiceUrl)
{
BridgeServiceUrl = bridgeServiceUrl;
}

public void Subscribe(string _event, string listenerId, string url)
{
var client = new RestClient(BridgeServiceUrl);
var request = new RestRequest($"/{listenerId}/{_event}", Method.Post);
request.AddHeader("Blackbird-Token", ApplicationConstants.BlackbirdToken);
request.AddBody(url);

client.Execute(request);
}

public void Unsubscribe(string _event, string listenerId, string url)
{
var client = new RestClient(BridgeServiceUrl);
var requestGet = new RestRequest($"/{listenerId}/{_event}", Method.Get);
requestGet.AddHeader("Blackbird-Token", ApplicationConstants.BlackbirdToken);
var webhooks = client.Get<List<BridgeGetResponse>>(requestGet);
var webhook = webhooks.FirstOrDefault(w => w.Value == url);

var requestDelete = new RestRequest($"/{listenerId}/{_event}/{webhook.Id}", Method.Delete);
requestDelete.AddHeader("Blackbird-Token", ApplicationConstants.BlackbirdToken);
client.Delete(requestDelete);
}
}
8 changes: 8 additions & 0 deletions Apps.Lionbridge/Webhooks/Bridge/Models/BridgeGetResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Apps.Lionbridge.Webhooks.Bridge.Models;

public class BridgeGetResponse
{
public string Id { get; set; }

public string Value { get; set; }
}
85 changes: 85 additions & 0 deletions Apps.Lionbridge/Webhooks/Handlers/BaseWebhookHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Apps.Lionbridge.Api;
using Apps.Lionbridge.Constants;
using Apps.Lionbridge.Webhooks.Bridge;
using Apps.Lionbridge.Webhooks.Responses;
using Blackbird.Applications.Sdk.Common;
using Blackbird.Applications.Sdk.Common.Authentication;
using Blackbird.Applications.Sdk.Common.Invocation;
using Blackbird.Applications.Sdk.Common.Webhooks;
using RestSharp;

namespace Apps.Lionbridge.Webhooks.Handlers;

public class BaseWebhookHandler : BaseInvocable, IWebhookEventHandler
{
private readonly string _bridgeServiceUrl;

private string SubscriptionEvent { get; set; }

protected readonly LionbridgeClient Client;

public BaseWebhookHandler(InvocationContext invocationContext, string subEvent) : base(invocationContext)
{
SubscriptionEvent = subEvent;
_bridgeServiceUrl = $"{invocationContext.UriInfo.BridgeServiceUrl.ToString().TrimEnd('/')}/webhooks/lionbridge";
Client = new LionbridgeClient(invocationContext.AuthenticationCredentialsProviders);
}


public async Task SubscribeAsync(IEnumerable<AuthenticationCredentialsProvider> authenticationCredentialsProviders,
Dictionary<string, string> values)
{
var listener = await GetListenerIdAsync();
if (listener == null)
{
listener = await CreateListenerAsync();
}

var bridge = new BridgeService(authenticationCredentialsProviders, _bridgeServiceUrl);
bridge.Subscribe(SubscriptionEvent, listener.ListenerId, values["payloadUrl"]);
}

public async Task UnsubscribeAsync(IEnumerable<AuthenticationCredentialsProvider> authenticationCredentialsProviders,
Dictionary<string, string> values)
{
var listener = await GetListenerIdAsync();
if (listener != null)
{
var bridge = new BridgeService(authenticationCredentialsProviders, _bridgeServiceUrl);
bridge.Unsubscribe(SubscriptionEvent, listener.ListenerId, values["payloadUrl"]);
await DeleteListenerAsync(listener.ListenerId);
}
}

private async Task<ListenerDto?> GetListenerIdAsync()
{
var request = new LionbridgeRequest(ApiEndpoints.Listeners, Method.Get);
var response = await Client.ExecuteWithErrorHandling<ListenersResponse>(request);

return response.Embedded.Listeners.FirstOrDefault(x => x.Type == SubscriptionEvent);
}

private async Task<ListenerDto> CreateListenerAsync()
{
var request = new LionbridgeRequest(ApiEndpoints.Listeners, Method.Post)
.AddJsonBody(new
{
uri = _bridgeServiceUrl,
type = SubscriptionEvent,
statusCodes = new []
{
"IN_TRANSLATION" // TODO: change in the future
},
acknowledgeStatusUpdate = true
});

var response = await Client.ExecuteWithErrorHandling<ListenerDto>(request);
return response;
}

private async Task DeleteListenerAsync(string listenerId)
{
var request = new LionbridgeRequest($"{ApiEndpoints.Listeners}/{listenerId}", Method.Delete);
await Client.ExecuteWithErrorHandling(request);
}
}
10 changes: 10 additions & 0 deletions Apps.Lionbridge/Webhooks/Handlers/JobStatusUpdatedHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Blackbird.Applications.Sdk.Common.Invocation;

namespace Apps.Lionbridge.Webhooks.Handlers;

public class JobStatusUpdatedHandler : BaseWebhookHandler
{
const string SubscriptionEvent = "JOB_STATUS_UPDATED";

public JobStatusUpdatedHandler(InvocationContext invocationContext) : base(invocationContext, SubscriptionEvent) { }
}
10 changes: 10 additions & 0 deletions Apps.Lionbridge/Webhooks/Handlers/RequestStatusUpdatedHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Blackbird.Applications.Sdk.Common.Invocation;

namespace Apps.Lionbridge.Webhooks.Handlers;

public class RequestStatusUpdatedHandler : BaseWebhookHandler
{
const string SubscriptionEvent = "REQUEST_STATUS_UPDATED";

public RequestStatusUpdatedHandler(InvocationContext invocationContext) : base(invocationContext, SubscriptionEvent) { }
}
6 changes: 6 additions & 0 deletions Apps.Lionbridge/Webhooks/Inputs/WebhookInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Apps.Lionbridge.Webhooks.Inputs;

public class WebhookInput
{
public string ListenerId { get; set; }
}
27 changes: 27 additions & 0 deletions Apps.Lionbridge/Webhooks/Responses/ListenerDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Newtonsoft.Json;

namespace Apps.Lionbridge.Webhooks.Responses;

public class ListenerDto
{
[JsonProperty("listenerId")]
public string ListenerId { get; set; }

[JsonProperty("uri")]
public string Uri { get; set; }

[JsonProperty("type")]
public string Type { get; set; }

[JsonProperty("statusCodes")]
public string[] StatusCodes { get; set; }

[JsonProperty("authType")]
public string AuthType { get; set; }

[JsonProperty("acknowledgeStatusUpdate")]
public bool AcknowledgeStatusUpdate { get; set; }

[JsonProperty("disabled")]
public bool Disabled { get; set; }
}
10 changes: 10 additions & 0 deletions Apps.Lionbridge/Webhooks/Responses/ListenersResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Apps.Lionbridge.Models.Dtos;

namespace Apps.Lionbridge.Webhooks.Responses;

public class ListenersResponse : EmbeddedItemsWrapper<ListenersWrapper>
{

}

public record ListenersWrapper(IEnumerable<ListenerDto> Listeners);
20 changes: 10 additions & 10 deletions Apps.Lionbridge/Webhooks/WebhookList.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Apps.Lionbridge.Api;
using Apps.Lionbridge.Constants;
using Apps.Lionbridge.Models.Dtos;
using Apps.Lionbridge.Models.Requests.Request;
using Apps.Lionbridge.Webhooks.Handlers;
using Apps.Lionbridge.Webhooks.Inputs;
using Apps.Lionbridge.Webhooks.Payload;
using Apps.Lionbridge.Webhooks.Responses;
Expand All @@ -16,7 +16,7 @@ public class WebhookList(InvocationContext invocationContext) : LionbridgeInvoca
{
#region Job Webhooks

[Webhook("Job status updated",
[Webhook("Job status updated", typeof(JobStatusUpdatedHandler),
Description = "Check for updates on jobs, as you are directly informed when the job is finished or cancelled")]
public async Task<WebhookResponse<JobStatusUpdatedResponse>> OnJobStatusUpdated(WebhookRequest webhookRequest,
[WebhookParameter] JobStatusUpdatedInput input)
Expand All @@ -35,15 +35,15 @@ public async Task<WebhookResponse<JobStatusUpdatedResponse>> OnJobStatusUpdated(
{
return preflightResponse;
}

bool archived = input.Archived ?? false;
if(archived != data.Archived)
if (archived != data.Archived)
{
return preflightResponse;
}

bool deleted = input.Deleted ?? false;
if(deleted != data.Deleted)
if (deleted != data.Deleted)
{
return preflightResponse;
}
Expand All @@ -66,7 +66,7 @@ public async Task<WebhookResponse<JobStatusUpdatedResponse>> OnJobStatusUpdated(

#region Request Webhooks

[Webhook("On request status updated",
[Webhook("On request status updated", typeof(RequestStatusUpdatedHandler),
Description =
"Check for updates on requests, as you are directly informed when the request is finished or cancelled")]
public async Task<WebhookResponse<RequestStatusUpdatedResponse>> OnRequestStatusUpdated(
Expand All @@ -81,7 +81,7 @@ public async Task<WebhookResponse<RequestStatusUpdatedResponse>> OnRequestStatus
HttpResponseMessage = null,
ReceivedWebhookRequestType = WebhookRequestType.Preflight
};

if (!string.IsNullOrEmpty(requests.JobId) && requests.JobId != data.JobId)
{
return preflightResponse;
Expand All @@ -108,7 +108,7 @@ private async Task<JobDto> GetJobDto(string jobId)
var apiRequest = new LionbridgeRequest($"{ApiEndpoints.Jobs}/{jobId}");
return await Client.ExecuteWithErrorHandling<JobDto>(apiRequest);
}

private async Task<List<RequestDto>> GetRequests(string jobId, IEnumerable<string> requestIds)
{
var requests = new List<RequestDto>();
Expand All @@ -118,7 +118,7 @@ private async Task<List<RequestDto>> GetRequests(string jobId, IEnumerable<strin
var request = await GetRequest(jobId, requestId);
requests.Add(request);
}

return requests;
}
}

0 comments on commit 58fa01c

Please sign in to comment.