Skip to content

Commit

Permalink
add sns listtopics support
Browse files Browse the repository at this point in the history
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

update listtopics test to handle new mock config
  • Loading branch information
NRatSony committed Jul 19, 2024
1 parent 1a9d01b commit 71373a6
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 77 deletions.
18 changes: 0 additions & 18 deletions app/gosns/gosns.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,6 @@ func createPemFile() (privkey *rsa.PrivateKey, pemkey []byte, err error) {
return
}

func ListTopics(w http.ResponseWriter, req *http.Request) {
content := req.FormValue("ContentType")

respStruct := app.ListTopicsResponse{}
respStruct.Xmlns = "http://queue.amazonaws.com/doc/2012-11-05/"
uuid, _ := common.NewUUID()
respStruct.Metadata = app.ResponseMetadata{RequestId: uuid}

respStruct.Result.Topics.Member = make([]app.TopicArnResult, 0, 0)
log.Println("Listing Topics")
for _, topic := range app.SyncTopics.Topics {
ta := app.TopicArnResult{TopicArn: topic.Arn}
respStruct.Result.Topics.Member = append(respStruct.Result.Topics.Member, ta)
}

SendResponseBack(w, req, respStruct, content)
}

func signMessage(privkey *rsa.PrivateKey, snsMsg *app.SNSMessage) (string, error) {
fs, err := formatSignature(snsMsg)
if err != nil {
Expand Down
38 changes: 8 additions & 30 deletions app/gosns/gosns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,6 @@ import (
"github.com/Admiral-Piett/goaws/app/common"
)

func TestListTopicshandler_POST_NoTopics(t *testing.T) {
// Create a request to pass to our handler. We don't have any query parameters for now, so we'll
// pass 'nil' as the third parameter.
req, err := http.NewRequest("POST", "/", nil)
if err != nil {
t.Fatal(err)
}

// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
rr := httptest.NewRecorder()
handler := http.HandlerFunc(ListTopics)

// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
// directly and pass in our Request and ResponseRecorder.
handler.ServeHTTP(rr, req)

// Check the status code is what we expect.
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}

// Check the response body is what we expect.
expected := "<Topics></Topics>"
if !strings.Contains(rr.Body.String(), expected) {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}

// TODO - add a subscription and I think this should work
func TestListSubscriptionByTopicResponse_No_Owner(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "Local")
Expand Down Expand Up @@ -229,6 +199,10 @@ func TestGetSubscriptionAttributesHandler_POST_Success(t *testing.T) {
t.Fatal(err)
}

defer func() {
test.ResetApp()
}()

topicName := "testing"
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
subArn, _ := common.NewUUID()
Expand Down Expand Up @@ -293,6 +267,10 @@ func TestSetSubscriptionAttributesHandler_FilterPolicy_POST_Success(t *testing.T
t.Fatal(err)
}

defer func() {
test.ResetApp()
}()

topicName := "testing"
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
subArn, _ := common.NewUUID()
Expand Down
40 changes: 40 additions & 0 deletions app/gosns/list_topics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gosns

import (
"net/http"

"github.com/google/uuid"

"github.com/Admiral-Piett/goaws/app"
"github.com/Admiral-Piett/goaws/app/models"
"github.com/Admiral-Piett/goaws/app/utils"

"github.com/Admiral-Piett/goaws/app/interfaces"
log "github.com/sirupsen/logrus"
)

func ListTopicsV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewListTopicsRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
if !ok {
log.Error("Invalid Request - ListTopicsV1")
return utils.CreateErrorResponseV1("InvalidParameterValue", false)
}

log.Debug("Listing Topics")
arnList := make([]models.TopicArnResult, 0)

for _, topic := range app.SyncTopics.Topics {
ta := models.TopicArnResult{TopicArn: topic.Arn}
arnList = append(arnList, ta)
}

requestId := uuid.NewString()
respStruct := models.ListTopicsResponse{
Xmlns: models.BASE_XMLNS,
Result: models.ListTopicsResult{Topics: models.TopicNamestype{Member: arnList}},
Metadata: app.ResponseMetadata{RequestId: requestId},
}

return http.StatusOK, respStruct
}
93 changes: 93 additions & 0 deletions app/gosns/list_topics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package gosns

import (
"fmt"
"net/http"
"testing"

"github.com/Admiral-Piett/goaws/app/conf"
"github.com/Admiral-Piett/goaws/app/interfaces"
"github.com/Admiral-Piett/goaws/app/models"
"github.com/Admiral-Piett/goaws/app/test"
"github.com/Admiral-Piett/goaws/app/utils"
"github.com/stretchr/testify/assert"
)

func TestListTopicsV1_NoTopics(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "NoQueuesOrTopics")
defer func() {
test.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.ListTopicsRequest)
*v = models.ListTopicsRequest{
NextToken: "",
}
return true
}

_, r := test.GenerateRequestInfo("POST", "/", nil, true)
code, res := ListTopicsV1(r)

response, _ := res.(models.ListTopicsResponse)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, models.BASE_XMLNS, response.Xmlns)
assert.NotEqual(t, "", response.Metadata)

assert.Len(t, response.Result.Topics.Member, 0)
}

func TestListTopicsV1_BaseTopics(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "BaseUnitTests")
defer func() {
test.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.ListTopicsRequest)
*v = models.ListTopicsRequest{
NextToken: "",
}
return true
}

_, r := test.GenerateRequestInfo("POST", "/", nil, true)
code, res := ListTopicsV1(r)

response, _ := res.(models.ListTopicsResponse)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, models.BASE_XMLNS, response.Xmlns)
assert.NotEqual(t, "", response.Metadata)

assert.Len(t, response.Result.Topics.Member, 4)

topicArnVisited := map[string]bool{}

for _, member := range response.Result.Topics.Member {
_, ok := topicArnVisited[member.TopicArn]
assert.False(t, ok, fmt.Sprintf("Found duplicated listed arn entry: %s", member.TopicArn))
topicArnVisited[member.TopicArn] = true
}
}

func TestListTopicsV1_request_transformer_error(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "BaseUnitTests")
defer func() {
test.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
return false
}

_, r := test.GenerateRequestInfo("POST", "/", nil, true)
code, _ := ListTopicsV1(r)

assert.Equal(t, http.StatusBadRequest, code)
}
27 changes: 27 additions & 0 deletions app/models/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,30 @@ func (r PublishResponse) GetResult() interface{} {
func (r PublishResponse) GetRequestId() string {
return r.Metadata.RequestId
}

/*** List Topics ***/
type TopicArnResult struct {
TopicArn string `xml:"TopicArn"`
NextToken string `xml:"NextToken"` // not implemented
}
type TopicNamestype struct {
Member []TopicArnResult `xml:"member"`
}

type ListTopicsResult struct {
Topics TopicNamestype `xml:"Topics"`
}

type ListTopicsResponse struct {
Xmlns string `xml:"xmlns,attr"`
Result ListTopicsResult `xml:"ListTopicsResult"`
Metadata app.ResponseMetadata `xml:"ResponseMetadata"`
}

func (r ListTopicsResponse) GetResult() interface{} {
return r.Result
}

func (r ListTopicsResponse) GetRequestId() string {
return r.Metadata.RequestId
}
12 changes: 12 additions & 0 deletions app/models/sns.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,15 @@ func (r *PublishRequest) SetAttributesFromForm(values url.Values) {
}
}
}

// ListTopics

func NewListTopicsRequest() *ListTopicsRequest {
return &ListTopicsRequest{}
}

type ListTopicsRequest struct {
NextToken string `json:"NextToken" schema:"NextToken"` // not implemented
}

func (r *ListTopicsRequest) SetAttributesFromForm(values url.Values) {}
4 changes: 2 additions & 2 deletions app/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ var routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractR
"DeleteMessageBatch": sqs.DeleteMessageBatchV1,

// SNS
"CreateTopic": sns.CreateTopicV1,
"Subscribe": sns.SubscribeV1,
"Unsubscribe": sns.UnsubscribeV1,
"Publish": sns.PublishV1,
"ListTopics": sns.ListTopicsV1,
"CreateTopic": sns.CreateTopicV1,
}

var routingTable = map[string]http.HandlerFunc{
// SNS
"ListTopics": sns.ListTopics,
"DeleteTopic": sns.DeleteTopic,
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
"GetSubscriptionAttributes": sns.GetSubscriptionAttributes,
Expand Down
4 changes: 2 additions & 2 deletions app/router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,15 @@ func TestActionHandler_v0_xml(t *testing.T) {
"DeleteMessageBatch": sqs.DeleteMessageBatchV1,

// SNS
"CreateTopic": sns.CreateTopicV1,
"Subscribe": sns.SubscribeV1,
"Unsubscribe": sns.UnsubscribeV1,
"Publish": sns.PublishV1,
"ListTopics": sns.ListTopicsV1,
"CreateTopic": sns.CreateTopicV1,
}

routingTable = map[string]http.HandlerFunc{
// SNS
"ListTopics": sns.ListTopics,
"DeleteTopic": sns.DeleteTopic,
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
"GetSubscriptionAttributes": sns.GetSubscriptionAttributes,
Expand Down
19 changes: 0 additions & 19 deletions app/sns_messages.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
package app

/*** List Topics Response */
type TopicArnResult struct {
TopicArn string `xml:"TopicArn"`
}

type TopicNamestype struct {
Member []TopicArnResult `xml:"member"`
}

type ListTopicsResult struct {
Topics TopicNamestype `xml:"Topics"`
}

type ListTopicsResponse struct {
Xmlns string `xml:"xmlns,attr"`
Result ListTopicsResult `xml:"ListTopicsResult"`
Metadata ResponseMetadata `xml:"ResponseMetadata"`
}

/*** Set Subscription Response ***/
type SetSubscriptionAttributesResponse struct {
Xmlns string `xml:"xmlns,attr"`
Expand Down
8 changes: 8 additions & 0 deletions smoke_tests/fixtures/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ var ListQueuesRequestBodyXML = struct {
Version: "2012-11-05",
}

var ListTopicsRequestBodyXML = struct {
Action string `xml:"Action"`
Version string `xml:"Version"`
}{
Action: "ListTopics",
Version: "2012-11-05",
}

var GetQueueAttributesRequestBodyXML = struct {
Action string `xml:"Action"`
Version string `xml:"Version"`
Expand Down
11 changes: 5 additions & 6 deletions smoke_tests/sns_create_topic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"net/http"
"testing"

"github.com/Admiral-Piett/goaws/app"
"github.com/Admiral-Piett/goaws/app/models"
"github.com/Admiral-Piett/goaws/app/test"
"github.com/aws/aws-sdk-go-v2/aws"
Expand Down Expand Up @@ -50,7 +49,7 @@ func Test_CreateTopicV1_json_success(t *testing.T) {
Expect().
Status(http.StatusOK).
Body().Raw()
r2 := app.ListTopicsResponse{}
r2 := models.ListTopicsResponse{}
xml.Unmarshal([]byte(r), &r2)
assert.Equal(t, 1, len(r2.Result.Topics.Member))
assert.Contains(t, r2.Result.Topics.Member[0].TopicArn, topicName)
Expand Down Expand Up @@ -97,7 +96,7 @@ func Test_CreateTopicV1_json_existant_topic(t *testing.T) {
Expect().
Status(http.StatusOK).
Body().Raw()
r2 := app.ListTopicsResponse{}
r2 := models.ListTopicsResponse{}
xml.Unmarshal([]byte(r), &r2)
assert.Equal(t, 1, len(r2.Result.Topics.Member))
assert.Contains(t, r2.Result.Topics.Member[0].TopicArn, topicName)
Expand Down Expand Up @@ -145,7 +144,7 @@ func Test_CreateTopicV1_json_add_multiple_topics(t *testing.T) {
Expect().
Status(http.StatusOK).
Body().Raw()
r2 := app.ListTopicsResponse{}
r2 := models.ListTopicsResponse{}
xml.Unmarshal([]byte(r), &r2)
assert.Equal(t, 2, len(r2.Result.Topics.Member))
}
Expand Down Expand Up @@ -191,7 +190,7 @@ func Test_CreateTopicV1_xml_success(t *testing.T) {
Expect().
Status(http.StatusOK).
Body().Raw()
r3 := app.ListTopicsResponse{}
r3 := models.ListTopicsResponse{}
xml.Unmarshal([]byte(r), &r3)
assert.Equal(t, 1, len(r3.Result.Topics.Member))
assert.Contains(t, r3.Result.Topics.Member[0].TopicArn, topicName)
Expand Down Expand Up @@ -249,7 +248,7 @@ func Test_CreateTopicV1_xml_existant_topic(t *testing.T) {
Expect().
Status(http.StatusOK).
Body().Raw()
r3 := app.ListTopicsResponse{}
r3 := models.ListTopicsResponse{}
xml.Unmarshal([]byte(r), &r3)
assert.Equal(t, 1, len(r3.Result.Topics.Member))
assert.Contains(t, r3.Result.Topics.Member[0].TopicArn, topicName)
Expand Down
Loading

0 comments on commit 71373a6

Please sign in to comment.