-
Notifications
You must be signed in to change notification settings - Fork 473
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a new binding component : alicloud sls log storage (#1873)
* new a bingding componet alicloud sls logstorage Signed-off-by: RcXu <[email protected]> Signed-off-by: Bernd Verst <[email protected]> * update sls binding component Signed-off-by: RcXu <[email protected]> Signed-off-by: Bernd Verst <[email protected]> * update the metadata decode method Signed-off-by: RcXu <[email protected]> Signed-off-by: Bernd Verst <[email protected]> * make modtidy-all Signed-off-by: Bernd Verst <[email protected]> * sort imports Signed-off-by: Bernd Verst <[email protected]> Co-authored-by: RcXu <[email protected]> Co-authored-by: Bernd Verst <[email protected]> Co-authored-by: Dapr Bot <[email protected]>
- Loading branch information
1 parent
5b14b00
commit 66d92cd
Showing
4 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package sls | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"time" | ||
|
||
sls "github.com/aliyun/aliyun-log-go-sdk" | ||
"github.com/aliyun/aliyun-log-go-sdk/producer" | ||
|
||
"github.com/dapr/components-contrib/bindings" | ||
"github.com/dapr/kit/config" | ||
"github.com/dapr/kit/logger" | ||
) | ||
|
||
type AliCloudSlsLogstorage struct { | ||
logger logger.Logger | ||
producer *producer.Producer | ||
metadata SlsLogstorageMetadata | ||
} | ||
|
||
type SlsLogstorageMetadata struct { | ||
Endpoint string `json:"endpoint"` | ||
AccessKeyID string `json:"accessKeyID"` | ||
AccessKeySecret string `json:"accessKeySecret"` | ||
} | ||
|
||
type Callback struct { | ||
s *AliCloudSlsLogstorage | ||
} | ||
|
||
// parse metadata field | ||
func (s *AliCloudSlsLogstorage) Init(metadata bindings.Metadata) error { | ||
m, err := s.parseMeta(metadata) | ||
if err != nil { | ||
return err | ||
} | ||
s.metadata = *m | ||
producerConfig := producer.GetDefaultProducerConfig() | ||
// the config properties in the component yaml file | ||
producerConfig.Endpoint = m.Endpoint | ||
producerConfig.AccessKeyID = m.AccessKeyID | ||
producerConfig.AccessKeySecret = m.AccessKeySecret | ||
s.producer = producer.InitProducer(producerConfig) | ||
|
||
s.producer.Start() | ||
return nil | ||
} | ||
|
||
func NewAliCloudSlsLogstorage(logger logger.Logger) *AliCloudSlsLogstorage { | ||
logger.Debug("initialized Sls log storage binding component") | ||
s := &AliCloudSlsLogstorage{ | ||
logger: logger, | ||
} | ||
return s | ||
} | ||
|
||
func (s *AliCloudSlsLogstorage) Invoke(ctx context.Context, req *bindings.InvokeRequest) (*bindings.InvokeResponse, error) { | ||
// verify the metadata property | ||
if logProject := req.Metadata["project"]; logProject == "" { | ||
return nil, fmt.Errorf("SLS binding error: project property not supplied") | ||
} | ||
if logstore := req.Metadata["logstore"]; logstore == "" { | ||
return nil, fmt.Errorf("SLS binding error: logstore property not supplied") | ||
} | ||
if topic := req.Metadata["topic"]; topic == "" { | ||
return nil, fmt.Errorf("SLS binding error: topic property not supplied") | ||
} | ||
if source := req.Metadata["source"]; source == "" { | ||
return nil, fmt.Errorf("SLS binding error: source property not supplied") | ||
} | ||
|
||
log, err := s.parseLog(req) | ||
if err != nil { | ||
s.logger.Info(err) | ||
return nil, err | ||
} | ||
|
||
s.logger.Debug(log) | ||
callBack := &Callback{} | ||
err = s.producer.SendLogWithCallBack(req.Metadata["project"], req.Metadata["logstore"], req.Metadata["topic"], req.Metadata["source"], log, callBack) | ||
if err != nil { | ||
s.logger.Info(err) | ||
return nil, err | ||
} | ||
return nil, nil | ||
} | ||
|
||
// parse the log content | ||
func (s *AliCloudSlsLogstorage) parseLog(req *bindings.InvokeRequest) (*sls.Log, error) { | ||
var logInfo map[string]string | ||
err := json.Unmarshal(req.Data, &logInfo) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return producer.GenerateLog(uint32(time.Now().Unix()), logInfo), nil | ||
} | ||
|
||
func (s *AliCloudSlsLogstorage) parseMeta(metadata bindings.Metadata) (*SlsLogstorageMetadata, error) { | ||
var m SlsLogstorageMetadata | ||
err := config.Decode(metadata.Properties, &m) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &m, nil | ||
} | ||
|
||
func (s *AliCloudSlsLogstorage) Operations() []bindings.OperationKind { | ||
return []bindings.OperationKind{bindings.CreateOperation} | ||
} | ||
|
||
func (callback *Callback) Success(result *producer.Result) { | ||
} | ||
|
||
func (callback *Callback) Fail(result *producer.Result) { | ||
msg := "unknown reason" | ||
if result.GetErrorMessage() != "" { | ||
msg = result.GetErrorMessage() | ||
} | ||
if result.GetErrorCode() != "" { | ||
callback.s.logger.Debug("Failed error code:", result.GetErrorCode()) | ||
} | ||
|
||
callback.s.logger.Info("Log storage failed:", msg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package sls | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/dapr/components-contrib/bindings" | ||
) | ||
|
||
/** | ||
* test the metadata in the yaml file | ||
*/ | ||
func TestSlsLogstorageMetadata(t *testing.T) { | ||
m := bindings.Metadata{} | ||
m.Properties = map[string]string{ | ||
"Endpoint": "ENDPOINT", | ||
"AccessKeyID": "ACCESSKEYID", | ||
"AccessKeySecret": "ACCESSKEYSECRET", | ||
} | ||
aliCloudSlsLogstorage := AliCloudSlsLogstorage{} | ||
|
||
meta, err := aliCloudSlsLogstorage.parseMeta(m) | ||
|
||
assert.Nil(t, err) | ||
assert.Equal(t, "ENDPOINT", meta.Endpoint) | ||
assert.Equal(t, "ACCESSKEYID", meta.AccessKeyID) | ||
assert.Equal(t, "ACCESSKEYSECRET", meta.AccessKeySecret) | ||
} | ||
|
||
/* | ||
* test the log content | ||
*/ | ||
func TestParseLog(t *testing.T) { | ||
aliCloudSlsLogstorage := AliCloudSlsLogstorage{} | ||
d, _ := json.Marshal(map[string]string{ | ||
"log1": "LOG1", | ||
"log2": "LOG2", | ||
}) | ||
log := bindings.InvokeRequest{ | ||
Data: d, | ||
Metadata: map[string]string{ | ||
"project": "PROJECT", | ||
"logstore": "LOGSTORE", | ||
"topic": "TOPIC", | ||
"source": "SOURCE", | ||
}, | ||
} | ||
parseLog, _ := aliCloudSlsLogstorage.parseLog(&log) | ||
for _, v := range parseLog.Contents { | ||
switch *v.Key { | ||
case "log1": | ||
assert.Equal(t, "LOG1", *v.Value) | ||
case "log2": | ||
assert.Equal(t, "LOG2", *v.Value) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters