diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go b/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go
index ffd999c8..dc714464 100644
--- a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go
+++ b/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go
@@ -40,20 +40,18 @@ type VisitorConfig struct {
type VisitorConfigData struct {
DataType string `json:"dataType"`
- ClientID string `json:"clientID"` // MQTT Client ID
- DeviceInfo string `json:"deviceInfo"` // Device information, such as device identification or other important information.
- OperationInfo OperationInfoType `json:"operationInfo"` // Operation information, such as adding, deleting, modifying and so on.
- SerializedFormat SerializedFormatType `json:"fileType"` // Supported formats: json, xml and yaml.
- ParsedMessage interface{} `json:"parsedMessage"` // The parsed message
+ ClientID string `json:"clientID"` // MQTT Client ID
+ DeviceInfo string `json:"deviceInfo"` // Device information, such as device identification or other important information.
+ OperationInfo OperationInfoType `json:"operationInfo"` // Operation information, such as adding, deleting, modifying and so on.
+ SerializedFormat SerializedFormatType `json:"fileType"` // Supported formats: json, xml and yaml.
+ ParsedMessage map[string]interface{} `json:"parsedMessage"` // The parsed message
}
// OperationInfoType defines the enumeration values for device operation.
type OperationInfoType uint
const (
- FULLTEXTMODIFY OperationInfoType = iota // full text revision
- PATHMODIFY // path revision
- VALUEMODIFY // value revision
+ UPDATE OperationInfoType = iota // revision
)
// SerializedFormatType defines the enumeration values for serialized types.
diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go b/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go
index bebae9bd..a6e10f81 100644
--- a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go
+++ b/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go
@@ -5,8 +5,10 @@ import (
"encoding/xml"
"errors"
"fmt"
+ "reflect"
"strings"
"sync"
+
"gopkg.in/yaml.v3"
)
@@ -132,9 +134,7 @@ func (c *ConfigData) GetMessage() (string, error) {
// OperationInfoType and SerializedFormatType mappings
var operationTypeMap = map[string]OperationInfoType{
- "fulltextmodify": FULLTEXTMODIFY,
- "pathmodify": PATHMODIFY,
- "valuemodify": VALUEMODIFY,
+ "update": UPDATE,
}
var serializedFormatMap = map[string]SerializedFormatType{
@@ -177,7 +177,7 @@ func (c *ConfigData) SplitTopic() (string, OperationInfoType, SerializedFormatTy
// The function ParseMessage parses the Message field according to the incoming type.
// parseType(0: json, 1: yaml, 2: xml)
// The value interface{} represents the parsed structure.
-func (c *ConfigData) ParseMessage(parseType SerializedFormatType) (interface{}, error) {
+func (c *ConfigData) ParseMessage(parseType SerializedFormatType) (map[string]interface{}, error) {
if c.Message == "" {
return nil, errors.New("message is empty")
}
@@ -200,7 +200,15 @@ func (c *ConfigData) ParseMessage(parseType SerializedFormatType) (interface{},
return nil, err
}
c.Message = convertedMessage
- return c.parseJSON()
+ originalMap, err := c.parseJSON()
+ var mp map[string]interface{}
+ for _, value := range originalMap {
+ if nestedMap, ok := value.(map[string]interface{}); ok {
+ mp = nestedMap
+ break
+ }
+ }
+ return mp, err
default:
return nil, errors.New("unsupported parse type")
@@ -208,12 +216,12 @@ func (c *ConfigData) ParseMessage(parseType SerializedFormatType) (interface{},
}
// The function parseJSON parses the Message field of the ConfigData (assumed to be a JSON string).
-func (c *ConfigData) parseJSON() (interface{}, error) {
+func (c *ConfigData) parseJSON() (map[string]interface{}, error) {
if c.Message == "" {
return nil, errors.New("message is empty")
}
- var result interface{}
+ var result map[string]interface{}
err := json.Unmarshal([]byte(c.Message), &result)
if err != nil {
return nil, err
@@ -267,6 +275,95 @@ func (c *ConfigData) NewVisitorConfigData() (*VisitorConfigData, error) {
}, nil
}
+/* --------------------------------------------------------------------------------------- */
+func (v *VisitorConfigData) ModifyVisitorConfigData(destDataConfig interface{}) error {
+ destValue := reflect.ValueOf(destDataConfig)
+ if destValue.Kind() != reflect.Ptr || destValue.Elem().Kind() != reflect.Struct {
+ return errors.New("destDataConfig must be a pointer to a struct")
+ }
+
+ destValue = destValue.Elem()
+
+ var tagName string
+ switch v.SerializedFormat {
+ case JSON:
+ tagName = "json"
+ case YAML:
+ tagName = "yaml"
+ case XML:
+ tagName = "xml"
+ default:
+ return errors.New("unknown serialized format")
+ }
+
+ // Update the destination struct using JSON tag
+ if err := updateStructFields(destValue, v.ParsedMessage, tagName); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// updateStructFields recursively updates struct fields from the given map using specified tag type
+func updateStructFields(structValue reflect.Value, data map[string]interface{}, tagName string) error {
+ structType := structValue.Type()
+
+ for i := 0; i < structValue.NumField(); i++ {
+ field := structValue.Field(i)
+ fieldType := structType.Field(i)
+ tagValue := fieldType.Tag.Get(tagName)
+
+ if tagValue == "" {
+ // Skip fields without the specified tag
+ continue
+ }
+
+ // Get the corresponding value from the map
+ value, exists := data[tagValue]
+ if !exists {
+ continue
+ }
+
+ // Update the field based on its kind
+ if field.Kind() == reflect.Struct {
+ // Recursively update nested structs
+ nestedData, ok := value.(map[string]interface{})
+ if !ok {
+ return fmt.Errorf("type mismatch for nested field %s", tagValue)
+ }
+ if err := updateStructFields(field, nestedData, tagName); err != nil {
+ return err
+ }
+ } else if field.Kind() == reflect.Slice {
+ // Handle slices if necessary
+ sliceData, ok := value.([]interface{})
+ if !ok {
+ return fmt.Errorf("type mismatch for slice field %s", tagValue)
+ }
+ newSlice := reflect.MakeSlice(field.Type(), len(sliceData), len(sliceData))
+ for j, item := range sliceData {
+ itemValue := reflect.ValueOf(item)
+ if newSlice.Index(j).Kind() == itemValue.Kind() {
+ newSlice.Index(j).Set(itemValue)
+ } else {
+ return fmt.Errorf("type mismatch for slice item in field %s", tagValue)
+ }
+ }
+ field.Set(newSlice)
+ } else {
+ // Set the field value
+ fieldValue := reflect.ValueOf(value)
+ if field.Type() == fieldValue.Type() {
+ field.Set(fieldValue)
+ } else {
+ return fmt.Errorf("type mismatch for field %s", tagValue)
+ }
+ }
+ }
+ return nil
+}
+
+
/* --------------------------------------------------------------------------------------- */
// The function ConvertYAMLToJSON converts a YAML string to a JSON string.
func convertYAMLToJSON(yamlString string) (string, error) {
@@ -325,7 +422,8 @@ func wrapXMLWithRoot(xmlString string) string {
}
// Wrap the remaining XML content with
- wrappedXML := "" + xmlString + ""
+ // wrappedXML := "" + xmlString + ""
+ wrappedXML := xmlString
return wrappedXML
}