Skip to content

Commit 03e4e02

Browse files
committed
add sns listtopics support
minor fixes add not implemented comment to sns model reset tests affecting new tests add debug message when listing sns topics remove merge remnants, minor fixups
1 parent c721136 commit 03e4e02

File tree

12 files changed

+318
-77
lines changed

12 files changed

+318
-77
lines changed

app/gosns/gosns.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,6 @@ func createPemFile() (privkey *rsa.PrivateKey, pemkey []byte, err error) {
8585
return
8686
}
8787

88-
func ListTopics(w http.ResponseWriter, req *http.Request) {
89-
content := req.FormValue("ContentType")
90-
91-
respStruct := app.ListTopicsResponse{}
92-
respStruct.Xmlns = "http://queue.amazonaws.com/doc/2012-11-05/"
93-
uuid, _ := common.NewUUID()
94-
respStruct.Metadata = app.ResponseMetadata{RequestId: uuid}
95-
96-
respStruct.Result.Topics.Member = make([]app.TopicArnResult, 0, 0)
97-
log.Println("Listing Topics")
98-
for _, topic := range app.SyncTopics.Topics {
99-
ta := app.TopicArnResult{TopicArn: topic.Arn}
100-
respStruct.Result.Topics.Member = append(respStruct.Result.Topics.Member, ta)
101-
}
102-
103-
SendResponseBack(w, req, respStruct, content)
104-
}
105-
10688
func signMessage(privkey *rsa.PrivateKey, snsMsg *app.SNSMessage) (string, error) {
10789
fs, err := formatSignature(snsMsg)
10890
if err != nil {

app/gosns/gosns_test.go

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,6 @@ import (
1515
"github.com/Admiral-Piett/goaws/app/common"
1616
)
1717

18-
func TestListTopicshandler_POST_NoTopics(t *testing.T) {
19-
// Create a request to pass to our handler. We don't have any query parameters for now, so we'll
20-
// pass 'nil' as the third parameter.
21-
req, err := http.NewRequest("POST", "/", nil)
22-
if err != nil {
23-
t.Fatal(err)
24-
}
25-
26-
// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
27-
rr := httptest.NewRecorder()
28-
handler := http.HandlerFunc(ListTopics)
29-
30-
// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
31-
// directly and pass in our Request and ResponseRecorder.
32-
handler.ServeHTTP(rr, req)
33-
34-
// Check the status code is what we expect.
35-
if status := rr.Code; status != http.StatusOK {
36-
t.Errorf("handler returned wrong status code: got %v want %v",
37-
status, http.StatusOK)
38-
}
39-
40-
// Check the response body is what we expect.
41-
expected := "<Topics></Topics>"
42-
if !strings.Contains(rr.Body.String(), expected) {
43-
t.Errorf("handler returned unexpected body: got %v want %v",
44-
rr.Body.String(), expected)
45-
}
46-
}
47-
4818
func TestPublishhandler_POST_SendMessage(t *testing.T) {
4919
defer func() {
5020
test.ResetApp()
@@ -464,6 +434,10 @@ func TestGetSubscriptionAttributesHandler_POST_Success(t *testing.T) {
464434
t.Fatal(err)
465435
}
466436

437+
defer func() {
438+
test.ResetApp()
439+
}()
440+
467441
topicName := "testing"
468442
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
469443
subArn, _ := common.NewUUID()
@@ -528,6 +502,10 @@ func TestSetSubscriptionAttributesHandler_FilterPolicy_POST_Success(t *testing.T
528502
t.Fatal(err)
529503
}
530504

505+
defer func() {
506+
test.ResetApp()
507+
}()
508+
531509
topicName := "testing"
532510
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
533511
subArn, _ := common.NewUUID()

app/gosns/list_topics.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package gosns
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/google/uuid"
7+
8+
"github.com/Admiral-Piett/goaws/app"
9+
"github.com/Admiral-Piett/goaws/app/models"
10+
"github.com/Admiral-Piett/goaws/app/utils"
11+
12+
"github.com/Admiral-Piett/goaws/app/interfaces"
13+
log "github.com/sirupsen/logrus"
14+
)
15+
16+
func ListTopicsV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
17+
requestBody := models.NewListTopicsRequest()
18+
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
19+
if !ok {
20+
log.Error("Invalid Request - ListTopicsV1")
21+
return utils.CreateErrorResponseV1("InvalidParameterValue", false)
22+
}
23+
24+
log.Debug("Listing Topics")
25+
arnList := make([]models.TopicArnResult, 0)
26+
27+
for _, topic := range app.SyncTopics.Topics {
28+
ta := models.TopicArnResult{TopicArn: topic.Arn}
29+
arnList = append(arnList, ta)
30+
}
31+
32+
requestId := uuid.NewString()
33+
respStruct := models.ListTopicsResponse{
34+
Xmlns: models.BASE_XMLNS,
35+
Result: models.ListTopicsResult{Topics: models.TopicNamestype{Member: arnList}},
36+
Metadata: app.ResponseMetadata{RequestId: requestId},
37+
}
38+
39+
return http.StatusOK, respStruct
40+
}

app/gosns/list_topics_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package gosns
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/Admiral-Piett/goaws/app/conf"
8+
"github.com/Admiral-Piett/goaws/app/interfaces"
9+
"github.com/Admiral-Piett/goaws/app/models"
10+
"github.com/Admiral-Piett/goaws/app/test"
11+
"github.com/Admiral-Piett/goaws/app/utils"
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func TestListTopicsV1_NoTopics(t *testing.T) {
16+
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "NoQueuesOrTopics")
17+
defer func() {
18+
test.ResetApp()
19+
utils.REQUEST_TRANSFORMER = utils.TransformRequest
20+
}()
21+
22+
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
23+
v := resultingStruct.(*models.ListTopicsRequest)
24+
*v = models.ListTopicsRequest{
25+
NextToken: "",
26+
}
27+
return true
28+
}
29+
30+
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
31+
code, res := ListTopicsV1(r)
32+
33+
response, _ := res.(models.ListTopicsResponse)
34+
35+
assert.Equal(t, http.StatusOK, code)
36+
assert.Equal(t, models.BASE_XMLNS, response.Xmlns)
37+
assert.NotEqual(t, "", response.Metadata)
38+
39+
assert.Len(t, response.Result.Topics.Member, 0)
40+
}
41+
42+
func TestListTopicsV1_BaseTopics(t *testing.T) {
43+
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "BaseUnitTests")
44+
defer func() {
45+
test.ResetApp()
46+
utils.REQUEST_TRANSFORMER = utils.TransformRequest
47+
}()
48+
49+
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
50+
v := resultingStruct.(*models.ListTopicsRequest)
51+
*v = models.ListTopicsRequest{
52+
NextToken: "",
53+
}
54+
return true
55+
}
56+
57+
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
58+
code, res := ListTopicsV1(r)
59+
60+
response, _ := res.(models.ListTopicsResponse)
61+
62+
assert.Equal(t, http.StatusOK, code)
63+
assert.Equal(t, models.BASE_XMLNS, response.Xmlns)
64+
assert.NotEqual(t, "", response.Metadata)
65+
66+
assert.Len(t, response.Result.Topics.Member, 2)
67+
assert.NotEqual(t, response.Result.Topics.Member[0].TopicArn, response.Result.Topics.Member[1].TopicArn)
68+
}
69+
70+
func TestListTopicsV1_request_transformer_error(t *testing.T) {
71+
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "BaseUnitTests")
72+
defer func() {
73+
test.ResetApp()
74+
utils.REQUEST_TRANSFORMER = utils.TransformRequest
75+
}()
76+
77+
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
78+
return false
79+
}
80+
81+
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
82+
code, _ := ListTopicsV1(r)
83+
84+
assert.Equal(t, http.StatusBadRequest, code)
85+
}

app/models/responses.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,30 @@ type ConfirmSubscriptionResponse struct {
328328
Result SubscribeResult `xml:"ConfirmSubscriptionResult"`
329329
Metadata app.ResponseMetadata `xml:"ResponseMetadata"`
330330
}
331+
332+
/*** List Topics ***/
333+
type TopicArnResult struct {
334+
TopicArn string `xml:"TopicArn"`
335+
NextToken string `xml:"NextToken"` // not implemented
336+
}
337+
type TopicNamestype struct {
338+
Member []TopicArnResult `xml:"member"`
339+
}
340+
341+
type ListTopicsResult struct {
342+
Topics TopicNamestype `xml:"Topics"`
343+
}
344+
345+
type ListTopicsResponse struct {
346+
Xmlns string `xml:"xmlns,attr"`
347+
Result ListTopicsResult `xml:"ListTopicsResult"`
348+
Metadata app.ResponseMetadata `xml:"ResponseMetadata"`
349+
}
350+
351+
func (r ListTopicsResponse) GetResult() interface{} {
352+
return r.Result
353+
}
354+
355+
func (r ListTopicsResponse) GetRequestId() string {
356+
return r.Metadata.RequestId
357+
}

app/models/sns.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,15 @@ type SubscriptionAttributes struct {
173173
//ReplayPolicy string `json:"ReplayPolicy" schema:"ReplayPolicy"`
174174
//ReplayStatus string `json:"ReplayStatus" schema:"ReplayStatus"`
175175
}
176+
177+
// ListTopics
178+
179+
func NewListTopicsRequest() *ListTopicsRequest {
180+
return &ListTopicsRequest{}
181+
}
182+
183+
type ListTopicsRequest struct {
184+
NextToken string `json:"NextToken" schema:"NextToken"` // not implemented
185+
}
186+
187+
func (r *ListTopicsRequest) SetAttributesFromForm(values url.Values) {}

app/router/router.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ var routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractR
7777
"DeleteQueue": sqs.DeleteQueueV1,
7878

7979
// SNS
80-
"CreateTopic": sns.CreateTopicV1,
8180
"Subscribe": sns.SubscribeV1,
81+
"ListTopics": sns.ListTopicsV1,
82+
"CreateTopic": sns.CreateTopicV1,
8283
}
8384

8485
var routingTable = map[string]http.HandlerFunc{
@@ -87,7 +88,6 @@ var routingTable = map[string]http.HandlerFunc{
8788
"DeleteMessageBatch": sqs.DeleteMessageBatch,
8889

8990
// SNS
90-
"ListTopics": sns.ListTopics,
9191
"DeleteTopic": sns.DeleteTopic,
9292
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
9393
"GetSubscriptionAttributes": sns.GetSubscriptionAttributes,

app/router/router_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,16 +269,16 @@ func TestActionHandler_v0_xml(t *testing.T) {
269269
"DeleteQueue": sqs.DeleteQueueV1,
270270

271271
// SNS
272-
"CreateTopic": sns.CreateTopicV1,
273272
"Subscribe": sns.SubscribeV1,
273+
"ListTopics": sns.ListTopicsV1,
274+
"CreateTopic": sns.CreateTopicV1,
274275
}
275276
routingTable = map[string]http.HandlerFunc{
276277
// SQS
277278
"SendMessageBatch": sqs.SendMessageBatch,
278279
"DeleteMessageBatch": sqs.DeleteMessageBatch,
279280

280281
// SNS
281-
"ListTopics": sns.ListTopics,
282282
"DeleteTopic": sns.DeleteTopic,
283283
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
284284
"GetSubscriptionAttributes": sns.GetSubscriptionAttributes,

app/sns_messages.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,5 @@
11
package app
22

3-
/*** List Topics Response */
4-
type TopicArnResult struct {
5-
TopicArn string `xml:"TopicArn"`
6-
}
7-
8-
type TopicNamestype struct {
9-
Member []TopicArnResult `xml:"member"`
10-
}
11-
12-
type ListTopicsResult struct {
13-
Topics TopicNamestype `xml:"Topics"`
14-
}
15-
16-
type ListTopicsResponse struct {
17-
Xmlns string `xml:"xmlns,attr"`
18-
Result ListTopicsResult `xml:"ListTopicsResult"`
19-
Metadata ResponseMetadata `xml:"ResponseMetadata"`
20-
}
21-
223
/*** Set Subscription Response ***/
234
type SetSubscriptionAttributesResponse struct {
245
Xmlns string `xml:"xmlns,attr"`

smoke_tests/fixtures/requests.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ var ListQueuesRequestBodyXML = struct {
1515
Version: "2012-11-05",
1616
}
1717

18+
var ListTopicsRequestBodyXML = struct {
19+
Action string `xml:"Action"`
20+
Version string `xml:"Version"`
21+
}{
22+
Action: "ListTopics",
23+
Version: "2012-11-05",
24+
}
25+
1826
var GetQueueAttributesRequestBodyXML = struct {
1927
Action string `xml:"Action"`
2028
Version string `xml:"Version"`

smoke_tests/sns_create_topic_test.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"net/http"
77
"testing"
88

9-
"github.com/Admiral-Piett/goaws/app"
109
"github.com/Admiral-Piett/goaws/app/models"
1110
"github.com/Admiral-Piett/goaws/app/test"
1211
"github.com/aws/aws-sdk-go-v2/aws"
@@ -50,7 +49,7 @@ func Test_CreateTopicV1_json_success(t *testing.T) {
5049
Expect().
5150
Status(http.StatusOK).
5251
Body().Raw()
53-
r2 := app.ListTopicsResponse{}
52+
r2 := models.ListTopicsResponse{}
5453
xml.Unmarshal([]byte(r), &r2)
5554
assert.Equal(t, 1, len(r2.Result.Topics.Member))
5655
assert.Contains(t, r2.Result.Topics.Member[0].TopicArn, topicName)
@@ -97,7 +96,7 @@ func Test_CreateTopicV1_json_existant_topic(t *testing.T) {
9796
Expect().
9897
Status(http.StatusOK).
9998
Body().Raw()
100-
r2 := app.ListTopicsResponse{}
99+
r2 := models.ListTopicsResponse{}
101100
xml.Unmarshal([]byte(r), &r2)
102101
assert.Equal(t, 1, len(r2.Result.Topics.Member))
103102
assert.Contains(t, r2.Result.Topics.Member[0].TopicArn, topicName)
@@ -145,7 +144,7 @@ func Test_CreateTopicV1_json_add_multiple_topics(t *testing.T) {
145144
Expect().
146145
Status(http.StatusOK).
147146
Body().Raw()
148-
r2 := app.ListTopicsResponse{}
147+
r2 := models.ListTopicsResponse{}
149148
xml.Unmarshal([]byte(r), &r2)
150149
assert.Equal(t, 2, len(r2.Result.Topics.Member))
151150
}
@@ -191,7 +190,7 @@ func Test_CreateTopicV1_xml_success(t *testing.T) {
191190
Expect().
192191
Status(http.StatusOK).
193192
Body().Raw()
194-
r3 := app.ListTopicsResponse{}
193+
r3 := models.ListTopicsResponse{}
195194
xml.Unmarshal([]byte(r), &r3)
196195
assert.Equal(t, 1, len(r3.Result.Topics.Member))
197196
assert.Contains(t, r3.Result.Topics.Member[0].TopicArn, topicName)
@@ -249,7 +248,7 @@ func Test_CreateTopicV1_xml_existant_topic(t *testing.T) {
249248
Expect().
250249
Status(http.StatusOK).
251250
Body().Raw()
252-
r3 := app.ListTopicsResponse{}
251+
r3 := models.ListTopicsResponse{}
253252
xml.Unmarshal([]byte(r), &r3)
254253
assert.Equal(t, 1, len(r3.Result.Topics.Member))
255254
assert.Contains(t, r3.Result.Topics.Member[0].TopicArn, topicName)

0 commit comments

Comments
 (0)