Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added PrintFromProcess/OrdersInDB.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added PrintFromProcess/PostMethodWorking.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added PrintFromProcess/UpdateProcessFlagToFalse.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ Note in Every command and URL being called there are fields that need to be repl

Example replacements (make sure to replace the curly brackets as well: don't keep curly brackets)

`{studentName}` - example `ajdewilzin` - this can be your name, independent of your login details
`VictorChicinas` - example `ajdewilzin` - this can be your name, independent of your login details

`{region}` - example `eu-north-1`
`eu-north-1` - example `eu-north-1`

### Steps
1. Create an SNS Topic:

```bash
aws sns create-topic --name {studentName}OrderCreatedTopic
aws sns create-topic --name VictorChicinasOrderCreatedTopic
```
If successful, you will see in your terminal a JSON response that includes `"TopicArn": "...`.

Expand All @@ -22,7 +22,7 @@ Replace `_topicArn` in your Controller code with the generated `TopicArn` value
2. Create an SQS Queue:

```bash
aws sqs create-queue --queue-name {studentName}OrderQueue
aws sqs create-queue --queue-name VictorChicinasOrderQueue
```

If successful, you will see in your terminal a JSON response that includes `"QueueUrl": "some_aws_url`.
Expand All @@ -31,21 +31,21 @@ Replace `_queueUrl` in your Controller code with the generated `QueueUrl` from t


```bash
aws sns subscribe --topic-arn arn:aws:sns:{region}:637423341661:{studentName}OrderCreatedTopic --protocol sqs --notification-endpoint arn:aws:sqs:{region}:637423341661:{studentName}OrderQueue
aws sns subscribe --topic-arn arn:aws:sns:eu-north-1:637423341661:VictorChicinasOrderCreatedTopic --protocol sqs --notification-endpoint arn:aws:sqs:eu-north-1:637423341661:VictorChicinasOrderQueue
```

You don't need to save the generated SubscriptionArn.

3. Create an EventBridge Event Bus:

```bash
aws events create-event-bus --name {StudentName}CustomEventBus --region {region}
aws events create-event-bus --name VictorChicinasCustomEventBus --region eu-north-1
```

4. Create an EventBridge Rule:

```bash
aws events put-rule --name {StudentName}OrderProcessedRule --event-pattern '{\"source\": [\"order.service\"]}' --event-bus-name {StudentName}CustomEventBus
aws events put-rule --name VictorChicinasOrderProcessedRule --event-pattern '{\"source\": [\"order.service\"]}' --event-bus-name VictorChicinasCustomEventBus
```

If your terminal complains about double quotes, you might need to remove the backslash `\` from the command above (and commands later on).
Expand All @@ -54,19 +54,19 @@ If your terminal complains about double quotes, you might need to remove the bac
5. Subscribe the SQS Queue to the SNS Topic

```bash
aws sqs get-queue-attributes --queue-url https://sqs.{region}.amazonaws.com/637423341661/{studentName}OrderQueue --attribute-name QueueArn --region {region}
aws sqs get-queue-attributes --queue-url https://sqs.eu-north-1.amazonaws.com/637423341661/VictorChicinasOrderQueue --attribute-name QueueArn --region eu-north-1
```

```bash
aws sns subscribe --topic-arn arn:aws:sns:{region}:637423341661:{studentName}OrderCreatedTopic --protocol sqs --notification-endpoint arn:aws:sqs:{region}:637423341661:{studentName}OrderQueue --region {region}
aws sns subscribe --topic-arn arn:aws:sns:eu-north-1:637423341661:VictorChicinasOrderCreatedTopic --protocol sqs --notification-endpoint arn:aws:sqs:eu-north-1:637423341661:VictorChicinasOrderQueue --region eu-north-1
```

6. Grant SNS Permissions to SQS


In Bash/Unix terminals you can run this command:
```bash
aws sqs set-queue-attributes --queue-url https://sqs.{region}.amazonaws.com/637423341661/{studentName}OrderQueue --attributes '{"Policy":"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"SQS:SendMessage\",\"Resource\":\"arn:aws:sqs:{region}:637423341661:{studentName}OrderQueue\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"arn:aws:sns:{region}:637423341661:{studentName}OrderCreatedTopic\"}}}]}"}' --region {region}
aws sqs set-queue-attributes --queue-url https://sqs.eu-north-1.amazonaws.com/637423341661/VictorChicinasOrderQueue --attributes '{"Policy":"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"SQS:SendMessage\",\"Resource\":\"arn:aws:sqs:eu-north-1:637423341661:VictorChicinasOrderQueue\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"arn:aws:sns:eu-north-1:637423341661:VictorChicinasOrderCreatedTopic\"}}}]}"}' --region eu-north-1
```


Expand Down
136 changes: 86 additions & 50 deletions WorkshopBackend/OrderService/Controllers/OrderController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Amazon.EventBridge.Model;
using System.Text.Json;
using InventoryService.Models;
using Npgsql;

[ApiController]
[Route("[controller]")]
Expand All @@ -15,8 +16,9 @@ public class OrderController : ControllerBase
private readonly IAmazonSQS _sqs;
private readonly IAmazonSimpleNotificationService _sns;
private readonly IAmazonEventBridge _eventBridge;
private readonly string _queueUrl = ""; // Format of https://.*
private readonly string _topicArn = ""; // Format of arn:aws.*
private readonly string _queueUrl = "https://sqs.eu-north-1.amazonaws.com/637423341661/VictorChicinasOrderQueue"; // Format of https://.*
private readonly string _topicArn = "arn:aws:sns:eu-north-1:637423341661:VictorChicinasOrderCreatedTopic"; // Format of arn:aws.*
private readonly string _connectionString = "Host=aaaa-database-2-victorchicinas.cr4y6a6oo1h9.eu-north-1.rds.amazonaws.com;Port=5432;Database=aaaa-database-2-victorchicinas;User Id=postgres;Password=NewPasswordToAWS";

public OrderController()
{
Expand All @@ -29,68 +31,102 @@ public OrderController()
[HttpGet]
public async Task<IActionResult> GetOrdersAndProcess()
{
/*
* AmazonSQSClient
*
*/
var request = new ReceiveMessageRequest
try
{
QueueUrl = _queueUrl,
MaxNumberOfMessages = 10,
WaitTimeSeconds = 20
};
// Receive messages from the SQS queue
var request = new ReceiveMessageRequest
{
QueueUrl = _queueUrl,
MaxNumberOfMessages = 10,
WaitTimeSeconds = 20
};

var response = await _sqs.ReceiveMessageAsync(request);
var response = await _sqs.ReceiveMessageAsync(request);

foreach (var message in response.Messages)
{
var order = JsonSerializer.Deserialize<Order>(message.Body);
// Process order (e.g., update inventory)
foreach (var message in response.Messages)
{
var order = JsonSerializer.Deserialize<Order>(message.Body);

// Process order: Calculate total and mark as processed
order.Total = order.Quantity * order.Amount;
order.Processed = true;

// Update the order in the database
using (var connection = new NpgsqlConnection(_connectionString))
{
await connection.OpenAsync();
var query = "UPDATE Orders SET total = @Total, processed = @Processed WHERE orderId = @OrderId";
using (var command = new NpgsqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Total", order.Total);
command.Parameters.AddWithValue("@Processed", order.Processed);
command.Parameters.AddWithValue("@OrderId", order.OrderId);
await command.ExecuteNonQueryAsync();
}
}

// Delete message after processing
await _sqs.DeleteMessageAsync(_queueUrl, message.ReceiptHandle);
// Delete message after processing
await _sqs.DeleteMessageAsync(_queueUrl, message.ReceiptHandle);
}

return Ok(new { Status = $"{response.Messages.Count()} Orders have been processed" });
}
catch (Exception ex)
{
// Log the exception (you can use a logging framework here)
return StatusCode(500, $"Internal server error: {ex.Message}");
}
return Ok(new { Status = $"{response.Messages.Count()}Order have been processed" });
}

[HttpPost]
public async Task<IActionResult> CreateOrder([FromBody] Order order)
{
/*
* AmazonSimpleNotificationServiceClient
*
*/
// Publish to SNS
var message = JsonSerializer.Serialize(order);
var publishRequest = new PublishRequest
try
{
TopicArn = _topicArn,
Message = message
};
// Insert the order into the database
using (var connection = new NpgsqlConnection(_connectionString))
{
await connection.OpenAsync();
var query = "INSERT INTO Orders (product, quantity, amount, processed, total) VALUES (@Product, @Quantity, @Amount, @Processed, @Total)";
using (var command = new NpgsqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Product", order.Product);
command.Parameters.AddWithValue("@Quantity", order.Quantity);
command.Parameters.AddWithValue("@Amount", order.Amount);
command.Parameters.AddWithValue("@Processed", order.Processed ?? false);
command.Parameters.AddWithValue("@Total", order.Quantity * order.Amount);
await command.ExecuteNonQueryAsync();
}
}

await _sns.PublishAsync(publishRequest);
// Publish the order to SNS
var message = JsonSerializer.Serialize(order);
var publishRequest = new PublishRequest
{
TopicArn = _topicArn,
Message = message
};
await _sns.PublishAsync(publishRequest);

// Send an event to EventBridge
var eventEntry = new PutEventsRequestEntry
{
Source = "order.service",
DetailType = "OrderCreated",
Detail = JsonSerializer.Serialize(order),
EventBusName = "CustomEventBus"
};
var putEventsRequest = new PutEventsRequest
{
Entries = new List<PutEventsRequestEntry> { eventEntry }
};
await _eventBridge.PutEventsAsync(putEventsRequest);

/*
* AmazonEventBridgeClient
*
*/
// Publish to EventBridge
var eventEntry = new PutEventsRequestEntry
{
Source = "order.service",
DetailType = "OrderCreated",
Detail = JsonSerializer.Serialize(order),
EventBusName = "CustomEventBus"
};

var putEventsRequest = new PutEventsRequest
return Ok(new { Status = "Order Created, Message Published to SNS and Event Emitted to EventBridge" });
}
catch (Exception ex)
{
Entries = new List<PutEventsRequestEntry> { eventEntry }
};

await _eventBridge.PutEventsAsync(putEventsRequest);

return Ok(new { Status = "Order Created, Message Published to SNS and Event Emitted to EventBridge" });
return StatusCode(500, $"Internal server error: {ex.Message}");
}
}
}
1 change: 1 addition & 0 deletions WorkshopBackend/OrderService/OrderService.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageReference Include="AWSSDK.SimpleNotificationService" Version="3.7.400.34" />
<PackageReference Include="AWSSDK.SQS" Version="3.7.400.34" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7" />
<PackageReference Include="Npgsql" Version="8.0.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

Expand Down
3 changes: 2 additions & 1 deletion WorkshopBackend/OrderService/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",

}
3 changes: 3 additions & 0 deletions conf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"SQS:SendMessage\",\"Resource\":\"arn:aws:sqs:eu-north-1:637423341661:VictorChicinasOrderQueue\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"arn:aws:sns:eu-north-1:637423341661:VictorChicinasOrderCreatedTopic\"}}}]}"
}