Skip to content

Commit 1230487

Browse files
Begun implementation of SNS subscription support
1 parent fce99dd commit 1230487

File tree

12 files changed

+324
-23
lines changed

12 files changed

+324
-23
lines changed

GuiStack/Authentication/Authenticator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*
6-
* Copyright © Vincent Bengtsson & Contributors 2022
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
77
* https://github.com/Visual-Vincent/GuiStack
88
*/
99

@@ -24,7 +24,7 @@ public abstract class Authenticator<TCredentials, TAuthenticatedClient>
2424
/// <param name="credentials">The credentials used to authenticated with the API or SDK.</param>
2525
public TAuthenticatedClient Authenticate()
2626
{
27-
return Authenticate(GetCredentials());
27+
return Authenticate(GetCredentials());
2828
}
2929

3030
/// <summary>

GuiStack/Models/SNSSubscription.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
7+
* https://github.com/Visual-Vincent/GuiStack
8+
*/
9+
10+
using System;
11+
using Amazon;
12+
13+
namespace GuiStack.Models
14+
{
15+
public class SNSSubscription
16+
{
17+
public Arn Arn { get; set; }
18+
public Arn TopicARN { get; set; }
19+
public string Protocol { get; set; }
20+
public string Endpoint { get; set; }
21+
public string Owner { get; set; }
22+
23+
public SNSSubscription()
24+
{
25+
}
26+
27+
public SNSSubscription(string arn, string topicArn, string protocol, string endpoint, string owner)
28+
{
29+
Arn = Arn.Parse(arn);
30+
TopicARN = Arn.Parse(topicArn);
31+
Protocol = protocol;
32+
Endpoint = endpoint;
33+
Owner = owner;
34+
}
35+
}
36+
}

GuiStack/Models/SNSTopicModel.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
7+
* https://github.com/Visual-Vincent/GuiStack
8+
*/
9+
10+
using System;
11+
using System.Collections.Generic;
12+
13+
namespace GuiStack.Models
14+
{
15+
public class SNSTopicModel
16+
{
17+
public SNSTopicInfo Topic { get; set; }
18+
public IEnumerable<SNSSubscription> Subscriptions { get; set; }
19+
20+
public SNSTopicModel(SNSTopicInfo topicInfo, IEnumerable<SNSSubscription> subscriptions)
21+
{
22+
Topic = topicInfo;
23+
Subscriptions = subscriptions;
24+
}
25+
}
26+
}

GuiStack/Pages/SNS/Index.cshtml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*
6-
* Copyright © Vincent Bengtsson & Contributors 2022-2023
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
77
* https://github.com/Visual-Vincent/GuiStack
88
*@
99

1010
@page "{topic?}"
1111

1212
@using System.Net
1313
@using Amazon.SimpleNotificationService
14+
@using GuiStack.Models;
1415
@model GuiStack.Pages.SNS.IndexModel
1516

1617
@{
@@ -67,7 +68,10 @@ else
6768
}
6869
else
6970
{
70-
await Html.RenderPartialAsync("~/Pages/SNS/_TopicInfo.cshtml", await Model.SNSRepository.GetTopicAttributesAsync(Model.Topic));
71+
var topic = await Model.SNSRepository.GetTopicAttributesAsync(Model.Topic);
72+
var subscriptions = await Model.SNSRepository.GetTopicSubscriptionsAsync(topic.TopicARN.ToString());
73+
74+
await Html.RenderPartialAsync("~/Pages/SNS/_TopicInfo.cshtml", new SNSTopicModel(topic, subscriptions));
7175
}
7276
}
7377
catch(AmazonSimpleNotificationServiceException ex)
@@ -84,7 +88,7 @@ else
8488
}
8589
else
8690
{
87-
<h2 class="error-text">Failed to fetch topics contents:</h2>
91+
<h2 class="error-text">Failed to fetch topic information:</h2>
8892
}
8993

9094
<p class="error-text">@ex.Message</p>
@@ -98,7 +102,7 @@ else
98102
}
99103
else
100104
{
101-
<h2 class="error-text">Failed to fetch topic contents:</h2>
105+
<h2 class="error-text">Failed to fetch topic information:</h2>
102106
}
103107

104108
<p class="error-text">@ex.Message</p>

GuiStack/Pages/SNS/_TopicInfo.cshtml

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,55 @@
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*
6-
* Copyright © Vincent Bengtsson & Contributors 2022-2023
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
77
* https://github.com/Visual-Vincent/GuiStack
88
*@
99

1010
@using GuiStack.Models
1111
@using GuiStack.Extensions
12-
@model SNSTopicInfo
12+
@using GuiStack.Repositories
13+
@model SNSTopicModel
14+
15+
<div id="sns-subscribe-to-sqs-modal" class="cssWindow dark backdropblur text-center">
16+
<div class="closeWindowButton"><a no-href onclick="closeParentWindow(event)">×</a></div>
17+
18+
<h2 class="title">Subscribe to SQS queue</h2>
19+
<div class="queue-selector-container text-left" style="margin-top: 16px; margin-bottom: 16px">
20+
Loading queues...
21+
</div>
22+
23+
<div class="modal-buttons text-center">
24+
<button onclick="sns_CreateSubscription_Click()">Create subscription</button>
25+
</div>
26+
</div>
1327

1428
<table class="gs-info-table colored">
1529
<tbody>
1630
<tr>
1731
<td>Type</td>
18-
<td>@(Model.FifoTopic ? "FIFO" : "Standard")</td>
32+
<td>@(Model.Topic.FifoTopic ? "FIFO" : "Standard")</td>
1933
</tr>
2034
<tr>
2135
<td>ARN</td>
22-
<td>@Model.TopicARN</td>
36+
<td>@Model.Topic.TopicARN</td>
2337
</tr>
2438
<tr>
2539
<td>Content-based deduplication</td>
26-
<td>@(Model.FifoTopic ? (Model.ContentBasedDeduplication ? "Yes" : "No") : "N/A")</td>
40+
<td>@(Model.Topic.FifoTopic ? (Model.Topic.ContentBasedDeduplication ? "Yes" : "No") : "N/A")</td>
2741
</tr>
2842
<tr>
2943
<td>Active subscriptions</td>
30-
<td>@Model.SubscriptionsConfirmed</td>
44+
<td>@Model.Topic.SubscriptionsConfirmed</td>
3145
</tr>
3246
</tbody>
3347
<tbody class="additional-info">
3448
<tr>
3549
<td>Pending subscriptions</td>
36-
<td>@Model.SubscriptionsPending</td>
50+
<td>@Model.Topic.SubscriptionsPending</td>
3751
</tr>
3852
<tr>
3953
<td>Deleted subscriptions</td>
40-
<td>@Model.SubscriptionsDeleted</td>
54+
<td>@Model.Topic.SubscriptionsDeleted</td>
4155
</tr>
4256
</tbody>
4357
<tbody>
@@ -56,4 +70,83 @@
5670
</td>
5771
</tr>
5872
</tbody>
59-
</table>
73+
</table>
74+
75+
<div style="display: flex; align-items: center">
76+
<h2>Subscriptions</h2>
77+
<div style="text-align: right; font-size: 1.5em; flex-grow: 1">
78+
<a no-href onclick="showWindow('sns-subscribe-to-sqs-modal')" class="gs-icon-stack initial-white neon-green">
79+
<i class="fa-solid fa-list-check" style="margin-right: 4px"></i>
80+
<i class="bi bi-plus-circle-fill gs-icon-overlay stroked" style="color: #000000"></i>
81+
</a>
82+
</div>
83+
</div>
84+
85+
<table class="gs-list padded autosize-all-cols-but-first">
86+
<thead>
87+
<tr>
88+
<th>Protocol</th>
89+
<th>Endpoint</th>
90+
<th>Owner</th>
91+
<th>Actions</th>
92+
</tr>
93+
</thead>
94+
<tbody>
95+
@foreach(var subscription in Model.Subscriptions)
96+
{
97+
<tr>
98+
<td>@subscription.Protocol</td>
99+
<td>@subscription.Endpoint</td>
100+
<td>@subscription.Owner</td>
101+
<td>
102+
<div class="gs-icons">
103+
<a no-href class="purple lnk-sns-sub-copyarn" title="Copy ARN">
104+
<i class="fa-solid fa-link"></i>
105+
</a>
106+
<a no-href class="red lnk-sns-sub-delete" title="Delete">
107+
<i class="fa-solid fa-trash-can"></i>
108+
</a>
109+
</div>
110+
</td>
111+
</tr>
112+
}
113+
</tbody>
114+
</table>
115+
116+
<script type="text/javascript">
117+
var subscribeToSqsModal = document.getElementById("sns-subscribe-to-sqs-modal");
118+
var queueSelectorContainer = $("#sns-subscribe-to-sqs-modal .queue-selector-container");
119+
120+
subscribeToSqsModal.addEventListener("windowopened", function() {
121+
$.ajax({
122+
type: "GET",
123+
url: "@Url.Page("/SQS/Index")",
124+
data: {
125+
handler: "QueueSelectorPartial"
126+
},
127+
cache: false,
128+
error: gsevent_AjaxError,
129+
success: function(result) {
130+
queueSelectorContainer.html(result);
131+
}
132+
});
133+
});
134+
135+
subscribeToSqsModal.addEventListener("windowclosed", function() {
136+
queueSelectorContainer.html("Loading queues...");
137+
});
138+
139+
function sns_CreateSubscription_Click()
140+
{
141+
var selectedItem = gs_GetSelectedTableItem(queueSelectorContainer[0]);
142+
143+
if(isNull(selectedItem))
144+
{
145+
alert("No queue selected");
146+
return;
147+
}
148+
149+
// TODO: Create subscription
150+
alert(selectedItem.getAttribute("data-queue-name"));
151+
}
152+
</script>

GuiStack/Pages/SQS/Index.cshtml.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,18 @@ public async Task<IActionResult> OnGetReceiveMessagesPartial(string prefix, int
8282
return HandleException(ex);
8383
}
8484
}
85+
86+
public async Task<IActionResult> OnGetQueueSelectorPartial()
87+
{
88+
try
89+
{
90+
var queues = await SQSRepository.GetQueuesAsync();
91+
return Partial("_QueueSelectorPartial", queues);
92+
}
93+
catch (Exception ex)
94+
{
95+
return HandleException(ex);
96+
}
97+
}
8598
}
8699
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
7+
* https://github.com/Visual-Vincent/GuiStack
8+
*@
9+
10+
@using GuiStack.Models;
11+
@model IEnumerable<SQSQueue>
12+
13+
@try
14+
{
15+
<table class="gs-selector-table gs-list padded autosize-all-cols-but-first">
16+
<tbody>
17+
@foreach(var queue in (Model ?? Enumerable.Empty<SQSQueue>()).OrderBy(m => m.Name))
18+
{
19+
<tr data-queue-name="@queue.Name" data-url="@queue.Url" onclick="gsevent_TableItem_Click(event)">
20+
<td><i class="fa-regular fa-circle-check on-selected"></i> @queue.Name</td>
21+
</tr>
22+
}
23+
</tbody>
24+
</table>
25+
}
26+
catch(Exception ex)
27+
{
28+
<h2 class="error-text">Failed to fetch queues:</h2>
29+
<p class="error-text">@ex.Message</p>
30+
}

GuiStack/Pages/Shared/_Layout.cshtml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*
6-
* Copyright © Vincent Bengtsson & Contributors 2022-2023
6+
* Copyright © Vincent Bengtsson & Contributors 2022-2024
77
* https://github.com/Visual-Vincent/GuiStack
88
*@
99

@@ -46,9 +46,9 @@
4646

4747
<nav class="gs-navbar">
4848
<a href="/" data-selected-regex="^/$">Dashboard</a>
49-
<a href="/S3" data-selected-regex="^/S3">S3</a>
50-
<a href="/SQS" data-selected-regex="^/SQS">SQS</a>
51-
<a href="/SNS" data-selected-regex="^/SNS">SNS</a>
49+
<a href="/S3" data-selected-regex="^/S3(?:/|\?|$)">S3</a>
50+
<a href="/SQS" data-selected-regex="^/SQS(?:/|\?|$)">SQS</a>
51+
<a href="/SNS" data-selected-regex="^/SNS(?:/|\?|$)">SNS</a>
5252
</nav>
5353

5454
<main style="overflow: auto">

0 commit comments

Comments
 (0)