Skip to content

Commit 7164ded

Browse files
committed
Avoid crashing update-redirects when CLI output is empty
1 parent abfa6a4 commit 7164ded

File tree

1 file changed

+40
-10
lines changed

1 file changed

+40
-10
lines changed

src/services/Elastic.Documentation.Assembler/Deploying/Redirects/AwsCloudFrontKeyValueStoreProxy.cs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ public void UpdateRedirects(string kvsName, IReadOnlyDictionary<string, string>
3131
if (string.IsNullOrEmpty(eTag))
3232
return;
3333

34-
var existingRedirects = ListAllKeys(kvsArn);
34+
var listingSuccessful = TryListAllKeys(kvsArn, out var existingRedirects);
35+
36+
if (!listingSuccessful)
37+
return;
3538

3639
var toPut = sourcedRedirects
3740
.Select(kvp => new PutKeyRequestListItem { Key = kvp.Key, Value = kvp.Value })
@@ -51,7 +54,14 @@ private string DescribeKeyValueStore(string kvsName)
5154
try
5255
{
5356
var json = CaptureMultiple("aws", "cloudfront", "describe-key-value-store", "--name", kvsName);
54-
var describeResponse = JsonSerializer.Deserialize<DescribeKeyValueStoreResponse>(string.Concat(json), AwsCloudFrontKeyValueStoreJsonContext.Default.DescribeKeyValueStoreResponse);
57+
var concatJson = string.Concat(json);
58+
if (string.IsNullOrWhiteSpace(concatJson))
59+
{
60+
Collector.EmitError("", "The output from cloudfront:describe-key-value-store was empty");
61+
return string.Empty;
62+
}
63+
64+
var describeResponse = JsonSerializer.Deserialize<DescribeKeyValueStoreResponse>(concatJson, AwsCloudFrontKeyValueStoreJsonContext.Default.DescribeKeyValueStoreResponse);
5565
if (describeResponse?.KeyValueStore is { ARN.Length: > 0 })
5666
return describeResponse.KeyValueStore.ARN;
5767

@@ -71,7 +81,13 @@ private string AcquireETag(string kvsArn)
7181
try
7282
{
7383
var json = CaptureMultiple("aws", "cloudfront-keyvaluestore", "describe-key-value-store", "--kvs-arn", kvsArn);
74-
var describeResponse = JsonSerializer.Deserialize<DescribeKeyValueStoreResponse>(string.Concat(json), AwsCloudFrontKeyValueStoreJsonContext.Default.DescribeKeyValueStoreResponse);
84+
var concatJson = string.Concat(json);
85+
if (string.IsNullOrWhiteSpace(concatJson))
86+
{
87+
Collector.EmitError("", "The output from cloudfront-keyvaluestore:describe-key-value-store was empty");
88+
return string.Empty;
89+
}
90+
var describeResponse = JsonSerializer.Deserialize<DescribeKeyValueStoreResponse>(concatJson, AwsCloudFrontKeyValueStoreJsonContext.Default.DescribeKeyValueStoreResponse);
7591
if (describeResponse?.ETag is not null)
7692
return describeResponse.ETag;
7793

@@ -85,23 +101,29 @@ private string AcquireETag(string kvsArn)
85101
}
86102
}
87103

88-
private HashSet<string> ListAllKeys(string kvsArn)
104+
private bool TryListAllKeys(string kvsArn, out HashSet<string> keys)
89105
{
90106
_logger.LogInformation("Acquiring existing redirects");
91-
var allKeys = new HashSet<string>();
107+
keys = [];
92108
string[] baseArgs = ["cloudfront-keyvaluestore", "list-keys", "--kvs-arn", kvsArn, "--page-size", "50", "--max-items", "50"];
93109
string? nextToken = null;
94110
try
95111
{
96112
do
97113
{
98114
var json = CaptureMultiple("aws", [.. baseArgs, .. nextToken is not null ? (string[])["--starting-token", nextToken] : []]);
99-
var response = JsonSerializer.Deserialize<ListKeysResponse>(string.Concat(json), AwsCloudFrontKeyValueStoreJsonContext.Default.ListKeysResponse);
115+
var concatJson = string.Concat(json);
116+
if (string.IsNullOrWhiteSpace(concatJson))
117+
{
118+
Collector.EmitError("", "The output from cloudfront-keyvaluestore:list-keys was empty");
119+
throw new JsonException("Empty output from cloudfront-keyvaluestore:list-keys");
120+
}
121+
var response = JsonSerializer.Deserialize<ListKeysResponse>(concatJson, AwsCloudFrontKeyValueStoreJsonContext.Default.ListKeysResponse);
100122

101123
if (response?.Items != null)
102124
{
103125
foreach (var item in response.Items)
104-
_ = allKeys.Add(item.Key);
126+
_ = keys.Add(item.Key);
105127
}
106128

107129
nextToken = response?.NextToken;
@@ -110,9 +132,9 @@ private HashSet<string> ListAllKeys(string kvsArn)
110132
catch (Exception e)
111133
{
112134
Collector.EmitError("", "An error occurred while acquiring existing redirects in the KeyValueStore", e);
113-
return [];
135+
return false;
114136
}
115-
return allKeys;
137+
return true;
116138
}
117139

118140

@@ -138,7 +160,15 @@ private string ProcessBatchUpdates(
138160
};
139161
var responseJson = CaptureMultiple(false, 1, "aws", "cloudfront-keyvaluestore", "update-keys", "--kvs-arn", kvsArn, "--if-match", eTag,
140162
$"--{operation.ToString().ToLowerInvariant()}", payload);
141-
var updateResponse = JsonSerializer.Deserialize<UpdateKeysResponse>(string.Concat(responseJson), AwsCloudFrontKeyValueStoreJsonContext.Default.UpdateKeysResponse);
163+
164+
var concatJson = string.Concat(responseJson);
165+
if (string.IsNullOrWhiteSpace(concatJson))
166+
{
167+
Collector.EmitError("", "The output from cloudfront-keyvaluestore:update-keys was empty");
168+
throw new JsonException("Empty output from cloudfront-keyvaluestore:update-keys");
169+
}
170+
171+
var updateResponse = JsonSerializer.Deserialize<UpdateKeysResponse>(concatJson, AwsCloudFrontKeyValueStoreJsonContext.Default.UpdateKeysResponse);
142172

143173
if (string.IsNullOrEmpty(updateResponse?.ETag))
144174
throw new Exception("Failed to get new ETag after update operation.");

0 commit comments

Comments
 (0)