|
| 1 | +package gosqs |
| 2 | + |
| 3 | +import ( |
| 4 | + "strconv" |
| 5 | + |
| 6 | + "github.com/aws/aws-sdk-go/aws" |
| 7 | + "github.com/aws/aws-sdk-go/aws/client" |
| 8 | + "github.com/aws/aws-sdk-go/aws/credentials" |
| 9 | + "github.com/aws/aws-sdk-go/aws/request" |
| 10 | + "github.com/aws/aws-sdk-go/aws/session" |
| 11 | +) |
| 12 | + |
| 13 | +// Config defines the gosqs configuration |
| 14 | +type Config struct { |
| 15 | + // private key to access aws |
| 16 | + Key string |
| 17 | + // secret to access aws |
| 18 | + Secret string |
| 19 | + // region for aws and used for determining the topic ARN |
| 20 | + Region string |
| 21 | + // provided automatically by aws, but must be set for emulators or local testing |
| 22 | + Hostname string |
| 23 | + // account ID of the aws account, used for determining the topic ARN |
| 24 | + AWSAccountID string |
| 25 | + // environment name, used for determinig the topic ARN |
| 26 | + Env string |
| 27 | + // prefix of the topic, this is set as a prefix to the environment |
| 28 | + TopicPrefix string |
| 29 | + // optional address of the topic, if this is not provided it will be created using other variables |
| 30 | + TopicARN string |
| 31 | + // optional address of queue, if this is not provided it will be retrieved during setup |
| 32 | + QueueURL string |
| 33 | + // used to extend the allowed processing time of a message |
| 34 | + VisibilityTimeout int |
| 35 | + // used to determine how many attempts exponential backoff should use before logging an error |
| 36 | + RetryCount int |
| 37 | + // defines the total amount of goroutines that can be run by the consumer |
| 38 | + WorkerPool int |
| 39 | + // defines the total number of processing extensions that occur. Each proccessing extension will double the |
| 40 | + // visibilitytimeout counter, ensuring the handler has more time to process the message. Default is 2 extensions (1m30s processing time) |
| 41 | + // set to 0 to turn off extension processing |
| 42 | + ExtensionLimit *int |
| 43 | + |
| 44 | + // Add custom attributes to the message. This might be a correlationId or client meta information |
| 45 | + // custom attributes will be viewable on the sqs dashboard as meta data |
| 46 | + Attributes []customAttribute |
| 47 | + |
| 48 | + // Add a custom logger, the default will be log.Println |
| 49 | + Logger Logger |
| 50 | +} |
| 51 | + |
| 52 | +// customAttribute add custom attributes to SNS and SQS messages. This can include correlationIds, or any additional information you would like |
| 53 | +// separate from the payload body. These attributes can be easily seen from the SQS console. |
| 54 | +type customAttribute struct { |
| 55 | + Title string |
| 56 | + // Use gosqs.DataTypeNumber or gosqs.DataTypeString |
| 57 | + DataType string |
| 58 | + // Value represents the value |
| 59 | + Value string |
| 60 | +} |
| 61 | + |
| 62 | +// NewCustomAttribute adds a custom attribute to SNS and SQS messages. This can include correlationIds, logIds, or any additional information you would like |
| 63 | +// separate from the payload body. These attributes can be easily seen from the SQS console. |
| 64 | +// |
| 65 | +// must use gosqs.DataTypeNumber of gosqs.DataTypeString for the datatype, the value must match the type provided |
| 66 | +func (c *Config) NewCustomAttribute(dataType dataType, title string, value interface{}) error { |
| 67 | + if dataType == DataTypeNumber { |
| 68 | + val, ok := value.(int) |
| 69 | + if !ok { |
| 70 | + return ErrMarshal |
| 71 | + } |
| 72 | + |
| 73 | + c.Attributes = append(c.Attributes, customAttribute{title, dataType.String(), strconv.Itoa(val)}) |
| 74 | + return nil |
| 75 | + } |
| 76 | + |
| 77 | + val, ok := value.(string) |
| 78 | + if !ok { |
| 79 | + return ErrMarshal |
| 80 | + } |
| 81 | + c.Attributes = append(c.Attributes, customAttribute{title, dataType.String(), val}) |
| 82 | + return nil |
| 83 | +} |
| 84 | + |
| 85 | +type dataType string |
| 86 | + |
| 87 | +func (dt dataType) String() string { |
| 88 | + return string(dt) |
| 89 | +} |
| 90 | + |
| 91 | +// DataTypeNumber represents the Number datatype, use it when creating custom attributes |
| 92 | +const DataTypeNumber = dataType("Number") |
| 93 | + |
| 94 | +// DataTypeString represents the String datatype, use it when creating custom attributes |
| 95 | +const DataTypeString = dataType("String") |
| 96 | + |
| 97 | +type retryer struct { |
| 98 | + client.DefaultRetryer |
| 99 | + retryCount int |
| 100 | +} |
| 101 | + |
| 102 | +// MaxRetries sets the total exponential back off attempts to 10 retries |
| 103 | +func (r retryer) MaxRetries() int { |
| 104 | + if r.retryCount > 0 { |
| 105 | + return r.retryCount |
| 106 | + } |
| 107 | + |
| 108 | + return 10 |
| 109 | +} |
| 110 | + |
| 111 | +// newSession creates a new aws session |
| 112 | +func newSession(c Config) (*session.Session, error) { |
| 113 | + //sets credentials |
| 114 | + creds := credentials.NewStaticCredentials(c.Key, c.Secret, "") |
| 115 | + _, err := creds.Get() |
| 116 | + if err != nil { |
| 117 | + return nil, ErrInvalidCreds.Context(err) |
| 118 | + } |
| 119 | + |
| 120 | + r := &retryer{retryCount: c.RetryCount} |
| 121 | + |
| 122 | + cfg := request.WithRetryer(aws.NewConfig().WithRegion(c.Region).WithCredentials(creds), r) |
| 123 | + |
| 124 | + //if an optional hostname config is provided, then replace the default one |
| 125 | + // |
| 126 | + // This will set the default AWS URL to a hostname of your choice. Perfect for testing, or mocking functionality |
| 127 | + if c.Hostname != "" { |
| 128 | + cfg.Endpoint = &c.Hostname |
| 129 | + } |
| 130 | + |
| 131 | + return session.NewSession(cfg) |
| 132 | +} |
0 commit comments