| 
 | 1 | +// Licensed to Elasticsearch B.V under one or more agreements.  | 
 | 2 | +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.  | 
 | 3 | +// See the LICENSE file in the project root for more information  | 
 | 4 | + | 
 | 5 | +using System.Text;  | 
 | 6 | +using Actions.Core.Services;  | 
 | 7 | +using Amazon.S3;  | 
 | 8 | +using Amazon.S3.Model;  | 
 | 9 | +using ConsoleAppFramework;  | 
 | 10 | +using Elastic.Markdown.CrossLinks;  | 
 | 11 | +using Microsoft.Extensions.Logging;  | 
 | 12 | + | 
 | 13 | +namespace Documentation.Assembler.Cli;  | 
 | 14 | + | 
 | 15 | +internal class LinkCommands(ILoggerFactory logger)  | 
 | 16 | +{  | 
 | 17 | +	private void AssignOutputLogger()  | 
 | 18 | +	{  | 
 | 19 | +		var log = logger.CreateLogger<Program>();  | 
 | 20 | +		ConsoleApp.Log = msg => log.LogInformation(msg);  | 
 | 21 | +		ConsoleApp.LogError = msg => log.LogError(msg);  | 
 | 22 | +	}  | 
 | 23 | + | 
 | 24 | +	/// <summary>  | 
 | 25 | +	/// Create an index.json file from all discovered links.json files in our S3 bucket  | 
 | 26 | +	/// </summary>  | 
 | 27 | +	/// <param name="ctx"></param>  | 
 | 28 | +	[Command("links create-index")]  | 
 | 29 | +	public async Task CreateLinkIndex(Cancel ctx = default)  | 
 | 30 | +	{  | 
 | 31 | +		AssignOutputLogger();  | 
 | 32 | + | 
 | 33 | +		IAmazonS3 client = new AmazonS3Client();  | 
 | 34 | +		var bucketName = "elastic-docs-link-index";  | 
 | 35 | +		var request = new ListObjectsV2Request { BucketName = bucketName, MaxKeys = 5 };  | 
 | 36 | + | 
 | 37 | +		Console.WriteLine("--------------------------------------");  | 
 | 38 | +		Console.WriteLine($"Listing the contents of {bucketName}:");  | 
 | 39 | +		Console.WriteLine("--------------------------------------");  | 
 | 40 | + | 
 | 41 | + | 
 | 42 | +		var linkIndex = new LinkIndex { Repositories = new Dictionary<string, Dictionary<string, LinkIndexEntry>>() };  | 
 | 43 | +		try  | 
 | 44 | +		{  | 
 | 45 | +			ListObjectsV2Response response;  | 
 | 46 | +			do  | 
 | 47 | +			{  | 
 | 48 | +				response = await client.ListObjectsV2Async(request, ctx);  | 
 | 49 | +				foreach (var obj in response.S3Objects)  | 
 | 50 | +				{  | 
 | 51 | +					if (!obj.Key.StartsWith("elastic/"))  | 
 | 52 | +						continue;  | 
 | 53 | + | 
 | 54 | +					var tokens = obj.Key.Split('/');  | 
 | 55 | +					if (tokens.Length < 3)  | 
 | 56 | +						continue;  | 
 | 57 | + | 
 | 58 | +					var repository = tokens[1];  | 
 | 59 | +					var branch = tokens[2];  | 
 | 60 | + | 
 | 61 | +					var entry = new LinkIndexEntry { Repository = repository, Branch = branch, ETag = obj.ETag.Trim('"'), Path = obj.Key };  | 
 | 62 | +					if (linkIndex.Repositories.TryGetValue(repository, out var existingEntry))  | 
 | 63 | +						existingEntry[branch] = entry;  | 
 | 64 | +					else  | 
 | 65 | +						linkIndex.Repositories.Add(repository, new Dictionary<string, LinkIndexEntry> { { branch, entry } });  | 
 | 66 | +					Console.WriteLine(entry);  | 
 | 67 | +				}  | 
 | 68 | + | 
 | 69 | +				// If the response is truncated, set the request ContinuationToken  | 
 | 70 | +				// from the NextContinuationToken property of the response.  | 
 | 71 | +				request.ContinuationToken = response.NextContinuationToken;  | 
 | 72 | +			} while (response.IsTruncated);  | 
 | 73 | +		}  | 
 | 74 | +		catch (AmazonS3Exception ex)  | 
 | 75 | +		{  | 
 | 76 | +			Console.WriteLine($"Error encountered on server. Message:'{ex.Message}' getting list of objects.");  | 
 | 77 | +		}  | 
 | 78 | + | 
 | 79 | +		var json = LinkIndex.Serialize(linkIndex);  | 
 | 80 | +		Console.WriteLine(json);  | 
 | 81 | + | 
 | 82 | +		using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));  | 
 | 83 | +		await client.UploadObjectFromStreamAsync(bucketName, "link-index.json", stream, new Dictionary<string, object>(), ctx);  | 
 | 84 | + | 
 | 85 | +		Console.WriteLine("Uploaded latest link-index.json");  | 
 | 86 | +	}  | 
 | 87 | +}  | 
0 commit comments