Skip to content

Commit a91f51b

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 1a9d01b commit a91f51b

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
// TODO - add a subscription and I think this should work
4919
func TestListSubscriptionByTopicResponse_No_Owner(t *testing.T) {
5020
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "Local")
@@ -229,6 +199,10 @@ func TestGetSubscriptionAttributesHandler_POST_Success(t *testing.T) {
229199
t.Fatal(err)
230200
}
231201

202+
defer func() {
203+
test.ResetApp()
204+
}()
205+
232206
topicName := "testing"
233207
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
234208
subArn, _ := common.NewUUID()
@@ -293,6 +267,10 @@ func TestSetSubscriptionAttributesHandler_FilterPolicy_POST_Success(t *testing.T
293267
t.Fatal(err)
294268
}
295269

270+
defer func() {
271+
test.ResetApp()
272+
}()
273+
296274
topicName := "testing"
297275
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
298276
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
@@ -420,3 +420,30 @@ func (r PublishResponse) GetResult() interface{} {
420420
func (r PublishResponse) GetRequestId() string {
421421
return r.Metadata.RequestId
422422
}
423+
424+
/*** List Topics ***/
425+
type TopicArnResult struct {
426+
TopicArn string `xml:"TopicArn"`
427+
NextToken string `xml:"NextToken"` // not implemented
428+
}
429+
type TopicNamestype struct {
430+
Member []TopicArnResult `xml:"member"`
431+
}
432+
433+
type ListTopicsResult struct {
434+
Topics TopicNamestype `xml:"Topics"`
435+
}
436+
437+
type ListTopicsResponse struct {
438+
Xmlns string `xml:"xmlns,attr"`
439+
Result ListTopicsResult `xml:"ListTopicsResult"`
440+
Metadata app.ResponseMetadata `xml:"ResponseMetadata"`
441+
}
442+
443+
func (r ListTopicsResponse) GetResult() interface{} {
444+
return r.Result
445+
}
446+
447+
func (r ListTopicsResponse) GetRequestId() string {
448+
return r.Metadata.RequestId
449+
}

app/models/sns.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,15 @@ func (r *PublishRequest) SetAttributesFromForm(values url.Values) {
224224
}
225225
}
226226
}
227+
228+
// ListTopics
229+
230+
func NewListTopicsRequest() *ListTopicsRequest {
231+
return &ListTopicsRequest{}
232+
}
233+
234+
type ListTopicsRequest struct {
235+
NextToken string `json:"NextToken" schema:"NextToken"` // not implemented
236+
}
237+
238+
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
@@ -79,15 +79,15 @@ var routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractR
7979
"DeleteMessageBatch": sqs.DeleteMessageBatchV1,
8080

8181
// SNS
82-
"CreateTopic": sns.CreateTopicV1,
8382
"Subscribe": sns.SubscribeV1,
8483
"Unsubscribe": sns.UnsubscribeV1,
8584
"Publish": sns.PublishV1,
85+
"ListTopics": sns.ListTopicsV1,
86+
"CreateTopic": sns.CreateTopicV1,
8687
}
8788

8889
var routingTable = map[string]http.HandlerFunc{
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
@@ -271,15 +271,15 @@ func TestActionHandler_v0_xml(t *testing.T) {
271271
"DeleteMessageBatch": sqs.DeleteMessageBatchV1,
272272

273273
// SNS
274-
"CreateTopic": sns.CreateTopicV1,
275274
"Subscribe": sns.SubscribeV1,
276275
"Unsubscribe": sns.UnsubscribeV1,
277276
"Publish": sns.PublishV1,
277+
"ListTopics": sns.ListTopicsV1,
278+
"CreateTopic": sns.CreateTopicV1,
278279
}
279280

280281
routingTable = map[string]http.HandlerFunc{
281282
// SNS
282-
"ListTopics": sns.ListTopics,
283283
"DeleteTopic": sns.DeleteTopic,
284284
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
285285
"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)