Skip to content

Commit 55fe249

Browse files
committed
Updates to scenario.
1 parent 781e8e7 commit 55fe249

File tree

3 files changed

+53
-105
lines changed

3 files changed

+53
-105
lines changed

dotnetv4/Redshift/Actions/RedshiftWrapper.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public RedshiftWrapper(AmazonRedshiftClient redshiftClient, AmazonRedshiftDataAP
4242
/// <param name="nodeType">The node type for the cluster.</param>
4343
/// <returns>The cluster that was created.</returns>
4444
public async Task<Cluster> CreateClusterAsync(string clusterIdentifier, string databaseName,
45-
string masterUsername, string masterUserPassword, string nodeType = "dc2.large")
45+
string masterUsername, string masterUserPassword, string nodeType = "ra3.large")
4646
{
4747
try
4848
{
@@ -159,15 +159,17 @@ public async Task<Cluster> DeleteClusterAsync(string clusterIdentifier)
159159
/// </summary>
160160
/// <param name="clusterIdentifier">The cluster identifier.</param>
161161
/// <param name="dbUser">The database user.</param>
162+
/// <param name="dbUser">The database name for authentication.</param>
162163
/// <returns>A list of database names.</returns>
163-
public async Task<List<string>> ListDatabasesAsync(string clusterIdentifier, string dbUser)
164+
public async Task<List<string>> ListDatabasesAsync(string clusterIdentifier, string dbUser, string databaseName)
164165
{
165166
try
166167
{
167168
var request = new ListDatabasesRequest
168169
{
169170
ClusterIdentifier = clusterIdentifier,
170-
DbUser = dbUser
171+
DbUser = dbUser,
172+
Database = databaseName
171173
};
172174

173175
var response = await _redshiftDataClient.ListDatabasesAsync(request);
@@ -231,7 +233,7 @@ year INTEGER NOT NULL
231233

232234
// snippet-start:[Redshift.dotnetv4.Insert]
233235
/// <summary>
234-
/// Insert a record into the Movies table.
236+
/// Insert a record into the Movies table using parameterized query.
235237
/// </summary>
236238
/// <param name="clusterIdentifier">The cluster identifier.</param>
237239
/// <param name="database">The database name.</param>
@@ -245,14 +247,20 @@ public async Task<string> InsertMovieAsync(string clusterIdentifier, string data
245247
{
246248
try
247249
{
248-
var sqlStatement = $"INSERT INTO Movies (id, title, year) VALUES ({id}, '{title}', {year})";
250+
var sqlStatement = "INSERT INTO Movies (id, title, year) VALUES (:id, :title, :year)";
249251

250252
var request = new ExecuteStatementRequest
251253
{
252254
ClusterIdentifier = clusterIdentifier,
253255
Database = database,
254256
DbUser = dbUser,
255-
Sql = sqlStatement
257+
Sql = sqlStatement,
258+
Parameters = new List<SqlParameter>
259+
{
260+
new SqlParameter { Name = "id", Value = id.ToString() },
261+
new SqlParameter { Name = "title", Value = title },
262+
new SqlParameter { Name = "year", Value = year.ToString() }
263+
}
256264
};
257265

258266
var response = await _redshiftDataClient.ExecuteStatementAsync(request);
@@ -270,7 +278,7 @@ public async Task<string> InsertMovieAsync(string clusterIdentifier, string data
270278

271279
// snippet-start:[Redshift.dotnetv4.Query]
272280
/// <summary>
273-
/// Query movies by year.
281+
/// Query movies by year using parameterized query.
274282
/// </summary>
275283
/// <param name="clusterIdentifier">The cluster identifier.</param>
276284
/// <param name="database">The database name.</param>
@@ -282,14 +290,18 @@ public async Task<List<string>> QueryMoviesByYearAsync(string clusterIdentifier,
282290
{
283291
try
284292
{
285-
var sqlStatement = $"SELECT title FROM Movies WHERE year = {year}";
293+
var sqlStatement = "SELECT title FROM Movies WHERE year = :year";
286294

287295
var request = new ExecuteStatementRequest
288296
{
289297
ClusterIdentifier = clusterIdentifier,
290298
Database = database,
291299
DbUser = dbUser,
292-
Sql = sqlStatement
300+
Sql = sqlStatement,
301+
Parameters = new List<SqlParameter>
302+
{
303+
new SqlParameter { Name = "year", Value = year.ToString() }
304+
}
293305
};
294306

295307
var response = await _redshiftDataClient.ExecuteStatementAsync(request);
@@ -380,11 +392,12 @@ public async Task<List<List<Field>>> GetStatementResultAsync(string statementId)
380392
private async Task WaitForStatementToCompleteAsync(string statementId)
381393
{
382394
var status = StatusString.SUBMITTED;
395+
DescribeStatementResponse? response = null;
383396

384397
while (status == StatusString.SUBMITTED || status == StatusString.PICKED || status == StatusString.STARTED)
385398
{
386399
await Task.Delay(1000); // Wait 1 second
387-
var response = await DescribeStatementAsync(statementId);
400+
response = await DescribeStatementAsync(statementId);
388401
status = response.Status;
389402
Console.WriteLine($"...{status}");
390403
}
@@ -395,8 +408,10 @@ private async Task WaitForStatementToCompleteAsync(string statementId)
395408
}
396409
else
397410
{
411+
var errorMessage = response?.Error ?? "Unknown error";
398412
Console.WriteLine($"The statement failed with status: {status}");
399-
throw new Exception($"Statement execution failed with status: {status}");
413+
Console.WriteLine($"Error message: {errorMessage}");
414+
throw new Exception($"Statement execution failed with status: {status}. Error: {errorMessage}");
400415
}
401416
}
402417

dotnetv4/Redshift/Scenarios/RedshiftBasics.cs

Lines changed: 24 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace RedshiftBasics;
1919
public class RedshiftBasics
2020
{
2121
private static RedshiftWrapper? _redshiftWrapper;
22-
private static readonly string MoviesFilePath = "../../../../../../../resources/sample_files/movies.json";
22+
private static readonly string _moviesFilePath = "../../../../../../resources/sample_files/movies.json";
2323

2424
/// <summary>
2525
/// Main method for the Amazon Redshift Getting Started scenario.
@@ -32,16 +32,16 @@ public static async Task Main(string[] args)
3232
var redshiftDataClient = new AmazonRedshiftDataAPIServiceClient();
3333
_redshiftWrapper = new RedshiftWrapper(redshiftClient, redshiftDataClient);
3434

35-
Console.WriteLine("================================================================================");
35+
Console.WriteLine(
36+
"================================================================================");
3637
Console.WriteLine("Welcome to the Amazon Redshift SDK Getting Started scenario.");
37-
Console.WriteLine("This .NET program demonstrates how to interact with Amazon Redshift by using the AWS SDK for .NET.");
38-
Console.WriteLine("Amazon Redshift is a fully managed, petabyte-scale data warehouse service hosted in the cloud.");
39-
Console.WriteLine("The program's primary functionality includes cluster creation, verification of cluster readiness,");
40-
Console.WriteLine("list databases, table creation, data population within the table, and execution of SQL statements.");
41-
Console.WriteLine("Furthermore, it demonstrates the process of querying data from the Movie table.");
42-
Console.WriteLine("Upon completion of the program, all AWS resources are cleaned up.");
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.");
4342
Console.WriteLine("Let's get started...");
44-
Console.WriteLine("================================================================================");
43+
Console.WriteLine(
44+
"================================================================================");
4545

4646
try
4747
{
@@ -65,6 +65,9 @@ public static async Task Main(string[] args)
6565
private static async Task RunScenarioAsync()
6666
{
6767
// Step 1: Get user credentials
68+
if (!File.Exists(_moviesFilePath))
69+
Console.WriteLine("filenotfound");
70+
6871
Console.WriteLine("Please enter your user name (default is awsuser):");
6972
var userName = Console.ReadLine();
7073
if (string.IsNullOrEmpty(userName))
@@ -76,7 +79,6 @@ private static async Task RunScenarioAsync()
7679
if (string.IsNullOrEmpty(userPassword))
7780
userPassword = "AwsUser1000";
7881

79-
Console.WriteLine("================================================================================");
8082
Console.WriteLine("================================================================================");
8183
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.");
8284

@@ -112,7 +114,7 @@ private static async Task RunScenarioAsync()
112114
Console.WriteLine($"List databases in {clusterIdentifier}");
113115
Console.WriteLine("Press Enter to continue...");
114116
Console.ReadLine();
115-
await _redshiftWrapper.ListDatabasesAsync(clusterIdentifier, userName);
117+
await _redshiftWrapper.ListDatabasesAsync(clusterIdentifier, userName, databaseName);
116118
Console.WriteLine("================================================================================");
117119

118120
// Step 6: Create Movies table
@@ -204,99 +206,29 @@ private static async Task RunScenarioAsync()
204206
/// <param name="recordCount">Number of records to insert.</param>
205207
private static async Task PopulateMoviesTableAsync(string clusterIdentifier, string database, string dbUser, int recordCount)
206208
{
207-
try
208-
{
209-
if (!File.Exists(MoviesFilePath))
210-
{
211-
Console.WriteLine($"Movies file not found at {MoviesFilePath}. Using sample data instead.");
212-
await PopulateWithSampleDataAsync(clusterIdentifier, database, dbUser, recordCount);
213-
return;
214-
}
215-
216-
var jsonContent = await File.ReadAllTextAsync(MoviesFilePath);
217-
var movies = JsonSerializer.Deserialize<List<Movie>>(jsonContent);
218-
219-
if (movies == null)
220-
{
221-
Console.WriteLine("Failed to parse movies JSON file. Using sample data instead.");
222-
await PopulateWithSampleDataAsync(clusterIdentifier, database, dbUser, recordCount);
223-
return;
224-
}
225-
226-
var insertCount = Math.Min(recordCount, movies.Count);
227-
228-
for (int i = 0; i < insertCount; i++)
229-
{
230-
var movie = movies[i];
231-
await _redshiftWrapper!.InsertMovieAsync(clusterIdentifier, database, dbUser, movie.Id, movie.Title, movie.Year);
232-
}
233-
}
234-
catch (Exception ex)
209+
if (!File.Exists(_moviesFilePath))
235210
{
236-
Console.WriteLine($"Error populating movies table: {ex.Message}");
237-
Console.WriteLine("Using sample data instead.");
238-
await PopulateWithSampleDataAsync(clusterIdentifier, database, dbUser, recordCount);
211+
throw new FileNotFoundException($"Required movies data file not found at: {_moviesFilePath}");
239212
}
240-
}
241213

242-
/// <summary>
243-
/// Populate the table with sample movie data when JSON file is not available.
244-
/// </summary>
245-
/// <param name="clusterIdentifier">The cluster identifier.</param>
246-
/// <param name="database">The database name.</param>
247-
/// <param name="dbUser">The database user.</param>
248-
/// <param name="recordCount">Number of records to insert.</param>
249-
private static async Task PopulateWithSampleDataAsync(string clusterIdentifier, string database, string dbUser, int recordCount)
250-
{
251-
var sampleMovies = new List<Movie>
214+
var jsonContent = await File.ReadAllTextAsync(_moviesFilePath);
215+
var options = new JsonSerializerOptions
252216
{
253-
new Movie { Id = 1, Title = "Rush", Year = 2013 },
254-
new Movie { Id = 2, Title = "Prisoners", Year = 2013 },
255-
new Movie { Id = 3, Title = "The Hunger Games: Catching Fire", Year = 2013 },
256-
new Movie { Id = 4, Title = "Thor: The Dark World", Year = 2013 },
257-
new Movie { Id = 5, Title = "This Is the End", Year = 2013 },
258-
new Movie { Id = 6, Title = "Despicable Me 2", Year = 2013 },
259-
new Movie { Id = 7, Title = "Man of Steel", Year = 2013 },
260-
new Movie { Id = 8, Title = "Gravity", Year = 2013 },
261-
new Movie { Id = 9, Title = "Pacific Rim", Year = 2013 },
262-
new Movie { Id = 10, Title = "World War Z", Year = 2013 },
263-
new Movie { Id = 11, Title = "Iron Man 3", Year = 2013 },
264-
new Movie { Id = 12, Title = "Star Trek Into Darkness", Year = 2013 },
265-
new Movie { Id = 13, Title = "Fast & Furious 6", Year = 2013 },
266-
new Movie { Id = 14, Title = "Monsters University", Year = 2013 },
267-
new Movie { Id = 15, Title = "Elysium", Year = 2013 },
268-
new Movie { Id = 16, Title = "The Hobbit: The Desolation of Smaug", Year = 2013 },
269-
new Movie { Id = 17, Title = "Captain Phillips", Year = 2013 },
270-
new Movie { Id = 18, Title = "Ender's Game", Year = 2013 },
271-
new Movie { Id = 19, Title = "The Wolverine", Year = 2013 },
272-
new Movie { Id = 20, Title = "Now You See Me", Year = 2013 }
217+
PropertyNameCaseInsensitive = true
273218
};
219+
var movies = JsonSerializer.Deserialize<List<Movie>>(jsonContent, options);
274220

275-
// Generate more movies if needed
276-
var movieList = new List<Movie>(sampleMovies);
277-
var random = new Random();
278-
var years = new[] { 2012, 2013, 2014 };
279-
var baseMovieTitles = new[] { "Action Movie", "Drama Film", "Comedy Show", "Thriller Movie", "Adventure Film", "Sci-Fi Movie", "Horror Film" };
280-
281-
while (movieList.Count < recordCount)
221+
if (movies == null || movies.Count == 0)
282222
{
283-
var baseTitle = baseMovieTitles[random.Next(baseMovieTitles.Length)];
284-
var year = years[random.Next(years.Length)];
285-
var movie = new Movie
286-
{
287-
Id = movieList.Count + 1,
288-
Title = $"{baseTitle} {movieList.Count + 1}",
289-
Year = year
290-
};
291-
movieList.Add(movie);
223+
throw new InvalidOperationException("Failed to parse movies JSON file or file is empty.");
292224
}
293225

294-
var insertCount = Math.Min(recordCount, movieList.Count);
226+
var insertCount = Math.Min(recordCount, movies.Count);
295227

296228
for (int i = 0; i < insertCount; i++)
297229
{
298-
var movie = movieList[i];
299-
await _redshiftWrapper!.InsertMovieAsync(clusterIdentifier, database, dbUser, movie.Id, movie.Title, movie.Year);
230+
var movie = movies[i];
231+
await _redshiftWrapper!.InsertMovieAsync(clusterIdentifier, database, dbUser, i, movie.Title, movie.Year);
300232
}
301233
}
302234

dotnetv4/Redshift/Tests/RedshiftIntegrationTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public async Task RedshiftFullWorkflow_Integration_CompletesSuccessfully()
9999

100100
// Step 3: List databases
101101
Console.WriteLine("Listing databases...");
102-
var databases = await _redshiftWrapper.ListDatabasesAsync(_testClusterIdentifier!, TestUsername);
102+
var databases = await _redshiftWrapper.ListDatabasesAsync(_testClusterIdentifier!, TestUsername, TestDatabaseName);
103103
Assert.IsNotNull(databases);
104104
Assert.IsTrue(databases.Count > 0);
105105
Console.WriteLine($"Found {databases.Count} databases.");
@@ -343,7 +343,8 @@ public async Task ListDatabases_WithExistingCluster_ReturnsResults()
343343
{
344344
var databases = await _redshiftWrapper.ListDatabasesAsync(
345345
availableCluster.ClusterIdentifier,
346-
TestUsername);
346+
TestUsername,
347+
TestDatabaseName);
347348

348349
Assert.IsNotNull(databases);
349350
Console.WriteLine($"Found {databases.Count} databases in cluster {availableCluster.ClusterIdentifier}");

0 commit comments

Comments
 (0)