diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go b/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go deleted file mode 100644 index dc714464..00000000 --- a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/devicetype.go +++ /dev/null @@ -1,78 +0,0 @@ -package driver - -import ( - "sync" - mqtt "github.com/eclipse/paho.mqtt.golang" - "github.com/kubeedge/mapper-framework/pkg/common" -) - -// CustomizedDev is the customized device configuration and client information. -type CustomizedDev struct { - CustomizedClient *CustomizedClient - Instance common.DeviceInstance -} - -type CustomizedClient struct { - // TODO add some variables to help you better implement device drivers - deviceMutex sync.Mutex - ProtocolConfig - MessageQueue MessageQueue -} - -type ProtocolConfig struct { - ProtocolName string `json:"protocolName"` - ConfigData `json:"configData"` -} - -type ConfigData struct { - // MQTT protocol config data - ClientID string `json:"clientID"` // MQTT Client ID - Topic string `json:"topic"` // Client need to specify a topic when publishing or subsribing. - Message string `json:"message"` // Content of the message -} - - -type VisitorConfig struct { - ProtocolName string `json:"protocolName"` - VisitorConfigData `json:"configData"` -} - -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 map[string]interface{} `json:"parsedMessage"` // The parsed message -} - -// OperationInfoType defines the enumeration values for device operation. -type OperationInfoType uint - -const ( - UPDATE OperationInfoType = iota // revision -) - -// SerializedFormatType defines the enumeration values for serialized types. -type SerializedFormatType uint - -const ( - JSON SerializedFormatType = iota // json - YAML // yaml - XML // xml -) - -// MessageQueue defines generic message queue operations and contains three methods: -// Publish is used to publish a message to the specified topic, the type of the message is interface{} in order to support multiple message formats. -// Subscribe subscribes to the specified topic, return the received message. -// Unsubscribe unsubscribes to the specified topic. -type MessageQueue interface { - Publish(topic string, message interface{}) error - Subscribe(topic string) (interface{}, error) - Unsubscribe(topic string) error -} - -type MqttMessageQueue struct { - client mqtt.Client -} diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/messagequeue.go b/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/messagequeue.go deleted file mode 100644 index 98fb22d4..00000000 --- a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/messagequeue.go +++ /dev/null @@ -1,60 +0,0 @@ -package driver - -import ( - "fmt" - "time" - - mqtt "github.com/eclipse/paho.mqtt.golang" -) - -// NewMqttMessageQueueWithAuth creates and initializes an MqttMessageQueue instance with authentication. -func NewMqttMessageQueueWithAuth(broker string, clientID string, username string, password string) (*MqttMessageQueue, error) { - opts := mqtt.NewClientOptions(). - AddBroker(broker). - SetClientID(clientID). - SetUsername(username). - SetPassword(password). - SetConnectTimeout(10 * time.Second) - - client := mqtt.NewClient(opts) - if token := client.Connect(); token.Wait() && token.Error() != nil { - return nil, token.Error() - } - - return &MqttMessageQueue{ - client: client, - }, nil -} - - -// Publish is used to publish a message to the specified topic, the type of the message is interface{} in order to support multiple message formats. -func (mq *MqttMessageQueue) Publish(topic string, message interface{}) error { - payload, ok := message.(string) - if !ok { - return fmt.Errorf("message must be a string") - } - token := mq.client.Publish(topic, 0, false, payload) - token.Wait() - return token.Error() -} - -// Subscribe subscribes to the specified topic, return the received message. -func (mq *MqttMessageQueue) Subscribe(topic string) (interface{}, error) { - ch := make(chan mqtt.Message) - token := mq.client.Subscribe(topic, 0, func(client mqtt.Client, msg mqtt.Message) { - ch <- msg - }) - token.Wait() - if token.Error() != nil { - return nil, token.Error() - } - message := <-ch - return string(message.Payload()), nil -} - -// Unsubscribe unsubscribes to the specified topic. -func (mq *MqttMessageQueue) Unsubscribe(topic string) error { - token := mq.client.Unsubscribe(topic) - token.Wait() - return token.Error() -} diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/Dockerfile b/mappers/mqtt-mapper/Dockerfile similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/Dockerfile rename to mappers/mqtt-mapper/Dockerfile diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/Dockerfile_nostream b/mappers/mqtt-mapper/Dockerfile_nostream similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/Dockerfile_nostream rename to mappers/mqtt-mapper/Dockerfile_nostream diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/Dockerfile_stream b/mappers/mqtt-mapper/Dockerfile_stream similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/Dockerfile_stream rename to mappers/mqtt-mapper/Dockerfile_stream diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/Makefile b/mappers/mqtt-mapper/Makefile similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/Makefile rename to mappers/mqtt-mapper/Makefile diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/cmd/main.go b/mappers/mqtt-mapper/cmd/main.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/cmd/main.go rename to mappers/mqtt-mapper/cmd/main.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/config.yaml b/mappers/mqtt-mapper/config.yaml similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/config.yaml rename to mappers/mqtt-mapper/config.yaml diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/influxdb2/client.go b/mappers/mqtt-mapper/data/dbmethod/influxdb2/client.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/influxdb2/client.go rename to mappers/mqtt-mapper/data/dbmethod/influxdb2/client.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/influxdb2/handler.go b/mappers/mqtt-mapper/data/dbmethod/influxdb2/handler.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/influxdb2/handler.go rename to mappers/mqtt-mapper/data/dbmethod/influxdb2/handler.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/mysql/client.go b/mappers/mqtt-mapper/data/dbmethod/mysql/client.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/mysql/client.go rename to mappers/mqtt-mapper/data/dbmethod/mysql/client.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/mysql/handler.go b/mappers/mqtt-mapper/data/dbmethod/mysql/handler.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/mysql/handler.go rename to mappers/mqtt-mapper/data/dbmethod/mysql/handler.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/redis/client.go b/mappers/mqtt-mapper/data/dbmethod/redis/client.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/redis/client.go rename to mappers/mqtt-mapper/data/dbmethod/redis/client.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/redis/handler.go b/mappers/mqtt-mapper/data/dbmethod/redis/handler.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/redis/handler.go rename to mappers/mqtt-mapper/data/dbmethod/redis/handler.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/tdengine/client.go b/mappers/mqtt-mapper/data/dbmethod/tdengine/client.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/tdengine/client.go rename to mappers/mqtt-mapper/data/dbmethod/tdengine/client.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/tdengine/handler.go b/mappers/mqtt-mapper/data/dbmethod/tdengine/handler.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/dbmethod/tdengine/handler.go rename to mappers/mqtt-mapper/data/dbmethod/tdengine/handler.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/publish/http/client.go b/mappers/mqtt-mapper/data/publish/http/client.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/publish/http/client.go rename to mappers/mqtt-mapper/data/publish/http/client.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/publish/mqtt/client.go b/mappers/mqtt-mapper/data/publish/mqtt/client.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/publish/mqtt/client.go rename to mappers/mqtt-mapper/data/publish/mqtt/client.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/stream/handler.go b/mappers/mqtt-mapper/data/stream/handler.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/stream/handler.go rename to mappers/mqtt-mapper/data/stream/handler.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/stream/img.go b/mappers/mqtt-mapper/data/stream/img.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/stream/img.go rename to mappers/mqtt-mapper/data/stream/img.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/data/stream/video.go b/mappers/mqtt-mapper/data/stream/video.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/data/stream/video.go rename to mappers/mqtt-mapper/data/stream/video.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/device/device.go b/mappers/mqtt-mapper/device/device.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/device/device.go rename to mappers/mqtt-mapper/device/device.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/device/devicestatus.go b/mappers/mqtt-mapper/device/devicestatus.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/device/devicestatus.go rename to mappers/mqtt-mapper/device/devicestatus.go diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/device/devicetwin.go b/mappers/mqtt-mapper/device/devicetwin.go similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/device/devicetwin.go rename to mappers/mqtt-mapper/device/devicetwin.go diff --git a/mappers/mqtt-mapper/driver/devicetype.go b/mappers/mqtt-mapper/driver/devicetype.go new file mode 100644 index 00000000..0d01e426 --- /dev/null +++ b/mappers/mqtt-mapper/driver/devicetype.go @@ -0,0 +1,72 @@ +package driver + +import ( + "sync" + "time" + + "github.com/kubeedge/mapper-framework/pkg/common" +) + +// CustomizedDev is the customized device configuration and client information. +type CustomizedDev struct { + CustomizedClient *CustomizedClient + Instance common.DeviceInstance +} + +type CustomizedClient struct { + // TODO add some variables to help you better implement device drivers + deviceMutex sync.Mutex + ProtocolConfig + DeviceInfo string `json:"deviceInfo"` + ParsedDeviceInfo map[string]interface{} `json:"parsedDeviceInfo"` +} + +type ProtocolConfig struct { + ProtocolName string `json:"protocolName"` + ConfigData `json:"configData"` +} + +type ConfigData struct { + // MQTT protocol config data + ClientID string `json:"clientID"` // MQTT Client ID + BrokerURL string `json:"brokerURL"` // MQTT Broker URL + Topic string `json:"topic"` // Topic for publishing or subscribing + Message string `json:"message"` // Content of the message + Username string `json:"username"` // Username for MQTT broker authentication + Password string `json:"password"` // Password for MQTT broker authentication + ConnectionTTL time.Duration `json:"connectionTTL"` // Connection timeout duration + LastMessage time.Time `json:"lastMessage"` // Timestamp of the last received message + IsData bool `json:"isData"` // Indicates if there is valid data +} + +type VisitorConfig struct { + ProtocolName string `json:"protocolName"` + VisitorConfigData `json:"configData"` +} + +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 map[string]interface{} `json:"parsedMessage"` // The parsed message +} + +// OperationInfoType defines the enumeration values for device operation. +type OperationInfoType uint + +const ( + UPDATE OperationInfoType = iota // revision +) + +// SerializedFormatType defines the enumeration values for serialized types. +type SerializedFormatType uint + +const ( + JSON SerializedFormatType = iota // json + YAML // yaml + XML // xml + JSONPATH +) diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go b/mappers/mqtt-mapper/driver/driver.go similarity index 72% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go rename to mappers/mqtt-mapper/driver/driver.go index a6e10f81..078a14de 100644 --- a/mappers/kubeedge-v1.17.0/mqtt-mapper/driver/driver.go +++ b/mappers/mqtt-mapper/driver/driver.go @@ -6,85 +6,46 @@ import ( "errors" "fmt" "reflect" + "strconv" "strings" "sync" + "github.com/kubeedge/mapper-framework/pkg/common" "gopkg.in/yaml.v3" ) -func NewClientWithMessageQueue(protocol ProtocolConfig, queue MessageQueue) (*CustomizedClient, error) { - return &CustomizedClient{ - ProtocolConfig: protocol, - deviceMutex: sync.Mutex{}, - MessageQueue: queue, - }, nil +func NewClient(protocol ProtocolConfig) (*CustomizedClient, error) { + client := &CustomizedClient{ + ProtocolConfig: protocol, + deviceMutex: sync.Mutex{}, + DeviceInfo: "", + ParsedDeviceInfo: make(map[string]interface{}), + } + return client, nil } -// Thread-safe access to ProtocolConfig. -func (client *CustomizedClient) GetProtocolConfig() ProtocolConfig { - client.deviceMutex.Lock() - defer client.deviceMutex.Unlock() - - return client.ProtocolConfig +func (c *CustomizedClient) InitDevice() error { + configData := &c.ProtocolConfig.ConfigData + _, _, format, _ := configData.SplitTopic() + c.DeviceInfo = c.ProtocolConfig.ConfigData.Message + c.ParsedDeviceInfo, _ = c.ParseMessage(format) + return nil } -// Thread-safe setting of ProtocolConfig. -func (client *CustomizedClient) SetProtocolConfig(config ProtocolConfig) { - client.deviceMutex.Lock() - defer client.deviceMutex.Unlock() +func (c *CustomizedClient) GetDeviceData(visitor *VisitorConfig) (interface{}, error) { - client.ProtocolConfig = config + return nil, nil } -// Thread-safe publishing of messages to MQTT. -func (client *CustomizedClient) SafePublish(topic string, message interface{}) error { - client.deviceMutex.Lock() - defer client.deviceMutex.Unlock() - - if client.MessageQueue == nil { - return errors.New("message queue is not initialized") - } - - // Calls the Publish method of the message queue - err := client.MessageQueue.Publish(topic, message) - if err != nil { - return fmt.Errorf("failed to publish message: %v", err) - } +func (c *CustomizedClient) SetDeviceData(data interface{}, visitor *VisitorConfig) error { + vPointer := visitor.VisitorConfigData + vPointer.ModifyVisitorConfigData(c.ParsedDeviceInfo) return nil } -// Thread-safe subscription to MQTT topics -func (client *CustomizedClient) SafeSubscribe(topic string) (interface{}, error) { - client.deviceMutex.Lock() - defer client.deviceMutex.Unlock() - - if client.MessageQueue == nil { - return nil, errors.New("message queue is not initialized") - } - - // Call the Subscribe method of the message queue - msg, err := client.MessageQueue.Subscribe(topic) - if err != nil { - return nil, fmt.Errorf("failed to subscribe to topic: %v", err) - } - return msg, nil -} - -// Thread-Safe Unsubscription to MQTT Topics -func (client *CustomizedClient) SafeUnsubscribe(topic string) error { - client.deviceMutex.Lock() - defer client.deviceMutex.Unlock() - - if client.MessageQueue == nil { - return errors.New("message queue is not initialized") - } - - // Call the Unsubscribe method of the message queue - err := client.MessageQueue.Unsubscribe(topic) - if err != nil { - return fmt.Errorf("failed to unsubscribe from topic: %v", err) - } - return nil +func (c *CustomizedClient) GetDeviceStates() (string, error) { + // TODO: GetDeviceStates + return common.DeviceStatusOK, nil } /* --------------------------------------------------------------------------------------- */ @@ -195,12 +156,12 @@ func (c *ConfigData) ParseMessage(parseType SerializedFormatType) (map[string]in return c.parseJSON() case XML: // xml - convertedMessage, err := convertXMLToJSON(c.Message) + convertedMessage, err := convertXMLToMap(c.Message) if err != nil { return nil, err } - c.Message = convertedMessage - originalMap, err := c.parseJSON() + // c.Message = convertedMessage + originalMap := convertedMessage var mp map[string]interface{} for _, value := range originalMap { if nestedMap, ok := value.(map[string]interface{}); ok { @@ -246,33 +207,33 @@ func (c *ConfigData) ValidateMessage() error { // NewVisitorConfigData creates a new instance of VisitorConfigData using ConfigData pointer and the result of SplitTopic. func (c *ConfigData) NewVisitorConfigData() (*VisitorConfigData, error) { - // get ClientID - clientID, err := c.GetClientID() - if err != nil { - return nil, err - } - - // get DeviceInfo, OperationInfo and SerializedFormat - deviceInfo, operationInfo, serializedFormat, err := c.SplitTopic() - if err != nil { - return nil, err - } - - // get ParsedMessage - parsedMessage, err := c.ParseMessage(serializedFormat) - if err != nil { - return nil, err - } - - // create - return &VisitorConfigData{ - DataType: "string", - ClientID: clientID, - DeviceInfo: deviceInfo, - OperationInfo: operationInfo, - SerializedFormat: serializedFormat, - ParsedMessage: parsedMessage, - }, nil + // get ClientID + clientID, err := c.GetClientID() + if err != nil { + return nil, err + } + + // get DeviceInfo, OperationInfo and SerializedFormat + deviceInfo, operationInfo, serializedFormat, err := c.SplitTopic() + if err != nil { + return nil, err + } + + // get ParsedMessage + parsedMessage, err := c.ParseMessage(serializedFormat) + if err != nil { + return nil, err + } + + // create + return &VisitorConfigData{ + DataType: "string", + ClientID: clientID, + DeviceInfo: deviceInfo, + OperationInfo: operationInfo, + SerializedFormat: serializedFormat, + ParsedMessage: parsedMessage, + }, nil } /* --------------------------------------------------------------------------------------- */ @@ -313,20 +274,26 @@ func updateStructFields(structValue reflect.Value, data map[string]interface{}, fieldType := structType.Field(i) tagValue := fieldType.Tag.Get(tagName) - if tagValue == "" { - // Skip fields without the specified tag - continue + var value interface{} + var exists bool + + if tagValue != "" { + // Attempt to get value using tag + value, exists = data[tagValue] + } + + if !exists { + // Fallback to field name if tag is not found + tagValue = fieldType.Name + value, exists = data[tagValue] } - // 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) @@ -335,7 +302,6 @@ func updateStructFields(structValue reflect.Value, data map[string]interface{}, 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) @@ -351,7 +317,6 @@ func updateStructFields(structValue reflect.Value, data map[string]interface{}, } field.Set(newSlice) } else { - // Set the field value fieldValue := reflect.ValueOf(value) if field.Type() == fieldValue.Type() { field.Set(fieldValue) @@ -363,7 +328,6 @@ func updateStructFields(structValue reflect.Value, data map[string]interface{}, return nil } - /* --------------------------------------------------------------------------------------- */ // The function ConvertYAMLToJSON converts a YAML string to a JSON string. func convertYAMLToJSON(yamlString string) (string, error) { @@ -383,21 +347,6 @@ func convertYAMLToJSON(yamlString string) (string, error) { return string(jsonData), nil } -// The function convertXMLToJSON converts an XML string to a JSON string. -func convertXMLToJSON(xmlString string) (string, error) { - xmlData, err := convertXMLToMap(xmlString) - if err != nil { - return "", err - } - - jsonData, err := mapToJSON(xmlData) - if err != nil { - return "", err - } - - return jsonData, nil -} - // The function ConvertXMLToMap converts XML string to map[string]interface{}. func convertXMLToMap(xmlString string) (map[string]interface{}, error) { // Wrap the XML content with @@ -422,7 +371,6 @@ func wrapXMLWithRoot(xmlString string) string { } // Wrap the remaining XML content with - // wrappedXML := "" + xmlString + "" wrappedXML := xmlString return wrappedXML } @@ -435,15 +383,29 @@ type Node struct { Attr []xml.Attr `xml:"-"` } +// convertValue attempts to convert string content to appropriate type. +func convertValue(content string) interface{} { + if f, err := strconv.ParseFloat(content, 64); err == nil { + return f + } else if i, err := strconv.Atoi(content); err == nil { + return i + } else if b, err := strconv.ParseBool(content); err == nil { + return b + } else { + return content + } +} + // The function nodeToMap recursively converts XML nodes to map[string]interface{}. func nodeToMap(node Node) map[string]interface{} { result := make(map[string]interface{}) + // If the node has no children, it is a leaf node, apply type conversion. if len(node.Nodes) == 0 { - // Leaf node - return map[string]interface{}{node.XMLName.Local: node.Content} + return map[string]interface{}{node.XMLName.Local: convertValue(strings.TrimSpace(node.Content))} } + // Process child nodes recursively. for _, child := range node.Nodes { childMap := nodeToMap(child) if existing, found := result[child.XMLName.Local]; found { @@ -470,4 +432,12 @@ func mapToJSON(data map[string]interface{}) (string, error) { return string(jsonData), nil } -/* --------------------------------------------------------------------------------------- */ \ No newline at end of file +func StructToJSON(v interface{}) (string, error) { + jsonData, err := json.MarshalIndent(v, "", " ") + if err != nil { + return "", err + } + return string(jsonData), nil +} + +/* --------------------------------------------------------------------------------------- */ diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/go.mod b/mappers/mqtt-mapper/go.mod similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/go.mod rename to mappers/mqtt-mapper/go.mod diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/go.sum b/mappers/mqtt-mapper/go.sum similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/go.sum rename to mappers/mqtt-mapper/go.sum diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/hack/make-rules/mapper.sh b/mappers/mqtt-mapper/hack/make-rules/mapper.sh similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/hack/make-rules/mapper.sh rename to mappers/mqtt-mapper/hack/make-rules/mapper.sh diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/resource/configmap.yaml b/mappers/mqtt-mapper/resource/configmap.yaml similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/resource/configmap.yaml rename to mappers/mqtt-mapper/resource/configmap.yaml diff --git a/mappers/kubeedge-v1.17.0/mqtt-mapper/resource/deployment.yaml b/mappers/mqtt-mapper/resource/deployment.yaml similarity index 100% rename from mappers/kubeedge-v1.17.0/mqtt-mapper/resource/deployment.yaml rename to mappers/mqtt-mapper/resource/deployment.yaml