/
subscription_service.go
138 lines (122 loc) · 4.28 KB
/
subscription_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package notification
import (
"fmt"
"io"
"net/http"
"github.com/cenkalti/backoff/v4"
"github.com/go-playground/validator/v10"
)
type SubscriptionService struct {
client *Client
validate *validator.Validate
}
type Subscription struct {
ID string `json:"_id,omitempty"`
ResourceType string `json:"resourceType,omitempty"`
TopicID string `json:"topicId" validate:"required"`
SubscriberID string `json:"subscriberId" validate:"required"`
SubscriptionEndpoint string `json:"subscriptionEndpoint" validate:"required"`
SubscriptionARN string `json:"subscriptionArn,omitempty"`
}
type ConfirmRequest struct {
AuthenticateOnUnsubscribe string `json:"authenticateOnUnsubscribe,omitempty"`
Token string `json:"token" validate:"required"`
TopicARN string `json:"topicArn" validate:"required"`
Endpoint string `json:"endpoint" validate:"required"`
}
func (p *SubscriptionService) CreateSubscription(subscription Subscription) (*Subscription, *Response, error) {
if err := p.validate.Struct(subscription); err != nil {
return nil, nil, err
}
req, err := p.client.newNotificationRequest("POST", "core/notification/Subscription", subscription, nil)
if err != nil {
return nil, nil, err
}
var createdSubscription Subscription
resp, err := p.client.do(req, &createdSubscription)
if (err != nil && err != io.EOF) || resp == nil {
if resp == nil && err != nil {
err = fmt.Errorf("CreateSubscription: %w", ErrEmptyResult)
}
return nil, resp, err
}
return &createdSubscription, resp, nil
}
func (p *SubscriptionService) GetSubscriptions(opt *GetOptions, options ...OptionFunc) ([]Subscription, *Response, error) {
var subscriptions []Subscription
req, err := p.client.newNotificationRequest("GET", "core/notification/Subscription", opt, options...)
if err != nil {
return nil, nil, err
}
req.Header.Set("Api-Version", APIVersion)
var bundleResponse struct {
ResourceType string `json:"resourceType,omitempty"`
Type string `json:"type,omitempty"`
Total int `json:"total"`
Entry []Subscription `json:"entry"`
}
resp, err := p.client.do(req, &bundleResponse)
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
return nil, resp, ErrEmptyResult
}
return nil, resp, err
}
if bundleResponse.Total == 0 {
return subscriptions, resp, ErrEmptyResult
}
subscriptions = append(subscriptions, bundleResponse.Entry...)
return subscriptions, resp, err
}
func (p *SubscriptionService) GetSubscription(id string) (*Subscription, *Response, error) {
subscriptions, resp, err := p.GetSubscriptions(&GetOptions{ID: &id})
if err != nil {
return nil, resp, err
}
if subscriptions == nil || len(subscriptions) != 1 {
return nil, resp, fmt.Errorf("GetSubscriber: not found")
}
return &subscriptions[0], resp, nil
}
func (p *SubscriptionService) DeleteSubscription(subscription Subscription) (bool, *Response, error) {
req, err := p.client.newNotificationRequest("DELETE", "core/notification/Subscription/"+subscription.ID, nil, nil)
if err != nil {
return false, nil, err
}
req.Header.Set("api-version", APIVersion)
resp, err := p.client.do(req, nil)
if err != nil {
return false, resp, err
}
if resp != nil && resp.StatusCode != http.StatusNoContent {
return false, resp, fmt.Errorf("DeleteSubscription: HTTP %d", resp.StatusCode)
}
return true, resp, err
}
func (p *SubscriptionService) ConfirmSubscription(confirm ConfirmRequest) (*Subscription, *Response, error) {
var confirmResponse Subscription
var resp *Response
if err := p.validate.Struct(confirm); err != nil {
return nil, nil, err
}
operation := func() error {
req, err := p.client.newNotificationRequest("POST", "core/notification/Subscription/_confirm", confirm, nil)
if err != nil {
return err
}
req.Header.Set("api-version", APIVersion)
resp, err = p.client.do(req, &confirmResponse)
if err != nil {
return err
}
if resp != nil && resp.StatusCode != http.StatusCreated {
return fmt.Errorf("ConfirmSubscription: HTTP %d", resp.StatusCode)
}
return err
}
err := backoff.Retry(operation, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 8))
if err != nil {
return nil, resp, err
}
return &confirmResponse, resp, nil
}