Skip to content

Commit ee1df4c

Browse files
Dai.OtsukaAdmiral-Piett
Dai.Otsuka
authored andcommitted
added get subscription attributes
rename review ref review ref
1 parent aa31fa4 commit ee1df4c

12 files changed

+476
-156
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package gosns
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
"strconv"
7+
8+
"github.com/Admiral-Piett/goaws/app"
9+
"github.com/Admiral-Piett/goaws/app/interfaces"
10+
"github.com/Admiral-Piett/goaws/app/models"
11+
"github.com/Admiral-Piett/goaws/app/utils"
12+
"github.com/google/uuid"
13+
log "github.com/sirupsen/logrus"
14+
)
15+
16+
func GetSubscriptionAttributesV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
17+
18+
requestBody := models.NewGetSubscriptionAttributesRequest()
19+
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
20+
21+
if !ok {
22+
log.Error("Invalid Request - GetSubscriptionAttributesV1")
23+
return utils.CreateErrorResponseV1("InvalidParameterValue", false)
24+
}
25+
26+
subscriptionArn := requestBody.SubscriptionArn
27+
28+
for _, topic := range app.SyncTopics.Topics {
29+
for _, sub := range topic.Subscriptions {
30+
if sub.SubscriptionArn == subscriptionArn {
31+
32+
entries := make([]models.SubscriptionAttributeEntry, 0, 0)
33+
entry := models.SubscriptionAttributeEntry{Key: "Owner", Value: app.CurrentEnvironment.AccountID}
34+
entries = append(entries, entry)
35+
entry = models.SubscriptionAttributeEntry{Key: "RawMessageDelivery", Value: strconv.FormatBool(sub.Raw)}
36+
entries = append(entries, entry)
37+
entry = models.SubscriptionAttributeEntry{Key: "TopicArn", Value: sub.TopicArn}
38+
entries = append(entries, entry)
39+
entry = models.SubscriptionAttributeEntry{Key: "Endpoint", Value: sub.EndPoint}
40+
entries = append(entries, entry)
41+
entry = models.SubscriptionAttributeEntry{Key: "PendingConfirmation", Value: "false"}
42+
entries = append(entries, entry)
43+
entry = models.SubscriptionAttributeEntry{Key: "ConfirmationWasAuthenticated", Value: "true"}
44+
entries = append(entries, entry)
45+
entry = models.SubscriptionAttributeEntry{Key: "SubscriptionArn", Value: sub.SubscriptionArn}
46+
entries = append(entries, entry)
47+
entry = models.SubscriptionAttributeEntry{Key: "Protocol", Value: sub.Protocol}
48+
entries = append(entries, entry)
49+
50+
if sub.FilterPolicy != nil {
51+
filterPolicyBytes, _ := json.Marshal(sub.FilterPolicy)
52+
entry = models.SubscriptionAttributeEntry{Key: "FilterPolicy", Value: string(filterPolicyBytes)}
53+
entries = append(entries, entry)
54+
}
55+
56+
result := models.GetSubscriptionAttributesResult{Attributes: models.GetSubscriptionAttributes{Entries: entries}}
57+
uuid := uuid.NewString()
58+
respStruct := models.GetSubscriptionAttributesResponse{
59+
Xmlns: models.BASE_XMLNS,
60+
Result: result,
61+
Metadata: app.ResponseMetadata{RequestId: uuid}}
62+
63+
return http.StatusOK, respStruct
64+
65+
}
66+
}
67+
}
68+
return utils.CreateErrorResponseV1("SubscriptionNotFound", false)
69+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package gosns
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/Admiral-Piett/goaws/app"
8+
"github.com/Admiral-Piett/goaws/app/conf"
9+
"github.com/Admiral-Piett/goaws/app/interfaces"
10+
"github.com/Admiral-Piett/goaws/app/models"
11+
"github.com/Admiral-Piett/goaws/app/test"
12+
"github.com/Admiral-Piett/goaws/app/utils"
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestGetSubscriptionAttributesV1_NonExistentSubscription(t *testing.T) {
17+
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "NoQueuesOrTopics")
18+
defer func() {
19+
test.ResetApp()
20+
utils.REQUEST_TRANSFORMER = utils.TransformRequest
21+
}()
22+
23+
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
24+
v := resultingStruct.(*models.GetSubscriptionAttributesRequest)
25+
*v = models.GetSubscriptionAttributesRequest{
26+
SubscriptionArn: "hogehoge",
27+
}
28+
return true
29+
}
30+
31+
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
32+
code, response := GetSubscriptionAttributesV1(r)
33+
errorResult := response.GetResult().(models.ErrorResult)
34+
35+
expected := models.ErrorResult{
36+
Type: "Not Found",
37+
Code: "AWS.SimpleNotificationService.NonExistentSubscription",
38+
Message: "The specified subscription does not exist for this wsdl version.",
39+
}
40+
assert.Equal(t, http.StatusNotFound, code)
41+
assert.Equal(t, expected, errorResult)
42+
}
43+
44+
func TestGetSubscriptionAttributesV1_TransformError(t *testing.T) {
45+
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "Local")
46+
defer func() {
47+
test.ResetApp()
48+
utils.REQUEST_TRANSFORMER = utils.TransformRequest
49+
}()
50+
51+
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
52+
return false
53+
}
54+
55+
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
56+
code, _ := GetSubscriptionAttributesV1(r)
57+
58+
assert.Equal(t, http.StatusBadRequest, code)
59+
}
60+
61+
func TestGetSubscriptionAttributesV1_success(t *testing.T) {
62+
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "Local")
63+
defer func() {
64+
test.ResetApp()
65+
utils.REQUEST_TRANSFORMER = utils.TransformRequest
66+
}()
67+
68+
localTopic1 := app.SyncTopics.Topics["local-topic1"]
69+
subscriptions := localTopic1.Subscriptions
70+
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
71+
v := resultingStruct.(*models.GetSubscriptionAttributesRequest)
72+
*v = models.GetSubscriptionAttributesRequest{
73+
// local-queue5
74+
SubscriptionArn: subscriptions[1].SubscriptionArn,
75+
}
76+
return true
77+
}
78+
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
79+
code, response := GetSubscriptionAttributesV1(r)
80+
81+
result := response.GetResult().(models.GetSubscriptionAttributesResult)
82+
assert.Equal(t, http.StatusOK, code)
83+
expectedAttributes := []models.SubscriptionAttributeEntry{
84+
{
85+
Key: "Owner",
86+
Value: app.CurrentEnvironment.AccountID,
87+
},
88+
{
89+
Key: "RawMessageDelivery",
90+
Value: "true",
91+
},
92+
{
93+
Key: "TopicArn",
94+
Value: localTopic1.Arn,
95+
},
96+
{
97+
Key: "Endpoint",
98+
Value: subscriptions[1].EndPoint,
99+
},
100+
{
101+
Key: "PendingConfirmation",
102+
Value: "false",
103+
},
104+
{
105+
Key: "ConfirmationWasAuthenticated",
106+
Value: "true",
107+
}, {
108+
Key: "SubscriptionArn",
109+
Value: subscriptions[1].SubscriptionArn,
110+
}, {
111+
Key: "Protocol",
112+
Value: "sqs",
113+
},
114+
{
115+
Key: "FilterPolicy",
116+
Value: "{\"foo\":[\"bar\"]}",
117+
},
118+
}
119+
120+
assert.ElementsMatch(t, expectedAttributes, result.Attributes.Entries)
121+
}

app/gosns/gosns.go

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"errors"
77
"fmt"
88
"net/http"
9-
"strconv"
109
"strings"
1110
"time"
1211

@@ -220,54 +219,6 @@ func SetSubscriptionAttributes(w http.ResponseWriter, req *http.Request) {
220219
createErrorResponse(w, req, "SubscriptionNotFound")
221220
}
222221

223-
func GetSubscriptionAttributes(w http.ResponseWriter, req *http.Request) {
224-
225-
content := req.FormValue("ContentType")
226-
subsArn := req.FormValue("SubscriptionArn")
227-
228-
for _, topic := range app.SyncTopics.Topics {
229-
for _, sub := range topic.Subscriptions {
230-
if sub.SubscriptionArn == subsArn {
231-
232-
entries := make([]app.SubscriptionAttributeEntry, 0, 0)
233-
entry := app.SubscriptionAttributeEntry{Key: "Owner", Value: app.CurrentEnvironment.AccountID}
234-
entries = append(entries, entry)
235-
entry = app.SubscriptionAttributeEntry{Key: "RawMessageDelivery", Value: strconv.FormatBool(sub.Raw)}
236-
entries = append(entries, entry)
237-
entry = app.SubscriptionAttributeEntry{Key: "TopicArn", Value: sub.TopicArn}
238-
entries = append(entries, entry)
239-
entry = app.SubscriptionAttributeEntry{Key: "Endpoint", Value: sub.EndPoint}
240-
entries = append(entries, entry)
241-
entry = app.SubscriptionAttributeEntry{Key: "PendingConfirmation", Value: "false"}
242-
entries = append(entries, entry)
243-
entry = app.SubscriptionAttributeEntry{Key: "ConfirmationWasAuthenticated", Value: "true"}
244-
entries = append(entries, entry)
245-
entry = app.SubscriptionAttributeEntry{Key: "SubscriptionArn", Value: sub.SubscriptionArn}
246-
entries = append(entries, entry)
247-
entry = app.SubscriptionAttributeEntry{Key: "Protocol", Value: sub.Protocol}
248-
entries = append(entries, entry)
249-
entry = app.SubscriptionAttributeEntry{Key: "Endpoint", Value: sub.EndPoint}
250-
entries = append(entries, entry)
251-
252-
if sub.FilterPolicy != nil {
253-
filterPolicyBytes, _ := json.Marshal(sub.FilterPolicy)
254-
entry = app.SubscriptionAttributeEntry{Key: "FilterPolicy", Value: string(filterPolicyBytes)}
255-
entries = append(entries, entry)
256-
}
257-
258-
result := app.GetSubscriptionAttributesResult{SubscriptionAttributes: app.SubscriptionAttributes{Entries: entries}}
259-
uuid, _ := common.NewUUID()
260-
respStruct := app.GetSubscriptionAttributesResponse{"http://sns.amazonaws.com/doc/2010-03-31", result, app.ResponseMetadata{RequestId: uuid}}
261-
262-
SendResponseBack(w, req, respStruct, content)
263-
264-
return
265-
}
266-
}
267-
}
268-
createErrorResponse(w, req, "SubscriptionNotFound")
269-
}
270-
271222
// NOTE: The use case for this is to use GoAWS to call some external system with the message payload. Essentially
272223
// it is a localized subscription to some non-AWS endpoint.
273224
func callEndpoint(endpoint string, subArn string, msg app.SNSMessage, raw bool) error {

app/gosns/gosns_test.go

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -74,74 +74,6 @@ func TestListSubscriptionByTopicResponse_No_Owner(t *testing.T) {
7474
}
7575
}
7676

77-
func TestGetSubscriptionAttributesHandler_POST_Success(t *testing.T) {
78-
// Create a request to pass to our handler. We don't have any query parameters for now, so we'll
79-
// pass 'nil' as the third parameter.
80-
req, err := http.NewRequest("POST", "/", nil)
81-
if err != nil {
82-
t.Fatal(err)
83-
}
84-
85-
defer func() {
86-
test.ResetApp()
87-
}()
88-
89-
topicName := "testing"
90-
topicArn := "arn:aws:sns:" + app.CurrentEnvironment.Region + ":000000000000:" + topicName
91-
subArn, _ := common.NewUUID()
92-
subArn = topicArn + ":" + subArn
93-
app.SyncTopics.Topics[topicName] = &app.Topic{Name: topicName, Arn: topicArn, Subscriptions: []*app.Subscription{
94-
{
95-
SubscriptionArn: subArn,
96-
FilterPolicy: &app.FilterPolicy{
97-
"foo": {"bar"},
98-
},
99-
},
100-
}}
101-
102-
form := url.Values{}
103-
form.Add("SubscriptionArn", subArn)
104-
req.PostForm = form
105-
106-
// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
107-
rr := httptest.NewRecorder()
108-
handler := http.HandlerFunc(GetSubscriptionAttributes)
109-
110-
// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
111-
// directly and pass in our Request and ResponseRecorder.
112-
handler.ServeHTTP(rr, req)
113-
114-
// Check the status code is what we expect.
115-
if status := rr.Code; status != http.StatusOK {
116-
t.Errorf("handler returned wrong status code: got %v want %v",
117-
status, http.StatusOK)
118-
}
119-
120-
// Check the response body is what we expect.
121-
expected := "</GetSubscriptionAttributesResult>"
122-
if !strings.Contains(rr.Body.String(), expected) {
123-
t.Errorf("handler returned unexpected body: got %v want %v",
124-
rr.Body.String(), expected)
125-
}
126-
127-
expectedElements := []string{"Owner", "RawMessageDelivery", "TopicArn", "Endpoint", "PendingConfirmation",
128-
"ConfirmationWasAuthenticated", "SubscriptionArn", "Protocol", "FilterPolicy"}
129-
for _, element := range expectedElements {
130-
expected := "<key>" + element + "</key>"
131-
if !strings.Contains(rr.Body.String(), expected) {
132-
t.Errorf("handler returned unexpected body: got %v want %v",
133-
rr.Body.String(), expected)
134-
}
135-
}
136-
137-
// Check the response body is what we expect.
138-
expected = "{&#34;foo&#34;:[&#34;bar&#34;]}"
139-
if !strings.Contains(rr.Body.String(), expected) {
140-
t.Errorf("handler returned unexpected body: got %v want %v",
141-
rr.Body.String(), expected)
142-
}
143-
}
144-
14577
func TestSetSubscriptionAttributesHandler_FilterPolicy_POST_Success(t *testing.T) {
14678
// Create a request to pass to our handler. We don't have any query parameters for now, so we'll
14779
// pass 'nil' as the third parameter.

app/gosns/unsubscribe_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,5 @@ func TestUnsubscribeV1_invalid_subscription_arn(t *testing.T) {
7979
_, r := test.GenerateRequestInfo("POST", "/", nil, true)
8080
status, _ := UnsubscribeV1(r)
8181

82-
assert.Equal(t, http.StatusBadRequest, status)
82+
assert.Equal(t, http.StatusNotFound, status)
8383
}

app/models/errors.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func init() {
2020
SnsErrors = map[string]SnsErrorType{
2121
"InvalidParameterValue": {HttpError: http.StatusBadRequest, Type: "InvalidParameterValue", Code: "AWS.SimpleNotificationService.InvalidParameterValue", Message: "An invalid or out-of-range value was supplied for the input parameter."},
2222
"TopicNotFound": {HttpError: http.StatusBadRequest, Type: "Not Found", Code: "AWS.SimpleNotificationService.NonExistentTopic", Message: "The specified topic does not exist for this wsdl version."},
23-
"SubscriptionNotFound": {HttpError: http.StatusBadRequest, Type: "Not Found", Code: "AWS.SimpleNotificationService.NonExistentSubscription", Message: "The specified subscription does not exist for this wsdl version."},
23+
"SubscriptionNotFound": {HttpError: http.StatusNotFound, Type: "Not Found", Code: "AWS.SimpleNotificationService.NonExistentSubscription", Message: "The specified subscription does not exist for this wsdl version."},
2424
"TopicExists": {HttpError: http.StatusBadRequest, Type: "Duplicate", Code: "AWS.SimpleNotificationService.TopicAlreadyExists", Message: "The specified topic already exists."},
2525
"ValidationError": {HttpError: http.StatusBadRequest, Type: "InvalidParameter", Code: "AWS.SimpleNotificationService.ValidationError", Message: "The input fails to satisfy the constraints specified by an AWS service."},
2626
}

app/models/responses.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,3 +493,32 @@ func (r ListSubscriptionsResponse) GetResult() interface{} {
493493
func (r ListSubscriptionsResponse) GetRequestId() string {
494494
return r.Metadata.RequestId
495495
}
496+
497+
/*** Get Subscription Attributes ***/
498+
type GetSubscriptionAttributesResult struct {
499+
Attributes GetSubscriptionAttributes `xml:"Attributes,omitempty"`
500+
}
501+
502+
type GetSubscriptionAttributes struct {
503+
/* SubscriptionArn, FilterPolicy */
504+
Entries []SubscriptionAttributeEntry `xml:"entry,omitempty"`
505+
}
506+
507+
type SubscriptionAttributeEntry struct {
508+
Key string `xml:"key,omitempty"`
509+
Value string `xml:"value,omitempty"`
510+
}
511+
512+
type GetSubscriptionAttributesResponse struct {
513+
Xmlns string `xml:"xmlns,attr,omitempty"`
514+
Result GetSubscriptionAttributesResult `xml:"GetSubscriptionAttributesResult"`
515+
Metadata app.ResponseMetadata `xml:"ResponseMetadata,omitempty"`
516+
}
517+
518+
func (r GetSubscriptionAttributesResponse) GetResult() interface{} {
519+
return r.Result
520+
}
521+
522+
func (r GetSubscriptionAttributesResponse) GetRequestId() string {
523+
return r.Metadata.RequestId
524+
}

app/models/sns.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,14 @@ type ListSubscriptionsRequest struct {
260260
}
261261

262262
func (r *ListSubscriptionsRequest) SetAttributesFromForm(values url.Values) {}
263+
264+
// Get Subscription Attributes V1
265+
func NewGetSubscriptionAttributesRequest() *GetSubscriptionAttributesRequest {
266+
return &GetSubscriptionAttributesRequest{}
267+
}
268+
269+
type GetSubscriptionAttributesRequest struct {
270+
SubscriptionArn string `json:"SubscriptionArn" schema:"SubscriptionArn"`
271+
}
272+
273+
func (r *GetSubscriptionAttributesRequest) SetAttributesFromForm(values url.Values) {}

0 commit comments

Comments
 (0)