diff options
| author | KubeEdge Bot <48982446+kubeedge-bot@users.noreply.github.com> | 2023-09-25 10:02:01 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-25 10:02:01 +0800 |
| commit | 6efa7d14472ce8bc9f779163517f4df353076b24 (patch) | |
| tree | c90d50f04c268203a28536dc55be2c1cb545536f /cloud | |
| parent | Merge pull request #5006 from wlq1212/k8scompatibility/schedule (diff) | |
| parent | device crd v1beta1 test (diff) | |
| download | kubeedge-6efa7d14472ce8bc9f779163517f4df353076b24.tar.gz | |
Merge pull request #4983 from cl2017/device_v1beta1_api
device crd v1beta1 and API definition
Diffstat (limited to 'cloud')
| -rw-r--r-- | cloud/pkg/admissioncontroller/admission.go | 6 | ||||
| -rw-r--r-- | cloud/pkg/admissioncontroller/admit_devicemodel.go | 16 | ||||
| -rw-r--r-- | cloud/pkg/devicecontroller/controller/downstream.go | 756 | ||||
| -rw-r--r-- | cloud/pkg/devicecontroller/controller/upstream.go | 10 | ||||
| -rw-r--r-- | cloud/pkg/devicecontroller/manager/configmap.go | 16 | ||||
| -rw-r--r-- | cloud/pkg/devicecontroller/manager/device.go | 2 | ||||
| -rw-r--r-- | cloud/pkg/devicecontroller/types/deviceprofile.go | 100 | ||||
| -rw-r--r-- | cloud/test/integration/crds/validation_test.go | 343 | ||||
| -rw-r--r-- | cloud/test/integration/fixtures/constants.go | 87 | ||||
| -rw-r--r-- | cloud/test/integration/fixtures/device.go | 600 | ||||
| -rw-r--r-- | cloud/test/integration/fixtures/devicemodel.go | 158 |
11 files changed, 81 insertions, 2013 deletions
diff --git a/cloud/pkg/admissioncontroller/admission.go b/cloud/pkg/admissioncontroller/admission.go index 2dbc1ebc5..7d9240512 100644 --- a/cloud/pkg/admissioncontroller/admission.go +++ b/cloud/pkg/admissioncontroller/admission.go @@ -21,7 +21,7 @@ import ( "k8s.io/klog/v2" "github.com/kubeedge/kubeedge/cloud/cmd/admission/app/options" - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" + "github.com/kubeedge/kubeedge/pkg/apis/devices/v1beta1" v1 "github.com/kubeedge/kubeedge/pkg/apis/rules/v1" "github.com/kubeedge/kubeedge/pkg/client/clientset/versioned" ) @@ -58,7 +58,7 @@ func addToScheme(scheme *runtime.Scheme) { utilruntime.Must(corev1.AddToScheme(scheme)) utilruntime.Must(admissionv1.AddToScheme(scheme)) utilruntime.Must(admissionregistrationv1.AddToScheme(scheme)) - utilruntime.Must(v1alpha2.AddDeviceCrds(scheme)) + utilruntime.Must(v1beta1.AddDeviceCrds(scheme)) } // AdmissionController implements the admission webhook for validation of configuration. @@ -172,7 +172,7 @@ func (ac *AdmissionController) registerWebhooks(opt *options.AdmissionOptions, c }, Rule: admissionregistrationv1.Rule{ APIGroups: []string{"devices.kubeedge.io"}, - APIVersions: []string{"v1alpha2"}, + APIVersions: []string{"v1beta1"}, Resources: []string{"devicemodels"}, }, }}, diff --git a/cloud/pkg/admissioncontroller/admit_devicemodel.go b/cloud/pkg/admissioncontroller/admit_devicemodel.go index 5aecc6b71..48262fcc3 100644 --- a/cloud/pkg/admissioncontroller/admit_devicemodel.go +++ b/cloud/pkg/admissioncontroller/admit_devicemodel.go @@ -8,7 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog/v2" - devicesv1alpha2 "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" + devicesv1beta1 "github.com/kubeedge/kubeedge/pkg/apis/devices/v1beta1" ) func admitDeviceModel(review admissionv1.AdmissionReview) *admissionv1.AdmissionResponse { @@ -19,7 +19,7 @@ func admitDeviceModel(review admissionv1.AdmissionReview) *admissionv1.Admission switch review.Request.Operation { case admissionv1.Create, admissionv1.Update: raw := review.Request.Object.Raw - devicemodel := devicesv1alpha2.DeviceModel{} + devicemodel := devicesv1beta1.DeviceModel{} deserializer := codecs.UniversalDeserializer() if _, _, err := deserializer.Decode(raw, nil, &devicemodel); err != nil { klog.Errorf("validation failed with error: %v", err) @@ -40,15 +40,15 @@ func admitDeviceModel(review admissionv1.AdmissionReview) *admissionv1.Admission return &reviewResponse } -func validateDeviceModel(devicemodel *devicesv1alpha2.DeviceModel, response *admissionv1.AdmissionResponse) string { +func validateDeviceModel(devicemodel *devicesv1beta1.DeviceModel, response *admissionv1.AdmissionResponse) string { //device properties must be either Int or String while additional properties is not banned. var msg string + propertyNameMap := make(map[string]bool) for _, property := range devicemodel.Spec.Properties { - if property.Type.String == nil && property.Type.Int == nil { - msg = "Either Int or String must be set" - response.Allowed = false - } else if property.Type.String != nil && property.Type.Int != nil { - msg = "Only one of [Int, String] could be set for properties" + if _, ok := propertyNameMap[property.Name]; !ok { + propertyNameMap[property.Name] = true + } else { + msg = "property names must be unique." response.Allowed = false } } diff --git a/cloud/pkg/devicecontroller/controller/downstream.go b/cloud/pkg/devicecontroller/controller/downstream.go index 5bc3c1acf..808238e15 100644 --- a/cloud/pkg/devicecontroller/controller/downstream.go +++ b/cloud/pkg/devicecontroller/controller/downstream.go @@ -17,16 +17,10 @@ limitations under the License. package controller import ( - "context" - "encoding/json" "reflect" - "strconv" "time" "github.com/google/uuid" - v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" @@ -40,7 +34,7 @@ import ( "github.com/kubeedge/kubeedge/cloud/pkg/devicecontroller/constants" "github.com/kubeedge/kubeedge/cloud/pkg/devicecontroller/manager" "github.com/kubeedge/kubeedge/cloud/pkg/devicecontroller/types" - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" + "github.com/kubeedge/kubeedge/pkg/apis/devices/v1beta1" crdinformers "github.com/kubeedge/kubeedge/pkg/client/informers/externalversions" ) @@ -51,7 +45,6 @@ type DownstreamController struct { deviceManager *manager.DeviceManager deviceModelManager *manager.DeviceModelManager - configMapManager *manager.ConfigMapManager } // syncDeviceModel is used to get events from informer @@ -62,7 +55,7 @@ func (dc *DownstreamController) syncDeviceModel() { klog.Info("stop syncDeviceModel") return case e := <-dc.deviceModelManager.Events(): - deviceModel, ok := e.Object.(*v1alpha2.DeviceModel) + deviceModel, ok := e.Object.(*v1beta1.DeviceModel) if !ok { klog.Warningf("object type: %T unsupported", e.Object) continue @@ -70,10 +63,10 @@ func (dc *DownstreamController) syncDeviceModel() { switch e.Type { case watch.Added: dc.deviceModelAdded(deviceModel) - case watch.Deleted: - dc.deviceModelDeleted(deviceModel) case watch.Modified: dc.deviceModelUpdated(deviceModel) + case watch.Deleted: + dc.deviceModelDeleted(deviceModel) default: klog.Warningf("deviceModel event type: %s unsupported", e.Type) } @@ -82,40 +75,19 @@ func (dc *DownstreamController) syncDeviceModel() { } // deviceModelAdded is function to process addition of new deviceModel in apiserver -func (dc *DownstreamController) deviceModelAdded(deviceModel *v1alpha2.DeviceModel) { +func (dc *DownstreamController) deviceModelAdded(deviceModel *v1beta1.DeviceModel) { // nothing to do when deviceModel added, only add in map dc.deviceModelManager.DeviceModel.Store(deviceModel.Name, deviceModel) } -// isDeviceModelUpdated is function to check if deviceModel is actually updated -func isDeviceModelUpdated(oldTwin *v1alpha2.DeviceModel, newTwin *v1alpha2.DeviceModel) bool { - // does not care fields - oldTwin.ObjectMeta.ResourceVersion = newTwin.ObjectMeta.ResourceVersion - oldTwin.ObjectMeta.Generation = newTwin.ObjectMeta.Generation - - // return true if ObjectMeta or Spec or Status changed, else false - return !reflect.DeepEqual(oldTwin.ObjectMeta, newTwin.ObjectMeta) || !reflect.DeepEqual(oldTwin.Spec, newTwin.Spec) -} - // deviceModelUpdated is function to process updated deviceModel -func (dc *DownstreamController) deviceModelUpdated(deviceModel *v1alpha2.DeviceModel) { - value, ok := dc.deviceModelManager.DeviceModel.Load(deviceModel.Name) - if ok { - cachedDeviceModel := value.(*v1alpha2.DeviceModel) - if isDeviceModelUpdated(cachedDeviceModel, deviceModel) { - dc.updateAllConfigMaps(deviceModel) - } - } - dc.deviceModelAdded(deviceModel) -} - -// updateAllConfigMaps is function to update configMaps which refer to an updated deviceModel -func (dc *DownstreamController) updateAllConfigMaps(deviceModel *v1alpha2.DeviceModel) { - //TODO: add logic to update all config maps, How to manage if a property is deleted but a device is referring that property. Need to come up with a design. +func (dc *DownstreamController) deviceModelUpdated(deviceModel *v1beta1.DeviceModel) { + // nothing to do when deviceModel updated, only add in map + dc.deviceModelManager.DeviceModel.Store(deviceModel.Name, deviceModel) } // deviceModelDeleted is function to process deleted deviceModel -func (dc *DownstreamController) deviceModelDeleted(deviceModel *v1alpha2.DeviceModel) { +func (dc *DownstreamController) deviceModelDeleted(deviceModel *v1beta1.DeviceModel) { // TODO: Need to use finalizer like method to delete all devices referring to this model. Need to come up with a design. dc.deviceModelManager.DeviceModel.Delete(deviceModel.Name) } @@ -128,7 +100,7 @@ func (dc *DownstreamController) syncDevice() { klog.Info("Stop syncDevice") return case e := <-dc.deviceManager.Events(): - device, ok := e.Object.(*v1alpha2.Device) + device, ok := e.Object.(*v1beta1.Device) if !ok { klog.Warningf("Object type: %T unsupported", e.Object) continue @@ -136,10 +108,10 @@ func (dc *DownstreamController) syncDevice() { switch e.Type { case watch.Added: dc.deviceAdded(device) - case watch.Deleted: - dc.deviceDeleted(device) case watch.Modified: dc.deviceUpdated(device) + case watch.Deleted: + dc.deviceDeleted(device) default: klog.Warningf("Device event type: %s unsupported", e.Type) } @@ -147,232 +119,14 @@ func (dc *DownstreamController) syncDevice() { } } -// addToConfigMap adds device in the configmap -func (dc *DownstreamController) addToConfigMap(device *v1alpha2.Device) { - configMap, ok := dc.configMapManager.ConfigMap.Load(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0]) - if !ok { - nodeConfigMap := &v1.ConfigMap{} - nodeConfigMap.Name = constants.DeviceProfileConfigPrefix + device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0] - nodeConfigMap.Namespace = device.Namespace - nodeConfigMap.Data = make(map[string]string) - // TODO: how to handle 2 device of multiple namespaces bind to same node ? - dc.addDeviceProfile(device, nodeConfigMap) - // store new config map - dc.configMapManager.ConfigMap.Store(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], nodeConfigMap) - - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Get(context.Background(), nodeConfigMap.Name, metav1.GetOptions{}); err != nil { - if apierrors.IsNotFound(err) { - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Create(context.Background(), nodeConfigMap, metav1.CreateOptions{}); err != nil { - klog.Errorf("Failed to create config map %v in namespace %v, error %v", nodeConfigMap, device.Namespace, err) - } - } - return - } - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Update(context.Background(), nodeConfigMap, metav1.UpdateOptions{}); err != nil { - klog.Errorf("Failed to update config map %v in namespace %v, error %v", nodeConfigMap, device.Namespace, err) - return - } - return - } - nodeConfigMap, ok := configMap.(*v1.ConfigMap) - if !ok { - klog.Error("Failed to assert to configmap") - return - } - dc.addDeviceProfile(device, nodeConfigMap) - // store new config map - dc.configMapManager.ConfigMap.Store(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], nodeConfigMap) - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Update(context.Background(), nodeConfigMap, metav1.UpdateOptions{}); err != nil { - klog.Errorf("Failed to update config map %v in namespace %v", nodeConfigMap, device.Namespace) - return - } -} - -// addDeviceProfile is function to add deviceProfile in configMap -func (dc *DownstreamController) addDeviceProfile(device *v1alpha2.Device, configMap *v1.ConfigMap) { - deviceProfile := &types.DeviceProfile{} - dp, ok := configMap.Data[constants.DeviceProfileJSON] - if !ok { - // create deviceProfileStruct - deviceProfile.DeviceInstances = make([]*types.DeviceInstance, 0) - deviceProfile.DeviceModels = make([]*types.DeviceModel, 0) - } else { - err := json.Unmarshal([]byte(dp), deviceProfile) - if err != nil { - klog.Errorf("Failed to Unmarshal deviceprofile: %v", deviceProfile) - return - } - } - - addDeviceInstanceAndProtocol(device, deviceProfile) - dm, ok := dc.deviceModelManager.DeviceModel.Load(device.Spec.DeviceModelRef.Name) - if !ok { - klog.Errorf("Failed to get device model %v", device.Spec.DeviceModelRef.Name) - return - } - deviceModel := dm.(*v1alpha2.DeviceModel) - // if model already exists no need to add model and visitors - checkModelExists := false - for _, dm := range deviceProfile.DeviceModels { - if dm.Name == deviceModel.Name { - checkModelExists = true - break - } - } - if !checkModelExists { - addDeviceModelAndVisitors(deviceModel, deviceProfile) - } - bytes, err := json.Marshal(deviceProfile) - if err != nil { - klog.Errorf("Failed to marshal deviceprofile: %v", deviceProfile) - return - } - configMap.Data[constants.DeviceProfileJSON] = string(bytes) -} - -// addDeviceModelAndVisitors adds deviceModels and deviceVisitors in configMap -func addDeviceModelAndVisitors(deviceModel *v1alpha2.DeviceModel, deviceProfile *types.DeviceProfile) { - model := &types.DeviceModel{} - model.Name = deviceModel.Name - model.Properties = make([]*types.Property, 0, len(deviceModel.Spec.Properties)) - for _, ppt := range deviceModel.Spec.Properties { - property := &types.Property{} - property.Name = ppt.Name - property.Description = ppt.Description - if ppt.Type.Int != nil { - property.AccessMode = string(ppt.Type.Int.AccessMode) - property.DataType = constants.DataTypeInt - property.DefaultValue = ppt.Type.Int.DefaultValue - property.Maximum = ppt.Type.Int.Maximum - property.Minimum = ppt.Type.Int.Minimum - property.Unit = ppt.Type.Int.Unit - } else if ppt.Type.String != nil { - property.AccessMode = string(ppt.Type.String.AccessMode) - property.DataType = constants.DataTypeString - property.DefaultValue = ppt.Type.String.DefaultValue - } else if ppt.Type.Double != nil { - property.AccessMode = string(ppt.Type.Double.AccessMode) - property.DataType = constants.DataTypeDouble - property.DefaultValue = ppt.Type.Double.DefaultValue - property.Maximum = ppt.Type.Double.Maximum - property.Minimum = ppt.Type.Double.Minimum - property.Unit = ppt.Type.Double.Unit - } else if ppt.Type.Float != nil { - property.AccessMode = string(ppt.Type.Float.AccessMode) - property.DataType = constants.DataTypeFloat - property.DefaultValue = ppt.Type.Float.DefaultValue - property.Maximum = ppt.Type.Float.Maximum - property.Minimum = ppt.Type.Float.Minimum - property.Unit = ppt.Type.Float.Unit - } else if ppt.Type.Boolean != nil { - property.AccessMode = string(ppt.Type.Boolean.AccessMode) - property.DataType = constants.DataTypeBoolean - property.DefaultValue = ppt.Type.Boolean.DefaultValue - } else if ppt.Type.Bytes != nil { - property.AccessMode = string(ppt.Type.Bytes.AccessMode) - property.DataType = constants.DataTypeBytes - } - model.Properties = append(model.Properties, property) - } - deviceProfile.DeviceModels = append(deviceProfile.DeviceModels, model) -} - -// add PropertyVisitors to DeviceInstance in configmap -func addPropertyVisitorsToDeviceInstance(device *v1alpha2.Device, deviceInstance *types.DeviceInstance) { - // clear old PropertyVisitors - deviceInstance.PropertyVisitors = make([]*types.PropertyVisitor, 0, len(device.Spec.PropertyVisitors)) - // add new PropertyVisitors - for _, pptv := range device.Spec.PropertyVisitors { - propertyVisitor := &types.PropertyVisitor{} - propertyVisitor.Name = pptv.PropertyName - propertyVisitor.PropertyName = pptv.PropertyName - propertyVisitor.ModelName = device.Spec.DeviceModelRef.Name - propertyVisitor.ReportCycle = pptv.ReportCycle - propertyVisitor.CollectCycle = pptv.CollectCycle - if pptv.Modbus != nil { - propertyVisitor.Protocol = constants.Modbus - propertyVisitor.VisitorConfig = pptv.Modbus - } else if pptv.OpcUA != nil { - propertyVisitor.Protocol = constants.OPCUA - propertyVisitor.VisitorConfig = pptv.OpcUA - } else if pptv.Bluetooth != nil { - propertyVisitor.Protocol = constants.Bluetooth - propertyVisitor.VisitorConfig = pptv.Bluetooth - } else if pptv.CustomizedProtocol != nil { - propertyVisitor.Protocol = constants.CustomizedProtocol - propertyVisitor.VisitorConfig = pptv.CustomizedProtocol - } - if pptv.CustomizedValues != nil { - propertyVisitor.CustomizedValues = pptv.CustomizedValues - } - deviceInstance.PropertyVisitors = append(deviceInstance.PropertyVisitors, propertyVisitor) - } -} - -// addDeviceInstanceAndProtocol adds deviceInstance and protocol in configMap -func addDeviceInstanceAndProtocol(device *v1alpha2.Device, deviceProfile *types.DeviceProfile) { - deviceInstance := &types.DeviceInstance{} - deviceProtocol := &types.Protocol{} - deviceInstance.ID = device.Name - deviceInstance.Name = device.Name - deviceInstance.Model = device.Spec.DeviceModelRef.Name - if device.Spec.Protocol.Common != nil { - deviceProtocol.ProtocolCommonConfig = device.Spec.Protocol.Common - } - var protocol string - if device.Spec.Protocol.OpcUA != nil { - protocol = constants.OPCUA + "-" + device.Name - deviceInstance.Protocol = protocol - deviceProtocol.Name = protocol - deviceProtocol.Protocol = constants.OPCUA - deviceProtocol.ProtocolConfig = device.Spec.Protocol.OpcUA - } else if device.Spec.Protocol.Modbus != nil { - protocol = constants.Modbus + "-" + device.Name - deviceInstance.Protocol = protocol - deviceProtocol.Name = protocol - deviceProtocol.Protocol = constants.Modbus - deviceProtocol.ProtocolConfig = device.Spec.Protocol.Modbus - } else if device.Spec.Protocol.Bluetooth != nil { - protocol = constants.Bluetooth + "-" + device.Name - deviceInstance.Protocol = protocol - deviceProtocol.Name = protocol - deviceProtocol.Protocol = constants.Bluetooth - deviceProtocol.ProtocolConfig = device.Spec.Protocol.Bluetooth - } else if device.Spec.Protocol.CustomizedProtocol != nil { - protocol = constants.CustomizedProtocol + "-" + device.Name - deviceInstance.Protocol = protocol - deviceProtocol.Name = protocol - deviceProtocol.Protocol = constants.CustomizedProtocol - deviceProtocol.ProtocolConfig = device.Spec.Protocol.CustomizedProtocol - } else { - klog.Warning("Device doesn't support valid protocol") - } - - deviceInstance.Twins = device.Status.Twins - - // add dataProperties and dataTopic - if len(device.Spec.Data.DataProperties) > 0 || len(device.Spec.Data.DataTopic) > 0 { - deviceInstance.Data = &v1alpha2.DeviceData{ - DataProperties: device.Spec.Data.DataProperties, - DataTopic: device.Spec.Data.DataTopic, - } - } - - addPropertyVisitorsToDeviceInstance(device, deviceInstance) - - deviceProfile.DeviceInstances = append(deviceProfile.DeviceInstances, deviceInstance) - deviceProfile.Protocols = append(deviceProfile.Protocols, deviceProtocol) -} - // deviceAdded creates a device, adds in deviceManagers map, send a message to edge node if node selector is present. -func (dc *DownstreamController) deviceAdded(device *v1alpha2.Device) { +func (dc *DownstreamController) deviceAdded(device *v1beta1.Device) { dc.deviceManager.Device.Store(device.Name, device) - if len(device.Spec.NodeSelector.NodeSelectorTerms) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values) != 0 { - dc.addToConfigMap(device) + if device.Spec.NodeName != "" { edgeDevice := createDevice(device) msg := model.NewMessage("") - resource, err := messagelayer.BuildResourceForDevice(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], "membership", "") + resource, err := messagelayer.BuildResourceForDevice(device.Spec.NodeName, "membership", "") if err != nil { klog.Warningf("Built message resource failed with error: %s", err) return @@ -397,7 +151,7 @@ func (dc *DownstreamController) deviceAdded(device *v1alpha2.Device) { } // createDevice creates a device from CRD -func createDevice(device *v1alpha2.Device) types.Device { +func createDevice(device *v1beta1.Device) types.Device { edgeDevice := types.Device{ // ID and name can be used as ID as we are using CRD and name(key in ETCD) will always be unique ID: device.Name, @@ -409,189 +163,21 @@ func createDevice(device *v1alpha2.Device) types.Device { edgeDevice.Description = description } - // TODO: optional is Always false, currently not present in CRD definition, need to add or remove from deviceTwin @ Edge - opt := false - optional := &opt - twin := make(map[string]*types.MsgTwin, len(device.Status.Twins)) - for i, dtwin := range device.Status.Twins { - expected := &types.TwinValue{} - expected.Value = &device.Status.Twins[i].Desired.Value - metadataType, ok := device.Status.Twins[i].Desired.Metadata["type"] - if !ok { - metadataType = "string" - } - timestamp := time.Now().UnixNano() / 1e6 - - metadata := &types.ValueMetadata{Timestamp: timestamp} - expected.Metadata = metadata - - // TODO: how to manage versioning ?? - cloudVersion, err := strconv.ParseInt(device.ResourceVersion, 10, 64) - if err != nil { - klog.Warningf("Failed to parse cloud version due to error %v", err) - } - twinVersion := &types.TwinVersion{CloudVersion: cloudVersion, EdgeVersion: 0} - msgTwin := &types.MsgTwin{ - Expected: expected, - Optional: optional, - Metadata: &types.TypeMetadata{Type: metadataType}, - ExpectedVersion: twinVersion, - } - twin[dtwin.PropertyName] = msgTwin - } - edgeDevice.Twin = twin return edgeDevice } -// isDeviceUpdated checks if device is actually updated -func isDeviceUpdated(oldTwin *v1alpha2.Device, newTwin *v1alpha2.Device) bool { - // does not care fields - oldTwin.ObjectMeta.ResourceVersion = newTwin.ObjectMeta.ResourceVersion - oldTwin.ObjectMeta.Generation = newTwin.ObjectMeta.Generation - // return true if ObjectMeta or Spec or Status changed, else false - return !reflect.DeepEqual(oldTwin.ObjectMeta, newTwin.ObjectMeta) || !reflect.DeepEqual(oldTwin.Spec, newTwin.Spec) || !reflect.DeepEqual(oldTwin.Status, newTwin.Status) -} - -// isNodeSelectorUpdated checks if nodeSelector is updated -func isNodeSelectorUpdated(oldTwin *v1.NodeSelector, newTwin *v1.NodeSelector) bool { - return !reflect.DeepEqual(oldTwin.NodeSelectorTerms, newTwin.NodeSelectorTerms) -} - -// isProtocolConfigUpdated checks if protocol is updated -func isProtocolConfigUpdated(oldTwin *v1alpha2.ProtocolConfig, newTwin *v1alpha2.ProtocolConfig) bool { - return !reflect.DeepEqual(oldTwin, newTwin) -} - -// isDeviceStatusUpdated checks if DeviceStatus is updated -func isDeviceStatusUpdated(oldTwin *v1alpha2.DeviceStatus, newTwin *v1alpha2.DeviceStatus) bool { - return !reflect.DeepEqual(oldTwin, newTwin) -} - -// isDeviceDataUpdated checks if DeviceData is updated -func isDeviceDataUpdated(oldData *v1alpha2.DeviceData, newData *v1alpha2.DeviceData) bool { - return !reflect.DeepEqual(oldData, newData) -} - -// isDevicePropertyVisitorsUpdated checks if DevicePropertyVisitors is updated -func isDevicePropertyVisitorsUpdated(oldPropertyVisitors *[]v1alpha2.DevicePropertyVisitor, newPropertyVisitors *[]v1alpha2.DevicePropertyVisitor) bool { - return !reflect.DeepEqual(oldPropertyVisitors, newPropertyVisitors) -} - -// updateConfigMap updates the protocol, twins and data in the deviceProfile in configmap -func (dc *DownstreamController) updateConfigMap(device *v1alpha2.Device) { - if len(device.Spec.NodeSelector.NodeSelectorTerms) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values) != 0 { - configMap, ok := dc.configMapManager.ConfigMap.Load(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0]) - if !ok { - klog.Error("Failed to load configmap") - return - } - - nodeConfigMap, ok := configMap.(*v1.ConfigMap) - if !ok { - klog.Error("Failed to assert to configmap") - return - } - dp, ok := nodeConfigMap.Data[constants.DeviceProfileJSON] - if !ok || dp == "{}" { - // This case should never be hit as we delete empty configmaps - klog.Error("Failed to get deviceProfile from configmap data or deviceProfile is empty") - return - } - - deviceProfile := &types.DeviceProfile{} - if err := json.Unmarshal([]byte(dp), deviceProfile); err != nil { - klog.Errorf("Failed to unmarshal due to error: %v", err) - return - } - var oldProtocol string - for _, devInst := range deviceProfile.DeviceInstances { - if device.Name == devInst.Name { - oldProtocol = devInst.Protocol - break - } - } - - // delete the old protocol - for i, ptcl := range deviceProfile.Protocols { - if ptcl.Name == oldProtocol { - deviceProfile.Protocols = append(deviceProfile.Protocols[:i], deviceProfile.Protocols[i+1:]...) - break - } - } - - // add new protocol - deviceProtocol := &types.Protocol{} - if device.Spec.Protocol.OpcUA != nil { - deviceProtocol = buildDeviceProtocol(constants.OPCUA, device.Name, device.Spec.Protocol.OpcUA) - } else if device.Spec.Protocol.Modbus != nil { - deviceProtocol = buildDeviceProtocol(constants.Modbus, device.Name, device.Spec.Protocol.Modbus) - } else if device.Spec.Protocol.Bluetooth != nil { - deviceProtocol = buildDeviceProtocol(constants.Bluetooth, device.Name, device.Spec.Protocol.Bluetooth) - } else if device.Spec.Protocol.CustomizedProtocol != nil { - deviceProtocol = buildDeviceProtocol(constants.CustomizedProtocol, device.Name, device.Spec.Protocol.CustomizedProtocol) - } else { - klog.Warning("Unsupported device protocol") - } - // add protocol common - deviceProtocol.ProtocolCommonConfig = device.Spec.Protocol.Common - - // update the propertyVisitors, twins, data and protocol in deviceInstance - for _, devInst := range deviceProfile.DeviceInstances { - if device.Name == devInst.Name { - // update property visitors - addPropertyVisitorsToDeviceInstance(device, devInst) - // update twins - devInst.Twins = device.Status.Twins - - // update data and data topic - if len(device.Spec.Data.DataProperties) > 0 || len(device.Spec.Data.DataTopic) > 0 { - devInst.Data = &v1alpha2.DeviceData{ - DataProperties: device.Spec.Data.DataProperties, - DataTopic: device.Spec.Data.DataTopic, - } - } - // update protocol - devInst.Protocol = deviceProtocol.Name - break - } - } - deviceProfile.Protocols = append(deviceProfile.Protocols, deviceProtocol) - - bytes, err := json.Marshal(deviceProfile) - if err != nil { - klog.Errorf("Failed to marshal deviceprofile: %v, error: %v", deviceProfile, err) - return - } - nodeConfigMap.Data[constants.DeviceProfileJSON] = string(bytes) - // store new config map - dc.configMapManager.ConfigMap.Store(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], nodeConfigMap) - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Update(context.Background(), nodeConfigMap, metav1.UpdateOptions{}); err != nil { - klog.Errorf("Failed to update config map %v in namespace %v, error: %v", nodeConfigMap, device.Namespace, err) - return - } - } -} - -func buildDeviceProtocol(protocol, deviceName string, ProtocolConfig interface{}) *types.Protocol { - var deviceProtocol types.Protocol - deviceProtocol.Name = protocol + "-" + deviceName - deviceProtocol.Protocol = protocol - deviceProtocol.ProtocolConfig = ProtocolConfig - return &deviceProtocol -} - // deviceUpdated updates the map, check if device is actually updated. -// If nodeSelector is updated, call add device for newNode, deleteDevice for old Node. -// If twin is updated, send twin update message to edge -func (dc *DownstreamController) deviceUpdated(device *v1alpha2.Device) { +// If NodeName is updated, call add device for newNode, deleteDevice for old Node. +// If Spec is updated, send update message to edge +func (dc *DownstreamController) deviceUpdated(device *v1beta1.Device) { value, ok := dc.deviceManager.Device.Load(device.Name) dc.deviceManager.Device.Store(device.Name, device) if ok { - cachedDevice := value.(*v1alpha2.Device) + cachedDevice := value.(*v1beta1.Device) if isDeviceUpdated(cachedDevice, device) { - // if node selector updated delete from old node and create in new node - if isNodeSelectorUpdated(cachedDevice.Spec.NodeSelector, device.Spec.NodeSelector) { - deletedDevice := &v1alpha2.Device{ObjectMeta: cachedDevice.ObjectMeta, + // if NodeName changed, delete from old node and create in new node + if cachedDevice.Spec.NodeName != device.Spec.NodeName { + deletedDevice := &v1beta1.Device{ObjectMeta: cachedDevice.ObjectMeta, Spec: cachedDevice.Spec, Status: cachedDevice.Status, TypeMeta: device.TypeMeta, @@ -599,43 +185,8 @@ func (dc *DownstreamController) deviceUpdated(device *v1alpha2.Device) { dc.deviceDeleted(deletedDevice) dc.deviceAdded(device) } else { - // update config map if spec, data or twins changed - if isProtocolConfigUpdated(&cachedDevice.Spec.Protocol, &device.Spec.Protocol) || - isDeviceStatusUpdated(&cachedDevice.Status, &device.Status) || - isDeviceDataUpdated(&cachedDevice.Spec.Data, &device.Spec.Data) || - isDevicePropertyVisitorsUpdated(&cachedDevice.Spec.PropertyVisitors, &device.Spec.PropertyVisitors) { - dc.updateConfigMap(device) - } - // update twin properties - if isDeviceStatusUpdated(&cachedDevice.Status, &device.Status) { - // TODO: add an else if condition to check if DeviceModelReference has changed, if yes whether deviceModelReference exists - twin := make(map[string]*types.MsgTwin) - addUpdatedTwins(device.Status.Twins, twin, device.ResourceVersion) - addDeletedTwins(cachedDevice.Status.Twins, device.Status.Twins, twin, device.ResourceVersion) - msg := model.NewMessage("") - - resource, err := messagelayer.BuildResourceForDevice(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], "device/"+device.Name+"/twin/cloud_updated", "") - if err != nil { - klog.Warningf("Built message resource failed with error: %s", err) - return - } - msg.BuildRouter(modules.DeviceControllerModuleName, constants.GroupTwin, resource, model.UpdateOperation) - content := types.DeviceTwinUpdate{Twin: twin} - content.EventID = uuid.New().String() - content.Timestamp = time.Now().UnixNano() / 1e6 - msg.Content = content - - err = dc.messageLayer.Send(*msg) - if err != nil { - klog.Errorf("Failed to send deviceTwin message %v due to error %v", msg, err) - } - } - // distribute device model - if isDeviceStatusUpdated(&cachedDevice.Status, &device.Status) || - isDeviceDataUpdated(&cachedDevice.Spec.Data, &device.Spec.Data) { - dc.sendDeviceModelMsg(device, model.UpdateOperation) - dc.sendDeviceMsg(device, model.UpdateOperation) - } + dc.sendDeviceModelMsg(device, model.UpdateOperation) + dc.sendDeviceMsg(device, model.UpdateOperation) } } } else { @@ -644,204 +195,56 @@ func (dc *DownstreamController) deviceUpdated(device *v1alpha2.Device) { } } -// addDeletedTwins add deleted twins in the message -func addDeletedTwins(oldTwin []v1alpha2.Twin, newTwin []v1alpha2.Twin, twin map[string]*types.MsgTwin, version string) { - opt := false - optional := &opt - for i, dtwin := range oldTwin { - if !ifTwinPresent(dtwin, newTwin) { - expected := &types.TwinValue{} - expected.Value = &oldTwin[i].Desired.Value - timestamp := time.Now().UnixNano() / 1e6 - - metadata := &types.ValueMetadata{Timestamp: timestamp} - expected.Metadata = metadata - - // TODO: how to manage versioning ?? - cloudVersion, err := strconv.ParseInt(version, 10, 64) - if err != nil { - klog.Warningf("Failed to parse cloud version due to error %v", err) - } - twinVersion := &types.TwinVersion{CloudVersion: cloudVersion, EdgeVersion: 0} - msgTwin := &types.MsgTwin{ - Expected: expected, - Optional: optional, - Metadata: &types.TypeMetadata{Type: "deleted"}, - ExpectedVersion: twinVersion, - } - twin[dtwin.PropertyName] = msgTwin - } - } +// isDeviceUpdated checks if device is actually updated +func isDeviceUpdated(oldTwin *v1beta1.Device, newTwin *v1beta1.Device) bool { + // does not care fields + oldTwin.ObjectMeta.ResourceVersion = newTwin.ObjectMeta.ResourceVersion + oldTwin.ObjectMeta.Generation = newTwin.ObjectMeta.Generation + // return true if ObjectMeta or Spec or Status changed, else false + return !reflect.DeepEqual(oldTwin.ObjectMeta, newTwin.ObjectMeta) || !reflect.DeepEqual(oldTwin.Spec, newTwin.Spec) } -// ifTwinPresent checks if twin is present in the array of twins -func ifTwinPresent(twin v1alpha2.Twin, newTwins []v1alpha2.Twin) bool { - for _, dtwin := range newTwins { - if twin.PropertyName == dtwin.PropertyName { - return true - } - } - return false -} +// deviceDeleted send a deleted message to the edgeNode and deletes the device from the deviceManager.Device map +func (dc *DownstreamController) deviceDeleted(device *v1beta1.Device) { + dc.deviceManager.Device.Delete(device.Name) -// addUpdatedTwins is function of add updated twins to send to edge -func addUpdatedTwins(newTwin []v1alpha2.Twin, twin map[string]*types.MsgTwin, version string) { - opt := false - optional := &opt - for i, dtwin := range newTwin { - expected := &types.TwinValue{} - expected.Value = &newTwin[i].Desired.Value - metadataType, ok := newTwin[i].Desired.Metadata["type"] - if !ok { - metadataType = "string" - } - timestamp := time.Now().UnixNano() / 1e6 + if device.Spec.NodeName != "" { + edgeDevice := createDevice(device) + msg := model.NewMessage("") - metadata := &types.ValueMetadata{Timestamp: timestamp} - expected.Metadata = metadata + resource, err := messagelayer.BuildResourceForDevice(device.Spec.NodeName, "membership", "") + msg.BuildRouter(modules.DeviceControllerModuleName, constants.GroupTwin, resource, model.UpdateOperation) - // TODO: how to manage versioning ?? - cloudVersion, err := strconv.ParseInt(version, 10, 64) + content := types.MembershipUpdate{RemoveDevices: []types.Device{ + edgeDevice, + }} + content.EventID = uuid.New().String() + content.Timestamp = time.Now().UnixNano() / 1e6 + msg.Content = content if err != nil { - klog.Warningf("Failed to parse cloud version due to error %v", err) - } - twinVersion := &types.TwinVersion{CloudVersion: cloudVersion, EdgeVersion: 0} - msgTwin := &types.MsgTwin{ - Expected: expected, - Optional: optional, - Metadata: &types.TypeMetadata{Type: metadataType}, - ExpectedVersion: twinVersion, - } - twin[dtwin.PropertyName] = msgTwin - } -} - -// deleteFromConfigMap deletes a device from configMap -func (dc *DownstreamController) deleteFromConfigMap(device *v1alpha2.Device) { - if len(device.Spec.NodeSelector.NodeSelectorTerms) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values) != 0 { - configMap, ok := dc.configMapManager.ConfigMap.Load(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0]) - if !ok { - return - } - nodeConfigMap, ok := configMap.(*v1.ConfigMap) - if !ok { - klog.Error("Failed to assert to configmap") - return - } - - dc.deleteFromDeviceProfile(device, nodeConfigMap) - - // There are two cases we can delete configMap: - // 1. no device bound to it, as Data[DeviceProfileJSON] is "{}" - // 2. device instance created alone then removed, as Data[DeviceProfileJSON] is "" - if nodeConfigMap.Data[constants.DeviceProfileJSON] == "{}" || nodeConfigMap.Data[constants.DeviceProfileJSON] == "" { - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Get(context.Background(), nodeConfigMap.Name, metav1.GetOptions{}); err == nil { - if err = dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Delete(context.Background(), nodeConfigMap.Name, metav1.DeleteOptions{}); err != nil { - klog.Errorf("failed to delete config map %s in namespace %s", nodeConfigMap.Name, device.Namespace) - return - } - } - // remove from cache - dc.configMapManager.ConfigMap.Delete(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0]) - return - } - - // store new config map - dc.configMapManager.ConfigMap.Store(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], nodeConfigMap) - if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Update(context.Background(), nodeConfigMap, metav1.UpdateOptions{}); err != nil { - klog.Errorf("Failed to update config map %v in namespace %v", nodeConfigMap, device.Namespace) - return - } - } -} - -// deleteFromDeviceProfile deletes a device from deviceProfile -func (dc *DownstreamController) deleteFromDeviceProfile(device *v1alpha2.Device, configMap *v1.ConfigMap) { - dp, ok := configMap.Data[constants.DeviceProfileJSON] - if !ok { - klog.Error("Device profile does not exist in the configmap") - return - } - - deviceProfile := &types.DeviceProfile{} - err := json.Unmarshal([]byte(dp), deviceProfile) - if err != nil { - klog.Errorf("Failed to Unmarshal deviceprofile: %v", deviceProfile) - return - } - deleteDeviceInstanceAndProtocol(device, deviceProfile) - - dm, ok := dc.deviceModelManager.DeviceModel.Load(device.Spec.DeviceModelRef.Name) - if !ok { - klog.Errorf("Failed to get device model %v", device.Spec.DeviceModelRef.Name) - return - } - deviceModel := dm.(*v1alpha2.DeviceModel) - // if model referenced by other devices, no need to delete the model - checkModelReferenced := false - for _, dvc := range deviceProfile.DeviceInstances { - if dvc.Model == deviceModel.Name { - checkModelReferenced = true - break - } - } - if !checkModelReferenced { - deleteDeviceModelAndVisitors(deviceModel, deviceProfile) - } - bytes, err := json.Marshal(deviceProfile) - if err != nil { - klog.Errorf("Failed to marshal deviceprofile: %v", deviceProfile) - return - } - configMap.Data[constants.DeviceProfileJSON] = string(bytes) -} - -// deleteDeviceInstanceAndProtocol deletes deviceInstance and protocol from deviceProfile -func deleteDeviceInstanceAndProtocol(device *v1alpha2.Device, deviceProfile *types.DeviceProfile) { - var protocol string - for i, devInst := range deviceProfile.DeviceInstances { - if device.Name == devInst.Name { - protocol = devInst.Protocol - deviceProfile.DeviceInstances[i] = deviceProfile.DeviceInstances[len(deviceProfile.DeviceInstances)-1] - deviceProfile.DeviceInstances[len(deviceProfile.DeviceInstances)-1] = nil - deviceProfile.DeviceInstances = deviceProfile.DeviceInstances[:len(deviceProfile.DeviceInstances)-1] - break - } - } - - for i, ptcl := range deviceProfile.Protocols { - if ptcl.Name == protocol { - deviceProfile.Protocols[i] = deviceProfile.Protocols[len(deviceProfile.Protocols)-1] - deviceProfile.Protocols[len(deviceProfile.Protocols)-1] = nil - deviceProfile.Protocols = deviceProfile.Protocols[:len(deviceProfile.Protocols)-1] + klog.Warningf("Built message resource failed with error: %s", err) return } - } -} - -// deleteDeviceModelAndVisitors deletes deviceModel and visitor from deviceProfile -func deleteDeviceModelAndVisitors(deviceModel *v1alpha2.DeviceModel, deviceProfile *types.DeviceProfile) { - for i, dm := range deviceProfile.DeviceModels { - if dm.Name == deviceModel.Name { - deviceProfile.DeviceModels[i] = deviceProfile.DeviceModels[len(deviceProfile.DeviceModels)-1] - deviceProfile.DeviceModels[len(deviceProfile.DeviceModels)-1] = nil - deviceProfile.DeviceModels = deviceProfile.DeviceModels[:len(deviceProfile.DeviceModels)-1] - break + err = dc.messageLayer.Send(*msg) + if err != nil { + klog.Errorf("Failed to send device addition message %v due to error %v", msg, err) } + dc.sendDeviceModelMsg(device, model.DeleteOperation) + dc.sendDeviceMsg(device, model.DeleteOperation) } } -func (dc *DownstreamController) sendDeviceMsg(device *v1alpha2.Device, operation string) { +func (dc *DownstreamController) sendDeviceMsg(device *v1beta1.Device, operation string) { device.SetGroupVersionKind(schema.GroupVersionKind{ - Group: v1alpha2.GroupName, - Version: v1alpha2.Version, + Group: v1beta1.GroupName, + Version: v1beta1.Version, Kind: constants.KindTypeDevice, }) modelMsg := model.NewMessage(""). SetResourceVersion(device.ResourceVersion). FillBody(device) modelResource, err := messagelayer.BuildResource( - device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], + device.Spec.NodeName, device.Namespace, constants.ResourceTypeDevice, device.Name) @@ -868,7 +271,7 @@ func (dc *DownstreamController) sendDeviceMsg(device *v1alpha2.Device, operation } } -func (dc *DownstreamController) sendDeviceModelMsg(device *v1alpha2.Device, operation string) { +func (dc *DownstreamController) sendDeviceModelMsg(device *v1beta1.Device, operation string) { // send operate msg for device model // now it is depended on device, maybe move this code to syncDeviceModel's method if device == nil || device.Spec.DeviceModelRef == nil { @@ -880,22 +283,22 @@ func (dc *DownstreamController) sendDeviceModelMsg(device *v1alpha2.Device, oper return } - deviceModel, ok := edgeDeviceModel.(*v1alpha2.DeviceModel) + deviceModel, ok := edgeDeviceModel.(*v1beta1.DeviceModel) if !ok { - klog.Warningf("edgeDeviceModel is not *v1alpha2.DeviceModel for device: %s, operation: %s", device.Name, operation) + klog.Warningf("edgeDeviceModel is not *v1beta1.DeviceModel for device: %s, operation: %s", device.Name, operation) return } deviceModel.SetGroupVersionKind(schema.GroupVersionKind{ - Group: v1alpha2.GroupName, - Version: v1alpha2.Version, + Group: v1beta1.GroupName, + Version: v1beta1.Version, Kind: constants.KindTypeDeviceModel, }) modelMsg := model.NewMessage(""). SetResourceVersion(deviceModel.ResourceVersion). FillBody(deviceModel) modelResource, err := messagelayer.BuildResource( - device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], + device.Spec.NodeName, deviceModel.Namespace, constants.ResourceTypeDeviceModel, deviceModel.Name) @@ -922,36 +325,6 @@ func (dc *DownstreamController) sendDeviceModelMsg(device *v1alpha2.Device, oper } } -// deviceDeleted send a deleted message to the edgeNode and deletes the device from the deviceManager.Device map -func (dc *DownstreamController) deviceDeleted(device *v1alpha2.Device) { - dc.deviceManager.Device.Delete(device.Name) - dc.deleteFromConfigMap(device) - edgeDevice := createDevice(device) - msg := model.NewMessage("") - - if len(device.Spec.NodeSelector.NodeSelectorTerms) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values) != 0 { - resource, err := messagelayer.BuildResourceForDevice(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], "membership", "") - msg.BuildRouter(modules.DeviceControllerModuleName, constants.GroupTwin, resource, model.UpdateOperation) - - content := types.MembershipUpdate{RemoveDevices: []types.Device{ - edgeDevice, - }} - content.EventID = uuid.New().String() - content.Timestamp = time.Now().UnixNano() / 1e6 - msg.Content = content - if err != nil { - klog.Warningf("Built message resource failed with error: %s", err) - return - } - err = dc.messageLayer.Send(*msg) - if err != nil { - klog.Errorf("Failed to send device addition message %v due to error %v", msg, err) - } - dc.sendDeviceModelMsg(device, model.DeleteOperation) - dc.sendDeviceMsg(device, model.DeleteOperation) - } -} - // Start DownstreamController func (dc *DownstreamController) Start() error { klog.Info("Start downstream devicecontroller") @@ -968,13 +341,13 @@ func (dc *DownstreamController) Start() error { // NewDownstreamController create a DownstreamController from config func NewDownstreamController(crdInformerFactory crdinformers.SharedInformerFactory) (*DownstreamController, error) { - deviceManager, err := manager.NewDeviceManager(crdInformerFactory.Devices().V1alpha2().Devices().Informer()) + deviceManager, err := manager.NewDeviceManager(crdInformerFactory.Devices().V1beta1().Devices().Informer()) if err != nil { klog.Warningf("Create device manager failed with error: %s", err) return nil, err } - deviceModelManager, err := manager.NewDeviceModelManager(crdInformerFactory.Devices().V1alpha2().DeviceModels().Informer()) + deviceModelManager, err := manager.NewDeviceModelManager(crdInformerFactory.Devices().V1beta1().DeviceModels().Informer()) if err != nil { klog.Warningf("Create device manager failed with error: %s", err) return nil, err @@ -985,7 +358,6 @@ func NewDownstreamController(crdInformerFactory crdinformers.SharedInformerFacto deviceManager: deviceManager, deviceModelManager: deviceModelManager, messageLayer: messagelayer.DeviceControllerMessageLayer(), - configMapManager: manager.NewConfigMapManager(), } return dc, nil } diff --git a/cloud/pkg/devicecontroller/controller/upstream.go b/cloud/pkg/devicecontroller/controller/upstream.go index 9c188f4f1..566a393d4 100644 --- a/cloud/pkg/devicecontroller/controller/upstream.go +++ b/cloud/pkg/devicecontroller/controller/upstream.go @@ -32,13 +32,13 @@ import ( "github.com/kubeedge/kubeedge/cloud/pkg/devicecontroller/constants" "github.com/kubeedge/kubeedge/cloud/pkg/devicecontroller/types" commonconst "github.com/kubeedge/kubeedge/common/constants" - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" + "github.com/kubeedge/kubeedge/pkg/apis/devices/v1beta1" crdClientset "github.com/kubeedge/kubeedge/pkg/client/clientset/versioned" ) // DeviceStatus is structure to patch device status type DeviceStatus struct { - Status v1alpha2.DeviceStatus `json:"status"` + Status v1beta1.DeviceStatus `json:"status"` } const ( @@ -128,7 +128,7 @@ func (uc *UpstreamController) updateDeviceStatus() { klog.Warningf("Device %s does not exist in downstream controller", deviceID) continue } - cacheDevice, ok := device.(*v1alpha2.Device) + cacheDevice, ok := device.(*v1beta1.Device) if !ok { klog.Warning("Failed to assert to CacheDevice type") continue @@ -137,7 +137,7 @@ func (uc *UpstreamController) updateDeviceStatus() { for twinName, twin := range msgTwin.Twin { for i, cacheTwin := range deviceStatus.Status.Twins { if twinName == cacheTwin.PropertyName && twin.Actual != nil && twin.Actual.Value != nil { - reported := v1alpha2.TwinProperty{} + reported := v1beta1.TwinProperty{} reported.Value = *twin.Actual.Value reported.Metadata = make(map[string]string) if twin.Actual.Metadata != nil { @@ -161,7 +161,7 @@ func (uc *UpstreamController) updateDeviceStatus() { klog.Errorf("Failed to marshal device status %v", deviceStatus) continue } - err = uc.crdClient.DevicesV1alpha2().RESTClient().Patch(MergePatchType).Namespace(cacheDevice.Namespace).Resource(ResourceTypeDevices).Name(deviceID).Body(body).Do(context.Background()).Error() + err = uc.crdClient.DevicesV1beta1().RESTClient().Patch(MergePatchType).Namespace(cacheDevice.Namespace).Resource(ResourceTypeDevices).Name(deviceID).Body(body).Do(context.Background()).Error() if err != nil { klog.Errorf("Failed to patch device status %v of device %v in namespace %v, err: %v", deviceStatus, deviceID, cacheDevice.Namespace, err) continue diff --git a/cloud/pkg/devicecontroller/manager/configmap.go b/cloud/pkg/devicecontroller/manager/configmap.go deleted file mode 100644 index ac839b88e..000000000 --- a/cloud/pkg/devicecontroller/manager/configmap.go +++ /dev/null @@ -1,16 +0,0 @@ -package manager - -import ( - "sync" -) - -// ConfigMapManager is a manager for configmap of deviceProfile -type ConfigMapManager struct { - // ConfigMap, key is nodeID, value is configmap - ConfigMap sync.Map -} - -// NewConfigMapManager is function to return new ConfigMapManager -func NewConfigMapManager() *ConfigMapManager { - return &ConfigMapManager{} -} diff --git a/cloud/pkg/devicecontroller/manager/device.go b/cloud/pkg/devicecontroller/manager/device.go index cd26d0386..9f004e174 100644 --- a/cloud/pkg/devicecontroller/manager/device.go +++ b/cloud/pkg/devicecontroller/manager/device.go @@ -14,7 +14,7 @@ type DeviceManager struct { // events from watch kubernetes api server events chan watch.Event - // Device, key is device.Name, value is *v1alpha2.Device{} + // Device, key is device.Name, value is *v1beta1.Device{} Device sync.Map } diff --git a/cloud/pkg/devicecontroller/types/deviceprofile.go b/cloud/pkg/devicecontroller/types/deviceprofile.go deleted file mode 100644 index b786918be..000000000 --- a/cloud/pkg/devicecontroller/types/deviceprofile.go +++ /dev/null @@ -1,100 +0,0 @@ -package types - -import ( - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" -) - -// DeviceProfile is structure to store in configMap. These types would be consumed by mappers to marshal / unmarshal the device profile json -type DeviceProfile struct { - // DeviceInstances is used to store list of all devices. - DeviceInstances []*DeviceInstance `json:"deviceInstances,omitempty"` - // DeviceModels is used to store list of all DeviceModels referenced by DeviceInstances - DeviceModels []*DeviceModel `json:"deviceModels,omitempty"` - // Protocols is list of all protocols used by DeviceInstances - Protocols []*Protocol `json:"protocols,omitempty"` -} - -// DeviceInstance is structure to store device in deviceProfile.json in configmap -type DeviceInstance struct { - // ID is deviceInstance ID - ID string `json:"id,omitempty"` - // Name is deviceInstance name - Name string `json:"name,omitempty"` - // Protocol is deviceInstance protocol name. It is generated by deviceController - Protocol string `json:"protocol,omitempty"` - // Model is deviceInstance model name - Model string `json:"model,omitempty"` - // A list of device twins containing desired/reported desired/reported values of twin properties. - // Optional: A passive device won't have twin properties and this list could be empty. - // +optional - Twins []v1alpha2.Twin `json:"twins,omitempty"` - // Data section describe a list of time-series properties which should be processed - // on edge node. - // +optional - Data *v1alpha2.DeviceData `json:"data,omitempty"` - // PropertyVisitors is list of all PropertyVisitors in DeviceModels - PropertyVisitors []*PropertyVisitor `json:"propertyVisitors,omitempty"` -} - -// DeviceModel is structure to store deviceModel in deviceProfile.json in configmap -type DeviceModel struct { - // Name is DeviceModel name - Name string `json:"name,omitempty"` - // Description is DeviceModel description - Description string `json:"description,omitempty"` - // Properties is list of DeviceModel properties - Properties []*Property `json:"properties,omitempty"` -} - -// Property is structure to store deviceModel property -type Property struct { - // Name is Property name - Name string `json:"name,omitempty"` - // DataType is property dataType - DataType string `json:"dataType,omitempty"` - // Description is property description - Description string `json:"description,omitempty"` - // AccessMode is property accessMode - AccessMode string `json:"accessMode,omitempty"` - // DefaultValue is property defaultValue - DefaultValue interface{} `json:"defaultValue,omitempty"` - // Minimum is property minimum value in case of int, double and float - Minimum interface{} `json:"minimum,omitempty"` - // Maximum is property maximum value in case of int, double and float - Maximum interface{} `json:"maximum,omitempty"` - // Unit is unit of measurement - Unit string `json:"unit,omitempty"` -} - -// Protocol is structure to store protocol in deviceProfile.json in configmap -type Protocol struct { - // Name is protocol name - Name string `json:"name,omitempty"` - // Protocol is protocol name defined in deviceInstance. It is generated by deviceController - Protocol string `json:"protocol,omitempty"` - // ProtocolConfig is protocol config - ProtocolConfig interface{} `json:"protocolConfig"` - // ProtocolCommonConfig is common part of protocol config - ProtocolCommonConfig interface{} `json:"protocolCommonConfig"` -} - -// PropertyVisitor is structure to store propertyVisitor in deviceProfile.json in configmap -type PropertyVisitor struct { - // Name is propertyVisitor name - Name string `json:"name,omitempty"` - // PropertyName is name of property it is mapped to - PropertyName string `json:"propertyName,omitempty"` - // ModelName is deviceModel name - ModelName string `json:"modelName,omitempty"` - // Protocol is protocol of propertyVisitor - Protocol string `json:"protocol,omitempty"` - // Define how frequent mapper will report the value. - ReportCycle int64 `json:"reportCycle,omitempty"` - // Define how frequent mapper will collect from device. - CollectCycle int64 `json:"collectCycle,omitempty"` - // Customized values for visitor of provided protocols - // +optional - CustomizedValues interface{} `json:"customizedValues,omitempty"` - // VisitorConfig is property visitor configuration - VisitorConfig interface{} `json:"visitorConfig,omitempty"` -} diff --git a/cloud/test/integration/crds/validation_test.go b/cloud/test/integration/crds/validation_test.go deleted file mode 100644 index e51facdb3..000000000 --- a/cloud/test/integration/crds/validation_test.go +++ /dev/null @@ -1,343 +0,0 @@ -/* -Copyright 2019 The KubeEdge Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package crds - -import ( - "context" - "os" - "testing" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kubeedge/kubeedge/cloud/pkg/common/client" - "github.com/kubeedge/kubeedge/cloud/test/integration/fixtures" - cloudcoreConfig "github.com/kubeedge/kubeedge/pkg/apis/componentconfig/cloudcore/v1alpha1" - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" - crdClientset "github.com/kubeedge/kubeedge/pkg/client/clientset/versioned" -) - -func buildCrdClient(t *testing.T) crdClientset.Interface { - kubeConfigPath := os.Getenv("KUBE_CONFIG") - kubeAPIServerURL := os.Getenv("KUBE_APISERVER_URL") - - client.InitKubeEdgeClient(&cloudcoreConfig.KubeAPIConfig{KubeConfig: kubeConfigPath, Master: kubeAPIServerURL}) - - return client.GetCRDClient() -} - -func TestValidDeviceModel(t *testing.T) { - testNamespace := os.Getenv("TESTNS") - tests := map[string]struct { - deviceModelFn func() *v1alpha2.DeviceModel - }{ - "valid bluetooth device model": { - deviceModelFn: func() *v1alpha2.DeviceModel { - deviceModel := fixtures.NewDeviceModelBluetooth("bluetooth-device-model", testNamespace) - return deviceModel - }, - }, - "valid modbus rtu device model": { - deviceModelFn: func() *v1alpha2.DeviceModel { - deviceModel := fixtures.NewDeviceModelModbus("modbus-device-model", testNamespace) - return deviceModel - }, - }, - "valid opc ua device model": { - deviceModelFn: func() *v1alpha2.DeviceModel { - deviceModel := fixtures.NewDeviceModelOpcUA("opcua-device-model", testNamespace) - return deviceModel - }, - }, - "valid customized protocol device model": { - deviceModelFn: func() *v1alpha2.DeviceModel { - deviceModel := fixtures.NewDeviceModelCustomized("customized-device-model", testNamespace) - return deviceModel - }, - }, - } - - crdClient := buildCrdClient(t) - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - deviceModel := tc.deviceModelFn() - _, err := crdClient.DevicesV1alpha2().DeviceModels(deviceModel.Namespace).Create(context.TODO(), deviceModel, v1.CreateOptions{}) - if err != nil { - t.Fatalf("%s: expected nil err , got %v", name, err) - } - }) - } -} - -func TestInvalidDeviceModel(t *testing.T) { - testNamespace := os.Getenv("TESTNS") - tests := map[string]struct { - deviceModelFn func() *v1alpha2.DeviceModel - }{ - "device model with property no name": { - deviceModelFn: func() *v1alpha2.DeviceModel { - deviceModel := fixtures.DeviceModelWithPropertyNoName("device-model-property-no-name", testNamespace) - return deviceModel - }, - }, - - "device model with property bad access mode": { - deviceModelFn: func() *v1alpha2.DeviceModel { - deviceModel := fixtures.DeviceModelWithPropertyBadAccessMode("model-property-bad-access-mode", testNamespace) - return deviceModel - }, - }, - } - - crdClient := buildCrdClient(t) - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - deviceModel := tc.deviceModelFn() - _, err := crdClient.DevicesV1alpha2().DeviceModels(deviceModel.Namespace).Create(context.TODO(), deviceModel, v1.CreateOptions{}) - if err == nil { - t.Fatalf("%s: expected error", name) - } - }) - } -} - -func TestValidDevice(t *testing.T) { - testNamespace := os.Getenv("TESTNS") - tests := map[string]struct { - deviceInstanceFn func() v1alpha2.Device - }{ - "valid device with modbus rtu protocol": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTU("device-modbus-rtu", testNamespace) - return deviceInstance - }, - }, - "valid device with modbus tcp protocol": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusTCP("device-modbus-tcp", testNamespace) - return deviceInstance - }, - }, - "valid device with opc ua protocol": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceOpcUA("device-opcua", testNamespace) - return deviceInstance - }, - }, - "valid device with customized protocol": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceCustomized("device-customized", testNamespace) - return deviceInstance - }, - }, - } - - crdClient := buildCrdClient(t) - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - device := tc.deviceInstanceFn() - _, err := crdClient.DevicesV1alpha2().Devices(device.Namespace).Create(context.TODO(), &device, v1.CreateOptions{}) - if err != nil { - t.Fatalf("%s expected nil err , got %v", name, err) - } - }) - } -} - -func TestInvalidDevice(t *testing.T) { - testNamespace := os.Getenv("TESTNS") - tests := map[string]struct { - deviceInstanceFn func() v1alpha2.Device - }{ - "device modbus rtu no baud rate": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUNoBaudRate("device-modbus-rtu-no-baud-rate", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu bad baud rate": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUBadBaudRate("device-modbus-rtu-bad-baud-rate", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu no data bits": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUNoDataBits("device-modbus-rtu-no-data-bits", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu bad data bits": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUBadDataBits("device-modbus-rtu-bad-data-bits", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu no parity": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUNoParity("device-modbus-rtu-no-parity", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu bad parity": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUBadParity("device-modbus-rtu-bad-parity", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu no serial port": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUNoSerialPort("device-modbus-rtu-no-serial-port", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu no slave id": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUNoSlaveID("device-modbus-rtu-no-slaveID", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu bad slave id": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUBadSlaveID("device-modbus-bad-slaveID", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu no stop bits": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUNoStopBits("device-modbus-rtu-no-stopbits", testNamespace) - return deviceInstance - }, - }, - "device modbus rtu bad_stop_bits": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusRTUBadStopBits("device-modbus-rtu-bad-stopbits", testNamespace) - return deviceInstance - }, - }, - "device modbus tcp no IP": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusTCPNoIP("device-modbus-tcp-no-IP", testNamespace) - return deviceInstance - }, - }, - "device modbus tcp no port": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusTCPNoPort("device-modbus-tcp-no-port", testNamespace) - return deviceInstance - }, - }, - "device modbus tcp no slaveID": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusTCPNoSlaveID("device-modbus-tcp-no-slaveID", testNamespace) - return deviceInstance - }, - }, - "device opcua no url": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceOpcUANoURL("device-opcua-no-url", testNamespace) - return deviceInstance - }, - }, - "device customized no protocol name": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceCustomizedNoName("device-customized-no-name", testNamespace) - return deviceInstance - }, - }, - "device no model reference": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceNoModelReference("device-no-model-ref", "default") - return deviceInstance - }, - }, - "device with ble protocol property bad operation type": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceBluetoothBadOperationType("device-bluetooth-bad-operation-type", testNamespace) - return deviceInstance - }, - }, - "device with ble protocol property no start index": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceBluetoothNoStartIndex("device-bluetooth-no-start-index", testNamespace) - return deviceInstance - }, - }, - "device with ble protocol property no end index": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceBluetoothNoEndIndex("device-bluetooth-bad-operation-type", testNamespace) - return deviceInstance - }, - }, - "device with ble protocol property no characteristic UUID": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceBluetoothNoCharacteristicUUID("device-bluetooth-no-char-uuid", testNamespace) - return deviceInstance - }, - }, - "device with modbus protocol property bad register": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusBadRegister("device-modbus-bad-register", testNamespace) - return deviceInstance - }, - }, - "device with modbus protocol property no register": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusNoRegister("device-modbus-no-register", testNamespace) - return deviceInstance - }, - }, - "device with modbus protocol property no limit": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusNoLimit("device-modbus-no-limit", testNamespace) - return deviceInstance - }, - }, - "device with ble protocol with no offset": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceModbusNoOffset("device-modbus-no-offset", testNamespace) - return deviceInstance - }, - }, - "device with opc ua property no nodeID": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceOpcUANoNodeID("device-modbus-no-nodeID", testNamespace) - return deviceInstance - }, - }, - "device with customized protocol no configData": { - deviceInstanceFn: func() v1alpha2.Device { - deviceInstance := fixtures.NewDeviceCustomizedNoConfigData("device-customized-no-configdata", testNamespace) - return deviceInstance - }, - }, - } - - crdClient := buildCrdClient(t) - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - device := tc.deviceInstanceFn() - _, err := crdClient.DevicesV1alpha2().Devices(device.Namespace).Create(context.TODO(), &device, v1.CreateOptions{}) - if err == nil { - t.Fatalf("%s : expected error", name) - } - }) - } -} diff --git a/cloud/test/integration/fixtures/constants.go b/cloud/test/integration/fixtures/constants.go deleted file mode 100644 index 596606cb9..000000000 --- a/cloud/test/integration/fixtures/constants.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2019 The KubeEdge Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fixtures - -// CRD API Constants -const ( - apiVersion = "devices.kubeedge.io/v1alpha2" - deviceModelKind = "DeviceModel" - deviceKind = "Device" -) - -const ( - ResourceDeviceModel = "devicemodels" - ResourceDevice = "devices" -) - -// Device Model Constants -const ( - devicePropertyTemperature = "temperature" - devicePropertyTemperatureDesc = "temperature in degree celsius" - devicePropertyUnit = "degree celsius" -) - -// Property Vistor Constants -const ( - // time.Duration, nanosecond - reportCycle = 1000000000 - collectCycle = 500000000 -) - -// Device instance constants -const ( - DefaultNamespace = "default" - DeviceModelRef = "sensor-tag-model" -) - -type deviceProtocol string - -// Supported protocols constants -const ( - deviceProtocolBluetooth deviceProtocol = "bluetooth" - deviceProtocolModbus deviceProtocol = "modbus" - deviceProtocolModbusRTU deviceProtocol = "modbusRTU" - deviceProtocolModbusTCP deviceProtocol = "modbusTCP" - deviceProtocolOPCUA deviceProtocol = "opcua" - deviceProtocolCustomized deviceProtocol = "customizedProtocol" -) - -// integer property type constants -const ( - minimum = 0 - maximum = 100 -) - -// Bluetooth Protocol Constants -const ( - characteristicUUID = "f000aa0104514000b000000000000000" - startIndex = 1 - endIndex = 2 - operationValue = 0.03125 - offset = 2 - limit = 1 -) - -// Modbus RTU Protocol Constants -const ( - baudRate = 110 - dataBits = 8 - stopBits = 1 - serialPort = "1" - parity = "none" - slaveID = 100 -) diff --git a/cloud/test/integration/fixtures/device.go b/cloud/test/integration/fixtures/device.go deleted file mode 100644 index 79baa9d36..000000000 --- a/cloud/test/integration/fixtures/device.go +++ /dev/null @@ -1,600 +0,0 @@ -/* -Copyright 2019 The KubeEdge Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fixtures - -import ( - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" - - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" -) - -type DeviceOp struct { - device v1alpha2.Device -} - -type DeviceOption func(*DeviceOp) - -func (op *DeviceOp) applyDeviceOpts(opts []DeviceOption) { - for _, opt := range opts { - opt(op) - } -} - -func newDeviceOp(opts ...DeviceOption) *DeviceOp { - op := &DeviceOp{ - device: v1alpha2.Device{ - Spec: v1alpha2.DeviceSpec{}, - ObjectMeta: metav1.ObjectMeta{}, - TypeMeta: metav1.TypeMeta{ - APIVersion: apiVersion, - Kind: deviceKind, - }, - }, - } - op.applyDeviceOpts(opts) - return op -} - -func withDeviceName(name string) DeviceOption { - return func(op *DeviceOp) { - op.device.ObjectMeta.Name = name - } -} - -func withDeviceNamespace(namespace string) DeviceOption { - return func(op *DeviceOp) { - op.device.ObjectMeta.Namespace = namespace - } -} - -func withDeviceModelReference(deviceModelRef string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.DeviceModelRef = &v1.LocalObjectReference{ - Name: deviceModelRef, - } - } -} - -func withProtocolConfig(protocol deviceProtocol) DeviceOption { - return func(op *DeviceOp) { - switch protocol { - case deviceProtocolModbusRTU: - op.device.Spec.Protocol = v1alpha2.ProtocolConfig{ - Modbus: &v1alpha2.ProtocolConfigModbus{ - SlaveID: pointer.Int64Ptr(1), - }, - Common: &v1alpha2.ProtocolConfigCommon{ - COM: &v1alpha2.ProtocolConfigCOM{}, - }, - } - case deviceProtocolModbusTCP: - op.device.Spec.Protocol = v1alpha2.ProtocolConfig{ - Modbus: &v1alpha2.ProtocolConfigModbus{ - SlaveID: pointer.Int64Ptr(1), - }, - Common: &v1alpha2.ProtocolConfigCommon{ - TCP: &v1alpha2.ProtocolConfigTCP{}, - }, - } - case deviceProtocolBluetooth: - op.device.Spec.Protocol = v1alpha2.ProtocolConfig{ - Bluetooth: &v1alpha2.ProtocolConfigBluetooth{}, - } - case deviceProtocolOPCUA: - op.device.Spec.Protocol = v1alpha2.ProtocolConfig{ - OpcUA: &v1alpha2.ProtocolConfigOpcUA{}, - } - case deviceProtocolCustomized: - op.device.Spec.Protocol = v1alpha2.ProtocolConfig{ - CustomizedProtocol: &v1alpha2.ProtocolConfigCustomized{}, - } - default: - } - } -} - -func withBaudRate(baudRate int64) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.COM.BaudRate = baudRate - } -} - -func withDataBits(dataBits int64) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.COM.DataBits = dataBits - } -} - -func withParity(parity string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.COM.Parity = parity - } -} - -func withSerialPort(serialPort string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.COM.SerialPort = serialPort - } -} - -func withStopBits(stopBits int64) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.COM.StopBits = stopBits - } -} - -func withSlaveID(slaveID int64) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Modbus.SlaveID = &slaveID - } -} - -func withTCPPort(port int64) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.TCP.Port = port - } -} - -func withTCPSlaveID(tcpSlaveID int64) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Modbus.SlaveID = &tcpSlaveID - } -} - -func withTCPServerIP(ip string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Common.TCP.IP = ip - } -} - -func withOPCUAServerURL(url string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.OpcUA.URL = url - } -} - -func withBluetoothMac(mac string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.Bluetooth.MACAddress = mac - } -} - -func withCustromizedProtocolName(name string) DeviceOption { - return func(op *DeviceOp) { - op.device.Spec.Protocol.CustomizedProtocol.ProtocolName = name - } -} - -type DevicePropertyVisitorOp struct { - devicePropertyVisitor v1alpha2.DevicePropertyVisitor -} - -type DevicePropertyVisitorOption func(*DevicePropertyVisitorOp) - -func withVisitorName(name string) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.PropertyName = name - } -} - -func withVisitorReportCycle(reportCycle int64) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.ReportCycle = reportCycle - } -} - -func withVisitorCollectCycle(collectCycle int64) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.CollectCycle = collectCycle - } -} - -func withVisitorConfig(protocol deviceProtocol) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - switch protocol { - case deviceProtocolBluetooth: - op.devicePropertyVisitor.VisitorConfig = v1alpha2.VisitorConfig{ - Bluetooth: &v1alpha2.VisitorConfigBluetooth{ - CharacteristicUUID: "", - BluetoothDataConverter: v1alpha2.BluetoothReadConverter{}, - }, - } - case deviceProtocolModbus: - op.devicePropertyVisitor.VisitorConfig = v1alpha2.VisitorConfig{ - Modbus: &v1alpha2.VisitorConfigModbus{}, - } - case deviceProtocolOPCUA: - op.devicePropertyVisitor.VisitorConfig = v1alpha2.VisitorConfig{ - OpcUA: &v1alpha2.VisitorConfigOPCUA{}, - } - case deviceProtocolCustomized: - op.devicePropertyVisitor.VisitorConfig = v1alpha2.VisitorConfig{ - CustomizedProtocol: &v1alpha2.VisitorConfigCustomized{}, - } - default: - } - } -} - -func withCharacteristicUUID(characteristicUUID string) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.Bluetooth.CharacteristicUUID = characteristicUUID - } -} - -func withStartIndex(startIndex int) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.Bluetooth.BluetoothDataConverter.StartIndex = startIndex - } -} - -func withEndIndex(endIndex int) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.Bluetooth.BluetoothDataConverter.EndIndex = endIndex - } -} - -func withOperation(operationType v1alpha2.BluetoothArithmeticOperationType, value float64) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - bluetoothOperation := v1alpha2.BluetoothOperations{ - BluetoothOperationType: operationType, - BluetoothOperationValue: value, - } - op.devicePropertyVisitor.VisitorConfig.Bluetooth.BluetoothDataConverter.OrderOfOperations = - append(op.devicePropertyVisitor.VisitorConfig.Bluetooth.BluetoothDataConverter.OrderOfOperations, bluetoothOperation) - } -} - -func withRegister(register v1alpha2.ModbusRegisterType) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.Modbus.Register = register - } -} - -func withOffset(offset int64) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.Modbus.Offset = &offset - } -} - -func withLimit(limit int64) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.Modbus.Limit = &limit - } -} - -func withNodeID(nodeID string) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.OpcUA.NodeID = nodeID - } -} - -func withBrowseName(browseName string) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.OpcUA.BrowseName = browseName - } -} - -func withProtocolName(protocolName string) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.CustomizedProtocol.ProtocolName = protocolName - } -} - -func withProtocolConfigData(configData *v1alpha2.CustomizedValue) DevicePropertyVisitorOption { - return func(op *DevicePropertyVisitorOp) { - op.devicePropertyVisitor.VisitorConfig.CustomizedProtocol.ConfigData = configData - } -} - -func (op *DevicePropertyVisitorOp) applyDevicePropVisitorOpts(opts []DevicePropertyVisitorOption) { - for _, opt := range opts { - opt(op) - } -} - -func newDevicePropVisitorOp(opts ...DevicePropertyVisitorOption) *DevicePropertyVisitorOp { - op := &DevicePropertyVisitorOp{ - devicePropertyVisitor: v1alpha2.DevicePropertyVisitor{}, - } - op.applyDevicePropVisitorOpts(opts) - return op -} - -func NewDeviceModbusRTU(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUNoBaudRate(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withDataBits(dataBits), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUBadBaudRate(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(100), withDataBits(dataBits), withParity(parity), - withSerialPort(serialPort), withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUNoDataBits(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUBadDataBits(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(10), withParity(parity), - withSerialPort(serialPort), withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUNoParity(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(10), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUBadParity(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity("test"), - withSerialPort(serialPort), withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUNoSerialPort(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), - withStopBits(stopBits), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUNoSlaveID(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), - withSerialPort(serialPort), withStopBits(stopBits)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUBadSlaveID(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), - withSerialPort(serialPort), withStopBits(stopBits), withSlaveID(300)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUNoStopBits(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), - withSerialPort(serialPort), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusRTUBadStopBits(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), - withSerialPort(serialPort), withStopBits(3), withSlaveID(slaveID)) - return deviceInstanceOp.device -} - -func NewDeviceModbusTCP(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusTCP), withTCPServerIP("127.0.0.1"), withTCPPort(8080), withTCPSlaveID(1)) - return deviceInstanceOp.device -} - -func NewDeviceModbusTCPNoIP(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusTCP), withTCPPort(8080), withTCPSlaveID(1)) - return deviceInstanceOp.device -} - -func NewDeviceModbusTCPNoPort(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusTCP), withTCPServerIP("127.0.0.1"), withTCPSlaveID(1)) - return deviceInstanceOp.device -} - -func NewDeviceModbusTCPNoSlaveID(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusTCP), withTCPPort(8080), withTCPServerIP("127.0.0.1")) - return deviceInstanceOp.device -} - -func NewDeviceOpcUA(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolOPCUA), withOPCUAServerURL("http://test-opcuaserver.com")) - return deviceInstanceOp.device -} - -func NewDeviceOpcUANoURL(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolOPCUA)) - return deviceInstanceOp.device -} - -func NewDeviceCustomized(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolCustomized), withCustromizedProtocolName("test-customized-protocol")) - return deviceInstanceOp.device -} - -func NewDeviceCustomizedNoName(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolCustomized)) - return deviceInstanceOp.device -} - -func NewDeviceNoModelReference(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withProtocolConfig(deviceProtocolOPCUA)) - return deviceInstanceOp.device -} - -func NewDeviceBluetoothBadOperationType(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolBluetooth), withBluetoothMac("BC:6A:29:AE:CC:96")) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolBluetooth), - withCharacteristicUUID(characteristicUUID), withStartIndex(startIndex), withEndIndex(endIndex), - withOperation("modulo", operationValue)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceBluetoothNoStartIndex(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolBluetooth), withBluetoothMac("BC:6A:29:AE:CC:96")) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolBluetooth), - withCharacteristicUUID(characteristicUUID), withEndIndex(endIndex), withOperation(v1alpha2.BluetoothAdd, operationValue)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceBluetoothNoEndIndex(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolBluetooth), withBluetoothMac("BC:6A:29:AE:CC:96")) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolBluetooth), - withCharacteristicUUID(characteristicUUID), withStartIndex(startIndex), withOperation(v1alpha2.BluetoothMultiply, operationValue)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceBluetoothNoCharacteristicUUID(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolBluetooth), withBluetoothMac("BC:6A:29:AE:CC:96")) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolBluetooth), - withStartIndex(startIndex), withEndIndex(endIndex), withOperation(v1alpha2.BluetoothAdd, operationValue)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceModbusBadRegister(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolModbus), - withRegister("test-register"), withLimit(limit), withOffset(offset)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceModbusNoLimit(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolModbus), - withRegister(v1alpha2.ModbusRegisterTypeCoilRegister), withOffset(offset)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceModbusNoOffset(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolModbus), - withRegister(v1alpha2.ModbusRegisterTypeCoilRegister), withLimit(limit)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceModbusNoRegister(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolModbusRTU), withBaudRate(baudRate), withDataBits(dataBits), withParity(parity), withSerialPort(serialPort), - withStopBits(stopBits), withSlaveID(slaveID)) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolModbus), - withLimit(limit), withOffset(offset)) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceOpcUANoNodeID(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolOPCUA), withOPCUAServerURL("http://test-opcuaserver.com")) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolOPCUA), - withBrowseName("test")) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} - -func NewDeviceCustomizedNoConfigData(name string, namespace string) v1alpha2.Device { - deviceInstanceOp := newDeviceOp(withDeviceName(name), withDeviceNamespace(namespace), withDeviceModelReference(DeviceModelRef), - withProtocolConfig(deviceProtocolCustomized), withCustromizedProtocolName("test-customized-protocol")) - - devicePropertyVisitorOp := newDevicePropVisitorOp(withVisitorName(devicePropertyTemperature), - withVisitorCollectCycle(collectCycle), - withVisitorReportCycle(reportCycle), - withVisitorConfig(deviceProtocolCustomized), - withProtocolName("test")) - deviceInstanceOp.device.Spec.PropertyVisitors = append(deviceInstanceOp.device.Spec.PropertyVisitors, devicePropertyVisitorOp.devicePropertyVisitor) - - return deviceInstanceOp.device -} diff --git a/cloud/test/integration/fixtures/devicemodel.go b/cloud/test/integration/fixtures/devicemodel.go deleted file mode 100644 index 77ee7e462..000000000 --- a/cloud/test/integration/fixtures/devicemodel.go +++ /dev/null @@ -1,158 +0,0 @@ -/* -Copyright 2019 The KubeEdge Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fixtures - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kubeedge/kubeedge/pkg/apis/devices/v1alpha2" -) - -type DevicePropertyOp struct { - deviceProperty v1alpha2.DeviceProperty -} - -type DevicePropertyOption func(*DevicePropertyOp) - -func withName(name string) DevicePropertyOption { - return func(op *DevicePropertyOp) { - op.deviceProperty.Name = name - } -} - -func withDescription(description string) DevicePropertyOption { - return func(op *DevicePropertyOp) { - op.deviceProperty.Description = description - } -} - -func withStringType(accessMode v1alpha2.PropertyAccessMode, defaultValue string) DevicePropertyOption { - return func(op *DevicePropertyOp) { - stringType := &v1alpha2.PropertyTypeString{ - DefaultValue: defaultValue, - } - stringType.AccessMode = accessMode - op.deviceProperty.Type = v1alpha2.PropertyType{ - String: stringType, - } - } -} - -func withIntType(accessMode v1alpha2.PropertyAccessMode, defaultValue int64, minimum int64, maximum int64, unit string) DevicePropertyOption { - return func(op *DevicePropertyOp) { - intType := &v1alpha2.PropertyTypeInt64{ - DefaultValue: defaultValue, - Minimum: minimum, - Maximum: maximum, - Unit: unit, - } - intType.AccessMode = accessMode - op.deviceProperty.Type = v1alpha2.PropertyType{ - Int: intType, - } - } -} - -func (op *DevicePropertyOp) applyDevicePropertyOpts(opts []DevicePropertyOption) { - for _, opt := range opts { - opt(op) - } -} - -func newDevicePropertyOp(opts ...DevicePropertyOption) *DevicePropertyOp { - op := &DevicePropertyOp{ - deviceProperty: v1alpha2.DeviceProperty{}, - } - op.applyDevicePropertyOpts(opts) - return op -} - -func newDeviceModel(name string, namespace string) *v1alpha2.DeviceModel { - spec := v1alpha2.DeviceModelSpec{} - deviceModel := &v1alpha2.DeviceModel{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: apiVersion, - Kind: deviceModelKind, - }, - Spec: spec, - } - return deviceModel -} - -func DeviceModelWithPropertyNoName(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withDescription(devicePropertyTemperatureDesc), - withStringType(v1alpha2.ReadOnly, "")) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - return deviceModel -} - -func DeviceModelWithPropertyNoType(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withName(devicePropertyTemperature), withDescription(devicePropertyTemperatureDesc)) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - return deviceModel -} - -func DeviceModelWithPropertyBadAccessMode(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withName(devicePropertyTemperature), withDescription(devicePropertyTemperatureDesc), - withStringType("", "")) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - - return deviceModel -} - -func NewDeviceModelBluetooth(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withName(devicePropertyTemperature), withDescription(devicePropertyTemperatureDesc), - withIntType(v1alpha2.ReadOnly, 0, minimum, maximum, devicePropertyUnit)) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - - return deviceModel -} - -func NewDeviceModelModbus(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withName(devicePropertyTemperature), withDescription(devicePropertyTemperatureDesc), - withIntType(v1alpha2.ReadOnly, 0, minimum, maximum, devicePropertyUnit)) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - - return deviceModel -} - -func NewDeviceModelOpcUA(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withName(devicePropertyTemperature), withDescription(devicePropertyTemperatureDesc), - withIntType(v1alpha2.ReadOnly, 0, minimum, maximum, devicePropertyUnit)) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - - return deviceModel -} - -func NewDeviceModelCustomized(name string, namespace string) *v1alpha2.DeviceModel { - deviceModel := newDeviceModel(name, namespace) - devicePropertyOp := newDevicePropertyOp(withName(devicePropertyTemperature), withDescription(devicePropertyTemperatureDesc), - withIntType(v1alpha2.ReadOnly, 0, minimum, maximum, devicePropertyUnit)) - deviceModel.Spec.Properties = append(deviceModel.Spec.Properties, devicePropertyOp.deviceProperty) - - return deviceModel -} |
