Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a8161f7
Initial plan
Copilot Jul 25, 2025
1baa3c8
Create WebDeploymentsApi interface and implementation with core models
Copilot Jul 25, 2025
2adb5ad
Changes before error encountered
Copilot Jul 25, 2025
2456cab
Complete WebDeploymentsApi model cleanup and add comprehensive tests
Copilot Jul 25, 2025
3d7e5d8
Restore deleted WebDeployment models and add missing dependencies
Copilot Jul 25, 2025
f025e45
Address code review feedback for WebDeploymentsApi implementation
Copilot Jul 28, 2025
427564a
Fixed WebDeploymentsApi parameters per review feedback
Copilot Jul 28, 2025
616296b
Fix parameter naming for collections - use plural names for collectio…
Copilot Jul 28, 2025
e813682
Use UriHelper.ParameterToString for boolean parameter conversion
Copilot Jul 28, 2025
5fd5856
Make all WebDeployment models used by WebDeploymentsApi sealed and clean
Copilot Jul 28, 2025
663ac54
Complete comprehensive WebDeployment model cleanup per issue #109 gui…
Copilot Jul 28, 2025
ae8d512
Add newlines at end of all WebDeployment model files
Copilot Jul 28, 2025
fa2ebca
Fix WebDeploymentsApi DeleteWebdeploymentsTokenRevokeAsync to use Nam…
Copilot Jul 29, 2025
9d637e3
Fix Delete Method
JackTelford Jul 29, 2025
9b4a0da
Complete comprehensive audit and model cleanup per issue #109 guidelines
Copilot Aug 13, 2025
a0e18e6
Fix HTTP client factory pattern and add missing newlines per review f…
Copilot Aug 20, 2025
2e84b67
Merge main branch and resolve conflicts
Copilot Aug 20, 2025
aae698b
Fix project file path references after merge
Copilot Aug 20, 2025
17d8b57
Merge branch 'main' into copilot/fix-109
JackTelford Aug 21, 2025
891a3ca
Remove leading slash from all URLs in WebDeploymentsApi
Copilot Aug 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
363 changes: 363 additions & 0 deletions src/PureCloud.Client/Apis/WebDeploymentsApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,363 @@
using System.Collections.Specialized;
using System.Net.Http.Json;
using Microsoft.Extensions.Options;
using PureCloud.Client.Contracts;
using PureCloud.Client.Http;
using PureCloud.Client.Json;
using PureCloud.Client.Models;

namespace PureCloud.Client.Apis;

/// <inheritdoc />
public sealed class WebDeploymentsApi : IWebDeploymentsApi
{
private readonly HttpClient _httpClient;
private readonly PureCloudJsonSerializerOptions _options;

public WebDeploymentsApi(IHttpClientFactory httpClientFactory, IOptions<PureCloudJsonSerializerOptions> options)
{
_httpClient = httpClientFactory.CreateClient(PureCloudConstants.PureCloudClientName);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep a global copy of the factory and create instance is every method instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Changed from storing HttpClient instance to storing IHttpClientFactory and creating client in each method following the FlowsApi pattern. Commit a0e18e6

_options = options.Value;
}

/// <inheritdoc />
public async Task<bool> DeleteWebdeploymentsConfigurationAsync(string configurationId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(configurationId);

var uri = $"/api/v2/webdeployments/configurations/{Uri.EscapeDataString(configurationId)}";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the variable by moving the string into the DeleteAsync method directly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Removed the URI variable and moved the string directly into the DeleteAsync method call. Applied this pattern to all methods without query parameters throughout the API. Commit a0e18e6


var response = await _httpClient.DeleteAsync(uri, cancellationToken);

return response.IsSuccessStatusCode;
}

/// <inheritdoc />
public async Task<bool> DeleteWebdeploymentsDeploymentAsync(string deploymentId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);

var uri = $"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}";

var response = await _httpClient.DeleteAsync(uri, cancellationToken);

return response.IsSuccessStatusCode;
}

/// <inheritdoc />
public async Task<bool> DeleteWebdeploymentsDeploymentCobrowseSessionIdAsync(string deploymentId, string sessionId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);
ArgumentException.ThrowIfNullOrEmpty(sessionId);

var uri = $"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}/cobrowse/{Uri.EscapeDataString(sessionId)}";

var response = await _httpClient.DeleteAsync(uri, cancellationToken);

return response.IsSuccessStatusCode;
}

/// <inheritdoc />
public async Task<bool> DeleteWebdeploymentsTokenRevokeAsync(string xJourneySessionId = null, string xJourneySessionType = null, CancellationToken cancellationToken = default)
{
var parameters = new NameValueCollection();

if (!string.IsNullOrEmpty(xJourneySessionId))
{
parameters.Add("X-Journey-Session-Id", Uri.EscapeDataString(xJourneySessionId));
}

if (!string.IsNullOrEmpty(xJourneySessionType))
{
parameters.Add("X-Journey-Session-Type", Uri.EscapeDataString(xJourneySessionType));
}

var uri = UriHelper.GetUri("/api/v2/webdeployments/token/revoke", parameters);

var response = await _httpClient.DeleteAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return true;

}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersion> GetWebdeploymentsConfigurationVersionAsync(string configurationId, string versionId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(configurationId);
ArgumentException.ThrowIfNullOrEmpty(versionId);

var uri = $"/api/v2/webdeployments/configurations/{Uri.EscapeDataString(configurationId)}/versions/{Uri.EscapeDataString(versionId)}";

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersion>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersionEntityListing> GetWebdeploymentsConfigurationVersionsAsync(string configurationId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(configurationId);

var uri = $"/api/v2/webdeployments/configurations/{Uri.EscapeDataString(configurationId)}/versions";

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersionEntityListing>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersion> GetWebdeploymentsConfigurationVersionsDraftAsync(string configurationId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(configurationId);

var uri = $"/api/v2/webdeployments/configurations/{Uri.EscapeDataString(configurationId)}/versions/draft";

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersion>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersionEntityListing> GetWebdeploymentsConfigurationsAsync(bool? showOnlyPublished = null, CancellationToken cancellationToken = default)
{
var parameters = new NameValueCollection();

if (showOnlyPublished.HasValue)
{
parameters.Add("showOnlyPublished", UriHelper.ParameterToString(showOnlyPublished.Value));
}

var uri = UriHelper.GetUri("/api/v2/webdeployments/configurations", parameters);

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersionEntityListing>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeployment> GetWebdeploymentsDeploymentAsync(string deploymentId, IEnumerable<string> expands = null, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);

var parameters = new NameValueCollection();

if (expands != null)
{
foreach (var expand in expands)
{
parameters.Add("expand", expand);
}
}

var uri = UriHelper.GetUri($"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}", parameters);

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeployment>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<CobrowseWebMessagingSession> GetWebdeploymentsDeploymentCobrowseSessionIdAsync(string deploymentId, string sessionId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);
ArgumentException.ThrowIfNullOrEmpty(sessionId);

var uri = $"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}/cobrowse/{Uri.EscapeDataString(sessionId)}";

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<CobrowseWebMessagingSession>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentActiveConfigurationOnDeployment> GetWebdeploymentsDeploymentConfigurationsAsync(string deploymentId, string type = null, IEnumerable<string> expands = null, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);

var parameters = new NameValueCollection();

if (!string.IsNullOrEmpty(type))
{
parameters.Add("type", type);
}

if (expands != null)
{
foreach (var expand in expands)
{
parameters.Add("expand", expand);
}
}

var uri = UriHelper.GetUri($"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}/configurations", parameters);

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentActiveConfigurationOnDeployment>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<IdentityResolutionConfig> GetWebdeploymentsDeploymentIdentityresolutionAsync(string deploymentId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);

var uri = $"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}/identityresolution";

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<IdentityResolutionConfig>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<ExpandableWebDeploymentEntityListing> GetWebdeploymentsDeploymentsAsync(IEnumerable<string> expands = null, CancellationToken cancellationToken = default)
{
var parameters = new NameValueCollection();

if (expands != null)
{
foreach (var expand in expands)
{
parameters.Add("expand", expand);
}
}

var uri = UriHelper.GetUri("/api/v2/webdeployments/deployments", parameters);

var response = await _httpClient.GetAsync(uri, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<ExpandableWebDeploymentEntityListing>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersion> CreateWebdeploymentsConfigurationVersionsDraftPublishAsync(string configurationId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(configurationId);

var uri = $"/api/v2/webdeployments/configurations/{Uri.EscapeDataString(configurationId)}/versions/draft/publish";

var response = await _httpClient.PostAsync(uri, null, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersion>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersion> CreateWebdeploymentsConfigurationsAsync(WebDeploymentConfigurationVersion configurationVersion, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(configurationVersion);

var uri = "/api/v2/webdeployments/configurations";

var response = await _httpClient.PostAsJsonAsync(uri, configurationVersion, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersion>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeployment> CreateWebdeploymentsDeploymentsAsync(WebDeployment deployment, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(deployment);

var uri = "/api/v2/webdeployments/deployments";

var response = await _httpClient.PostAsJsonAsync(uri, deployment, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeployment>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentsAuthorizationResponse> CreateWebdeploymentsTokenOauthcodegrantjwtexchangeAsync(WebDeploymentsOAuthExchangeRequest body, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(body);

var uri = "/api/v2/webdeployments/token/oauthcodegrantjwtexchange";

var response = await _httpClient.PostAsJsonAsync(uri, body, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentsAuthorizationResponse>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<SignedData> CreateWebdeploymentsTokenRefreshAsync(WebDeploymentsRefreshJWTRequest body = null, CancellationToken cancellationToken = default)
{
var uri = "/api/v2/webdeployments/token/refresh";

var response = await _httpClient.PostAsJsonAsync(uri, body, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<SignedData>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeploymentConfigurationVersion> UpdateWebdeploymentsConfigurationVersionsDraftAsync(string configurationId, WebDeploymentConfigurationVersion configurationVersion, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(configurationId);
ArgumentNullException.ThrowIfNull(configurationVersion);

var uri = $"/api/v2/webdeployments/configurations/{Uri.EscapeDataString(configurationId)}/versions/draft";

var response = await _httpClient.PutAsJsonAsync(uri, configurationVersion, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeploymentConfigurationVersion>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<WebDeployment> UpdateWebdeploymentsDeploymentAsync(string deploymentId, WebDeployment deployment, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);
ArgumentNullException.ThrowIfNull(deployment);

var uri = $"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}";

var response = await _httpClient.PutAsJsonAsync(uri, deployment, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WebDeployment>(_options.JsonSerializerOptions, cancellationToken);
}

/// <inheritdoc />
public async Task<IdentityResolutionConfig> UpdateWebdeploymentsDeploymentIdentityresolutionAsync(string deploymentId, IdentityResolutionConfig body, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrEmpty(deploymentId);
ArgumentNullException.ThrowIfNull(body);

var uri = $"/api/v2/webdeployments/deployments/{Uri.EscapeDataString(deploymentId)}/identityresolution";

var response = await _httpClient.PutAsJsonAsync(uri, body, _options.JsonSerializerOptions, cancellationToken);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<IdentityResolutionConfig>(_options.JsonSerializerOptions, cancellationToken);
}
}
Loading