Skip to content

Commit f830992

Browse files
committed
Updates to interactivity and setup.
1 parent 3c0854b commit f830992

File tree

3 files changed

+153
-111
lines changed

3 files changed

+153
-111
lines changed

dotnetv4/Redshift/Actions/RedshiftWrapper.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ namespace RedshiftActions;
1717
/// </summary>
1818
public class RedshiftWrapper
1919
{
20-
private readonly AmazonRedshiftClient _redshiftClient;
21-
private readonly AmazonRedshiftDataAPIServiceClient _redshiftDataClient;
20+
private readonly IAmazonRedshift _redshiftClient;
21+
private readonly IAmazonRedshiftDataAPIService _redshiftDataClient;
2222

2323
/// <summary>
2424
/// Constructor for RedshiftWrapper.
2525
/// </summary>
2626
/// <param name="redshiftClient">Amazon Redshift client.</param>
2727
/// <param name="redshiftDataClient">Amazon Redshift Data API client.</param>
28-
public RedshiftWrapper(AmazonRedshiftClient redshiftClient, AmazonRedshiftDataAPIServiceClient redshiftDataClient)
28+
public RedshiftWrapper(IAmazonRedshift redshiftClient, IAmazonRedshiftDataAPIService redshiftDataClient)
2929
{
3030
_redshiftClient = redshiftClient;
3131
_redshiftDataClient = redshiftDataClient;
@@ -468,12 +468,16 @@ private async Task WaitForStatementToCompleteAsync(string statementId)
468468
/// Wait for a cluster to become available.
469469
/// </summary>
470470
/// <param name="clusterIdentifier">The cluster identifier.</param>
471+
/// <param name="isInteractive">Whether to prompt for user input.</param>
471472
/// <returns>A task representing the asynchronous operation.</returns>
472-
public async Task WaitForClusterAvailableAsync(string clusterIdentifier)
473+
public async Task WaitForClusterAvailableAsync(string clusterIdentifier, bool isInteractive = true)
473474
{
474475
Console.WriteLine($"Wait until {clusterIdentifier} is available.");
475-
Console.WriteLine("Press Enter to continue...");
476-
Console.ReadLine();
476+
if (isInteractive)
477+
{
478+
Console.WriteLine("Press Enter to continue...");
479+
Console.ReadLine();
480+
}
477481

478482
Console.WriteLine("Waiting for cluster to become available. This may take a few minutes.");
479483

dotnetv4/Redshift/Scenarios/RedshiftBasics.cs

Lines changed: 140 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using System.Threading.Tasks;
99
using Amazon.Redshift;
1010
using Amazon.RedshiftDataAPIService;
11+
using Microsoft.Extensions.DependencyInjection;
12+
using Microsoft.Extensions.Hosting;
1113
using RedshiftActions;
1214

1315
namespace RedshiftBasics;
@@ -18,7 +20,8 @@ namespace RedshiftBasics;
1820
/// </summary>
1921
public class RedshiftBasics
2022
{
21-
private static RedshiftWrapper? _redshiftWrapper;
23+
public static bool IsInteractive = true;
24+
public static RedshiftWrapper? Wrapper = null;
2225
private static readonly string _moviesFilePath = "../../../../../../resources/sample_files/movies.json";
2326

2427
/// <summary>
@@ -27,116 +30,138 @@ public class RedshiftBasics
2730
/// <param name="args">Command line arguments.</param>
2831
public static async Task Main(string[] args)
2932
{
30-
// Initialize the Amazon Redshift clients
31-
var redshiftClient = new AmazonRedshiftClient();
32-
var redshiftDataClient = new AmazonRedshiftDataAPIServiceClient();
33-
_redshiftWrapper = new RedshiftWrapper(redshiftClient, redshiftDataClient);
34-
35-
Console.WriteLine(
36-
"================================================================================");
37-
Console.WriteLine("Welcome to the Amazon Redshift SDK Getting Started scenario.");
38-
Console.WriteLine(
39-
"This .NET program demonstrates how to interact with Amazon Redshift by using the AWS SDK for .NET.");
40-
Console.WriteLine(
41-
"Upon completion of the program, all resources are cleaned up.");
42-
Console.WriteLine("Let's get started...");
43-
Console.WriteLine(
44-
"================================================================================");
33+
using var host = Host.CreateDefaultBuilder(args)
34+
.ConfigureServices((_, services) =>
35+
services.AddAWSService<IAmazonRedshift>()
36+
.AddAWSService<IAmazonRedshiftDataAPIService>()
37+
.AddTransient<RedshiftWrapper>()
38+
)
39+
.Build();
4540

46-
try
47-
{
48-
await RunScenarioAsync();
49-
}
50-
catch (Exception ex)
51-
{
52-
Console.WriteLine($"An error occurred: {ex.Message}");
53-
Console.WriteLine(ex.StackTrace);
54-
}
55-
finally
56-
{
57-
redshiftClient.Dispose();
58-
redshiftDataClient.Dispose();
59-
}
41+
Wrapper = host.Services.GetRequiredService<RedshiftWrapper>();
42+
43+
await RunScenarioAsync();
6044
}
6145

6246
/// <summary>
6347
/// Run the complete Amazon Redshift scenario.
6448
/// </summary>
65-
private static async Task RunScenarioAsync()
49+
public static async Task RunScenarioAsync()
6650
{
67-
// Step 1: Get user credentials
68-
if (!File.Exists(_moviesFilePath))
69-
Console.WriteLine("filenotfound");
70-
71-
Console.WriteLine("Please enter your user name (default is awsuser):");
72-
var userName = Console.ReadLine();
73-
if (string.IsNullOrEmpty(userName))
74-
userName = "awsuser";
75-
76-
Console.WriteLine("================================================================================");
77-
Console.WriteLine("Please enter your user password (default is AwsUser1000):");
78-
var userPassword = Console.ReadLine();
79-
if (string.IsNullOrEmpty(userPassword))
80-
userPassword = "AwsUser1000";
81-
82-
Console.WriteLine("================================================================================");
83-
Console.WriteLine("A Redshift cluster refers to the collection of computing resources and storage that work together to process and analyze large volumes of data.");
84-
85-
// Step 2: Get cluster identifier
86-
Console.WriteLine("Enter a cluster id value (default is redshift-cluster-movies):");
87-
var clusterIdentifier = Console.ReadLine();
88-
if (string.IsNullOrEmpty(clusterIdentifier))
89-
clusterIdentifier = "redshift-cluster-movies";
90-
91-
var databaseName = "dev";
92-
9351
try
9452
{
53+
Console.WriteLine(
54+
"================================================================================");
55+
Console.WriteLine("Welcome to the Amazon Redshift SDK Getting Started scenario.");
56+
Console.WriteLine(
57+
"This .NET program demonstrates how to interact with Amazon Redshift by using the AWS SDK for .NET.");
58+
Console.WriteLine(
59+
"Upon completion of the program, all resources are cleaned up.");
60+
Console.WriteLine("Let's get started...");
61+
Console.WriteLine(
62+
"================================================================================");
63+
64+
// Set all variables to default values
65+
string userName = "awsuser";
66+
string userPassword = "AwsUser1000";
67+
string clusterIdentifier = "redshift-cluster-movies";
68+
var databaseName = "dev";
69+
int recordCount = 50;
70+
int year = 2013;
71+
72+
// Step 1: Get user credentials (if interactive)
73+
if (IsInteractive)
74+
{
75+
Console.WriteLine("Please enter your user name (default is awsuser):");
76+
var userInput = Console.ReadLine();
77+
if (!string.IsNullOrEmpty(userInput))
78+
userName = userInput;
79+
80+
Console.WriteLine("================================================================================");
81+
Console.WriteLine("Please enter your user password (default is AwsUser1000):");
82+
var passwordInput = Console.ReadLine();
83+
if (!string.IsNullOrEmpty(passwordInput))
84+
userPassword = passwordInput;
85+
86+
Console.WriteLine("================================================================================");
87+
Console.WriteLine("A Redshift cluster refers to the collection of computing resources and storage that work together to process and analyze large volumes of data.");
88+
89+
// Step 2: Get cluster identifier
90+
Console.WriteLine("Enter a cluster id value (default is redshift-cluster-movies):");
91+
var clusterInput = Console.ReadLine();
92+
if (!string.IsNullOrEmpty(clusterInput))
93+
clusterIdentifier = clusterInput;
94+
}
95+
else
96+
{
97+
Console.WriteLine($"Using default values: userName={userName}, clusterIdentifier={clusterIdentifier}");
98+
}
99+
95100
// Step 3: Create Redshift cluster
96-
await _redshiftWrapper!.CreateClusterAsync(clusterIdentifier, databaseName, userName, userPassword);
101+
await Wrapper!.CreateClusterAsync(clusterIdentifier, databaseName, userName, userPassword);
97102
Console.WriteLine("================================================================================");
98103

99104
// Step 4: Wait for cluster to become available
100105
Console.WriteLine("================================================================================");
101-
await _redshiftWrapper.WaitForClusterAvailableAsync(clusterIdentifier);
106+
await Wrapper.WaitForClusterAvailableAsync(clusterIdentifier, IsInteractive);
102107
Console.WriteLine("================================================================================");
103108

104109
// Step 5: List databases
105110
Console.WriteLine("================================================================================");
106111
Console.WriteLine($" When you created {clusterIdentifier}, the dev database is created by default and used in this scenario.");
107112
Console.WriteLine(" To create a custom database, you need to have a CREATEDB privilege.");
108113
Console.WriteLine(" For more information, see the documentation here: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html.");
109-
Console.WriteLine("Press Enter to continue...");
110-
Console.ReadLine();
114+
if (IsInteractive)
115+
{
116+
Console.WriteLine("Press Enter to continue...");
117+
Console.ReadLine();
118+
}
111119
Console.WriteLine("================================================================================");
112120

113121
Console.WriteLine("================================================================================");
114122
Console.WriteLine($"List databases in {clusterIdentifier}");
115-
Console.WriteLine("Press Enter to continue...");
116-
Console.ReadLine();
117-
await _redshiftWrapper.ListDatabasesAsync(clusterIdentifier, userName, databaseName);
123+
if (IsInteractive)
124+
{
125+
Console.WriteLine("Press Enter to continue...");
126+
Console.ReadLine();
127+
}
128+
await Wrapper.ListDatabasesAsync(clusterIdentifier, userName, databaseName);
118129
Console.WriteLine("================================================================================");
119130

120131
// Step 6: Create Movies table
121132
Console.WriteLine("================================================================================");
122133
Console.WriteLine("Now you will create a table named Movies.");
123-
Console.WriteLine("Press Enter to continue...");
124-
Console.ReadLine();
125-
await _redshiftWrapper.CreateTableAsync(clusterIdentifier, databaseName, userName);
134+
if (IsInteractive)
135+
{
136+
Console.WriteLine("Press Enter to continue...");
137+
Console.ReadLine();
138+
}
139+
await Wrapper.CreateTableAsync(clusterIdentifier, databaseName, userName);
126140
Console.WriteLine("================================================================================");
127141

128142
// Step 7: Populate the Movies table
129143
Console.WriteLine("================================================================================");
130144
Console.WriteLine("Populate the Movies table using the Movies.json file.");
131-
Console.WriteLine("Specify the number of records you would like to add to the Movies Table.");
132-
Console.WriteLine("Please enter a value between 50 and 200.");
133-
Console.Write("Enter a value: ");
134-
135-
var recordCountInput = Console.ReadLine();
136-
if (!int.TryParse(recordCountInput, out var recordCount) || recordCount < 50 || recordCount > 200)
145+
146+
if (IsInteractive)
137147
{
138-
recordCount = 50;
139-
Console.WriteLine($"Invalid input. Using default value of {recordCount}.");
148+
Console.WriteLine("Specify the number of records you would like to add to the Movies Table.");
149+
Console.WriteLine("Please enter a value between 50 and 200.");
150+
Console.Write("Enter a value: ");
151+
152+
var recordCountInput = Console.ReadLine();
153+
if (int.TryParse(recordCountInput, out var inputCount) && inputCount >= 50 && inputCount <= 200)
154+
{
155+
recordCount = inputCount;
156+
}
157+
else
158+
{
159+
Console.WriteLine($"Invalid input. Using default value of {recordCount}.");
160+
}
161+
}
162+
else
163+
{
164+
Console.WriteLine($"Using default record count: {recordCount}");
140165
}
141166

142167
await PopulateMoviesTableAsync(clusterIdentifier, databaseName, userName, recordCount);
@@ -146,55 +171,66 @@ private static async Task RunScenarioAsync()
146171
// Step 8 & 9: Query movies by year
147172
Console.WriteLine("================================================================================");
148173
Console.WriteLine("Query the Movies table by year. Enter a value between 2012-2014.");
149-
Console.Write("Enter a year: ");
150-
var yearInput = Console.ReadLine();
151-
if (!int.TryParse(yearInput, out var year) || year < 2012 || year > 2014)
174+
175+
if (IsInteractive)
176+
{
177+
Console.Write("Enter a year: ");
178+
var yearInput = Console.ReadLine();
179+
if (int.TryParse(yearInput, out var inputYear) && inputYear >= 2012 && inputYear <= 2014)
180+
{
181+
year = inputYear;
182+
}
183+
else
184+
{
185+
Console.WriteLine($"Invalid input. Using default value of {year}.");
186+
}
187+
}
188+
else
152189
{
153-
year = 2013;
154-
Console.WriteLine($"Invalid input. Using default value of {year}.");
190+
Console.WriteLine($"Using default year: {year}");
155191
}
156192

157-
await _redshiftWrapper.QueryMoviesByYearAsync(clusterIdentifier, databaseName, userName, year);
193+
await Wrapper.QueryMoviesByYearAsync(clusterIdentifier, databaseName, userName, year);
158194
Console.WriteLine("================================================================================");
159195

160196
// Step 10: Modify the cluster
161197
Console.WriteLine("================================================================================");
162198
Console.WriteLine("Now you will modify the Redshift cluster.");
163-
Console.WriteLine("Press Enter to continue...");
164-
Console.ReadLine();
165-
await _redshiftWrapper.ModifyClusterAsync(clusterIdentifier, "wed:07:30-wed:08:00");
199+
if (IsInteractive)
200+
{
201+
Console.WriteLine("Press Enter to continue...");
202+
Console.ReadLine();
203+
}
204+
await Wrapper.ModifyClusterAsync(clusterIdentifier, "wed:07:30-wed:08:00");
166205
Console.WriteLine("================================================================================");
167206

168207
// Step 11 & 12: Delete cluster confirmation
169208
Console.WriteLine("================================================================================");
170-
Console.WriteLine("Would you like to delete the Amazon Redshift cluster? (y/n)");
171-
var deleteResponse = Console.ReadLine();
172-
if (deleteResponse?.ToLower() == "y" || deleteResponse?.ToLower() == "yes")
209+
if (IsInteractive)
173210
{
174-
await _redshiftWrapper.DeleteClusterAsync(clusterIdentifier);
211+
Console.WriteLine("Would you like to delete the Amazon Redshift cluster? (y/n)");
212+
var deleteResponse = Console.ReadLine();
213+
if (deleteResponse?.ToLower() == "y" || deleteResponse?.ToLower() == "yes")
214+
{
215+
await Wrapper.DeleteClusterAsync(clusterIdentifier);
216+
}
175217
}
218+
else
219+
{
220+
Console.WriteLine("Deleting the Amazon Redshift cluster (non-interactive mode)...");
221+
await Wrapper.DeleteClusterAsync(clusterIdentifier);
222+
}
223+
Console.WriteLine("================================================================================");
224+
225+
Console.WriteLine("================================================================================");
226+
Console.WriteLine("This concludes the Amazon Redshift SDK Getting Started scenario.");
176227
Console.WriteLine("================================================================================");
177228
}
178229
catch (Exception ex)
179230
{
180231
Console.WriteLine($"An error occurred during the scenario: {ex.Message}");
181-
182-
// Attempt cleanup
183-
Console.WriteLine("Attempting to clean up resources...");
184-
try
185-
{
186-
await _redshiftWrapper!.DeleteClusterAsync(clusterIdentifier);
187-
}
188-
catch (Exception cleanupEx)
189-
{
190-
Console.WriteLine($"Cleanup failed: {cleanupEx.Message}");
191-
}
192232
throw;
193233
}
194-
195-
Console.WriteLine("================================================================================");
196-
Console.WriteLine("This concludes the Amazon Redshift SDK Getting Started scenario.");
197-
Console.WriteLine("================================================================================");
198234
}
199235

200236
/// <summary>
@@ -228,7 +264,7 @@ private static async Task PopulateMoviesTableAsync(string clusterIdentifier, str
228264
for (int i = 0; i < insertCount; i++)
229265
{
230266
var movie = movies[i];
231-
await _redshiftWrapper!.InsertMovieAsync(clusterIdentifier, database, dbUser, i, movie.Title, movie.Year);
267+
await Wrapper!.InsertMovieAsync(clusterIdentifier, database, dbUser, i, movie.Title, movie.Year);
232268
}
233269
}
234270

@@ -237,7 +273,6 @@ private static async Task PopulateMoviesTableAsync(string clusterIdentifier, str
237273
/// </summary>
238274
private class Movie
239275
{
240-
public int Id { get; set; }
241276
public string Title { get; set; } = string.Empty;
242277
public int Year { get; set; }
243278
}

dotnetv4/Redshift/Scenarios/RedshiftBasics.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12+
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="4.0.3.13" />
1213
<PackageReference Include="AWSSDK.Redshift" Version="4.0.4.1" />
1314
<PackageReference Include="AWSSDK.RedshiftDataAPIService" Version="4.0.3" />
15+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
16+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
1417
</ItemGroup>
1518

1619
<ItemGroup>

0 commit comments

Comments
 (0)