3 Star 1 Fork 0

EdgexFoundry/core-metadata-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
rest_device.go 30.96 KB
一键复制 编辑 原始数据 按行查看 历史
Jim White 提交于 2017-12-29 21:37 . fixes to address black box tests
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
/*******************************************************************************
* Copyright 2017 Dell Inc.
*
* 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.
*
* @microservice: core-metadata-go service
* @author: Spencer Bull & Ryan Comer, Dell
* @version: 0.5.0
*******************************************************************************/
package main
import (
"encoding/json"
"errors"
"net/http"
"net/url"
"strconv"
"time"
"github.com/edgexfoundry/core-domain-go/models"
notifications "github.com/edgexfoundry/support-notifications-client-go"
"github.com/gorilla/mux"
"gopkg.in/mgo.v2"
)
func restGetAllDevices(w http.ResponseWriter, _ *http.Request) {
res := make([]models.Device, 0)
err := getAllDevices(&res)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check the max length
if len(res) > configuration.ReadMaxLimit {
err = errors.New("Max limit exceeded")
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusRequestEntityTooLarge)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(&res)
}
// Post a new device
// Attached objects (Addressable, Profile, Service) are referenced by ID or name
// 409 conflict if any of the attached items can't be found by ID or name
// Ignore everything else from the attached objects
func restAddNewDevice(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
var d models.Device
err := json.NewDecoder(r.Body).Decode(&d)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Addressable check
// Try by name
err = getAddressableByName(&d.Addressable, d.Addressable.Name)
if err != nil {
// Try by ID
err = getAddressableById(&d.Addressable, d.Addressable.Id.Hex())
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error()+": A device must be associated to an Addressable", http.StatusConflict)
return
}
}
// Service Check
// Try by name
err = getDeviceServiceByName(&d.Service, d.Service.Service.Name)
if err != nil {
// Try by ID
err = getDeviceServiceById(&d.Service, d.Service.Service.Id.Hex())
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error()+": A device must be associated with a device service", http.StatusConflict)
return
}
}
// Profile Check
// Try by name
err = getDeviceProfileByName(&d.Profile, d.Profile.Name)
if err != nil {
// Try by ID
err = getDeviceProfileById(&d.Profile, d.Profile.Id.Hex())
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error()+": A device must be associated with a device profile", http.StatusConflict)
return
}
}
// Check operating/admin state
if d.OperatingState == models.OperatingState("") || d.AdminState == models.AdminState("") {
err = errors.New("Device can't have null operating state or admin state")
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusConflict)
return
}
// Add the device
err = addDevice(&d)
if err != nil {
if err == ErrDuplicateName {
http.Error(w, "Duplicate name for device", http.StatusConflict)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Notify the associates
notifyDeviceAssociates(d, models.POST)
w.WriteHeader(http.StatusOK)
w.Write([]byte(d.Id.Hex()))
}
// Update the device
// Use ID to identify device first, then name
// Can't create new Device Services/Profiles with a PUT, but you can reference another one
func restUpdateDevice(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
var rd models.Device
err := json.NewDecoder(r.Body).Decode(&rd)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var oldDevice models.Device
// First try ID
err = getDeviceById(&oldDevice, rd.Id.Hex())
if err != nil {
// Then try name
err = getDeviceByName(&oldDevice, rd.Name)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusNotFound)
return
}
}
if err = updateDeviceFields(rd, &oldDevice); err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
if err = UpdateDevice(oldDevice); err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Notify
notifyDeviceAssociates(oldDevice, models.PUT)
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
// Update the device fields
func updateDeviceFields(from models.Device, to *models.Device) error {
if (from.Addressable != models.Addressable{}) {
// Check if the new addressable exists
var a models.Addressable
// Try ID first
err := getAddressableById(&a, from.Addressable.Id.Hex())
if err != nil {
// Then try name
err = getAddressableByName(&a, from.Addressable.Name)
if err != nil {
return errors.New("Addressable not found for updated device")
}
}
to.Addressable = a
}
if (from.Service.String() != models.DeviceService{}.String()) {
// Check if the new service exists
var ds models.DeviceService
// Try ID first
err := getDeviceServiceById(&ds, from.Service.Service.Id.Hex())
if err != nil {
// Then try name
err = getDeviceServiceByName(&ds, from.Service.Service.Name)
if err != nil {
return errors.New("Device service not found for updated device")
}
}
to.Service = ds
}
if (from.Profile.String() != models.DeviceProfile{}.String()) {
// Check if the new profile exists
var dp models.DeviceProfile
// Try ID first
err := getDeviceProfileById(&dp, from.Profile.Id.Hex())
if err != nil {
// Then try Name
err = getDeviceProfileByName(&dp, from.Profile.Name)
if err != nil {
return errors.New("Device profile not found for updated device")
}
}
to.Profile = dp
}
if from.AdminState != "" {
to.AdminState = from.AdminState
}
if from.Description != "" {
to.Description = from.Description
}
if from.Labels != nil {
to.Labels = from.Labels
}
if from.LastConnected != 0 {
to.LastConnected = from.LastConnected
}
if from.LastReported != 0 {
to.LastReported = from.LastReported
}
if from.Location != nil {
to.Location = from.Location
}
if from.OperatingState != models.OperatingState("") {
to.OperatingState = from.OperatingState
}
if from.Origin != 0 {
to.Origin = from.Origin
}
if from.Name != "" {
to.Name = from.Name
// Check if the name is unique
var checkD models.Device
err := getDeviceByName(&checkD, from.Name)
if err != nil {
// A problem occured accessing database
if err != mgo.ErrNotFound {
loggingClient.Error(err.Error(), "")
return err
}
}
// Found a device, make sure its the one we're trying to update
if err != mgo.ErrNotFound {
// Differnt IDs -> Name is not unique
if checkD.Id != to.Id {
err = errors.New("Duplicate name for Device")
loggingClient.Error(err.Error(), "")
return err
}
}
}
return nil
}
func restGetDevicesWithLabel(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
label, err := url.QueryUnescape(vars[LABEL])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var labels []string
labels = append(labels, label)
res := make([]models.Device, 0)
err = getDevicesWithLabel(&res, labels)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restGetDeviceByProfileId(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var pid string = vars[PROFILEID]
// Check if the device profile exists
var dp models.DeviceProfile
err := getDeviceProfileById(&dp, pid)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
res := make([]models.Device, 0)
err = getDevicesByProfileId(&res, pid)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restGetDeviceByServiceId(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var sid string = vars[SERVICEID]
res := make([]models.Device, 0)
// Check if the device service exists
var ds models.DeviceService
err := getDeviceServiceById(&ds, sid)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
err = getDevicesByServiceId(&res, sid)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
// If the result array is empty, don't return http.NotFound, just return empty array
func restGetDeviceByServiceName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
sn, err := url.QueryUnescape(vars[SERVICENAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device service exists
var ds models.DeviceService
err = getDeviceServiceByName(&ds, sn)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
res := make([]models.Device, 0)
// Find devices by service ID now that you have the Service object (and therefor the ID)
err = getDevicesByServiceId(&res, ds.Service.Id.Hex())
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restGetDeviceByAddressableName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
an, err := url.QueryUnescape(vars[ADDRESSABLENAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the addressable exists
var a models.Addressable
err = getAddressableByName(&a, an)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
res := make([]models.Device, 0)
// Use the addressable ID now that you have the addressable object
err = getDevicesByAddressableId(&res, a.Id.Hex())
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restGetDeviceByProfileName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
pn, err := url.QueryUnescape(vars[PROFILENAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device profile exists
var dp models.DeviceProfile
err = getDeviceProfileByName(&dp, pn)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
res := make([]models.Device, 0)
// Use profile ID now that you have the profile object
err = getDevicesByProfileId(&res, dp.Id.Hex())
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restGetDeviceByAddressableId(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var aid string = vars[ADDRESSABLEID]
// Check if the addressable exists
var a models.Addressable
err := getAddressableById(&a, aid)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
res := make([]models.Device, 0)
err = getDevicesByAddressableId(&res, aid)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restGetDeviceById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID]
var res models.Device
if err := getDeviceById(&res, did); err != nil {
loggingClient.Error(err.Error(), "")
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func restSetDeviceOpStateById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID] // TODO check if DID needs to be a bson
var os string = vars[OPSTATE]
f := models.IsOperatingStateType(os)
if !f {
err := errors.New("Invalid State: " + os + " Must be 'ENABLED' or 'DISABLED'")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return
}
// Check if the device exists
var d models.Device
err := getDeviceById(&d, did)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update OpState
if err = setOpState(d, os, w); err != nil {
return
}
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
return
}
func restSetDeviceOpStateByName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var os string = vars[OPSTATE]
f := models.IsOperatingStateType(os)
// Opstate is invalid
if !f {
err := errors.New("Invalid State: " + os + " Must be 'ENABLED' or 'DISABLED'")
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update OpState
if err = setOpState(d, os, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
// Update the opstate of the device
func setOpState(d models.Device, os string, w http.ResponseWriter) error {
err := setById(DEVICECOL, d.Id.Hex(), "operatingState", os)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return err
}
// Notify
notifyDeviceAssociates(d, models.PUT)
return nil
}
func restSetDeviceAdminStateById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID]
var as string = vars[ADMINSTATE]
f := models.IsAdminStateType(as)
if !f {
err := errors.New("Invalid State: " + as + " Must be 'LOCKED' or 'UNLOCKED'")
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err := getDeviceById(&d, did)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update the AdminState
if err = setAdminState(d, as, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
return
}
func restSetDeviceAdminStateByName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var as string = vars[ADMINSTATE]
f := models.IsAdminStateType(as)
if !f {
err = errors.New("Invalid State: " + as + " Must be 'LOCKED' or 'UNLOCKED'")
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update the admin state
if err = setAdminState(d, as, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
return
}
// Update the admin state for the device
func setAdminState(d models.Device, as string, w http.ResponseWriter) error {
if err := setById(DEVICECOL, d.Id.Hex(), ADMINSTATE, as); err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return err
}
if err := notifyDeviceAssociates(d, models.PUT); err != nil {
return err
}
return nil
}
func restDeleteDeviceById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID]
// Check if the device exists
var d models.Device
//err := getDeviceById(&d, did)
if err := getDeviceById(&d, did); err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
if err := deleteDevice(d, w); err != nil {
loggingClient.Error(err.Error(), "")
return
}
w.Write([]byte("true"))
}
func restDeleteDeviceByName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusNotFound)
return
}
if err := deleteDevice(d, w); err != nil {
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
// Delete the device
func deleteDevice(d models.Device, w http.ResponseWriter) error {
if err := deleteAssociatedReportsForDevice(d, w); err != nil {
return err
}
if err := deleteById(DEVICECOL, d.Id.Hex()); err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return err
}
// Notify Associates
if err := notifyDeviceAssociates(d, models.DELETE); err != nil {
return err
}
return nil
}
// Delete the associated device reports for the device
func deleteAssociatedReportsForDevice(d models.Device, w http.ResponseWriter) error {
var reports []models.DeviceReport
if err := getDeviceReportByDeviceName(&reports, d.Name); err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return err
}
// Delete the associated reports
for _, report := range reports {
if err := deleteById(DRCOL, report.Id.Hex()); err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
loggingClient.Error(err.Error(), "")
return err
}
notifyDeviceReportAssociates(report, models.DELETE)
}
return nil
}
func restSetDeviceLastConnectedById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID]
var vlc string = vars[LASTCONNECTED]
lc, err := strconv.ParseInt(vlc, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceById(&d, did)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last connected
if err = setLastConnected(d, lc, false, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
func restSetLastConnectedByIdNotify(w http.ResponseWriter, r *http.Request) {
// Get the URL parameters
vars := mux.Vars(r)
var did = vars[ID]
var vlc = vars[LASTCONNECTED]
notify, err := strconv.ParseBool(vars[LASTCONNECTEDNOTIFY])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
lc, err := strconv.ParseInt(vlc, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceById(&d, did)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last connected
if err = setLastConnected(d, lc, notify, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
func restSetDeviceLastConnectedByName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var vlc string = vars[LASTCONNECTED]
lc, err := strconv.ParseInt(vlc, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last connected
if err = setLastConnected(d, lc, false, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
func restSetDeviceLastConnectedByNameNotify(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var vlc string = vars[LASTCONNECTED]
lc, err := strconv.ParseInt(vlc, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
notify, err := strconv.ParseBool(vars[LASTCONNECTEDNOTIFY])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last connected
if err = setLastConnected(d, lc, notify, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
// Update the last connected value for the device
func setLastConnected(d models.Device, time int64, notify bool, w http.ResponseWriter) error {
if err := setByIdInt(DEVICECOL, d.Id.Hex(), LASTCONNECTED, time); err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return err
}
if notify {
notifyDeviceAssociates(d, models.PUT)
}
return nil
}
func restSetDeviceLastReportedById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID]
var vlr string = vars[LASTREPORTED]
lr, err := strconv.ParseInt(vlr, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceById(&d, did)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update Last Reported
if err = setLastReported(d, lr, false, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
func restSetDeviceLastReportedByIdNotify(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var did string = vars[ID]
var vlr string = vars[LASTREPORTED]
lr, err := strconv.ParseInt(vlr, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
notify, err := strconv.ParseBool(vars[LASTREPORTEDNOTIFY])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceById(&d, did)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last reported
if err = setLastReported(d, lr, notify, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
func restSetDeviceLastReportedByName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var vlr string = vars[LASTREPORTED]
lr, err := strconv.ParseInt(vlr, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last reported
if err = setLastReported(d, lr, false, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
func restSetDeviceLastReportedByNameNotify(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
n, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var vlr string = vars[LASTREPORTED]
lr, err := strconv.ParseInt(vlr, 10, 64)
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
notify, err := strconv.ParseBool(vars[LASTREPORTEDNOTIFY])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Check if the device exists
var d models.Device
err = getDeviceByName(&d, n)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
// Update last reported
if err = setLastReported(d, lr, notify, w); err != nil {
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("true"))
}
// Update the last reported field of the device
func setLastReported(d models.Device, time int64, notify bool, w http.ResponseWriter) error {
if err := setByIdInt(DEVICECOL, d.Id.Hex(), LASTREPORTED, time); err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return err
}
if notify {
notifyDeviceAssociates(d, models.PUT)
}
return nil
}
func restGetDeviceByName(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
dn, err := url.QueryUnescape(vars[NAME])
if err != nil {
loggingClient.Error(err.Error(), "")
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
var res models.Device
err = getDeviceByName(&res, dn)
if err != nil {
if err == mgo.ErrNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
loggingClient.Error(err.Error(), "")
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
// Notify the associated device service for the device
func notifyDeviceAssociates(d models.Device, action models.NotifyAction) error {
// Post the notification to the notifications service
postNotification(d.Name, action)
// Callback for device service
var ds models.DeviceService
if err := getDeviceServiceById(&ds, d.Service.Service.Id.Hex()); err != nil {
loggingClient.Error(err.Error(), "")
return err
}
var services []models.DeviceService
services = append(services, ds)
if err := notifyAssociates(services, d.Id.Hex(), action, models.DEVICE); err != nil {
loggingClient.Error(err.Error(), "")
return err
}
return nil
}
func postNotification(name string, action models.NotifyAction) {
// Only post notification if the configuration is set
if configuration.NotificationPostDeviceChanges {
// Make the notification
notification := notifications.Notification{
Slug: configuration.NotificationsSlug + strconv.FormatInt((time.Now().UnixNano()/int64(time.Millisecond)), 10),
Content: configuration.NotificationContent + name + "-" + string(action),
Category: notifications.SW_HEALTH,
Description: configuration.NotificationDescription,
Labels: []string{configuration.NotificationLabel},
Sender: configuration.NotificationSender,
Severity: notifications.NORMAL,
}
notificationsClient.RecieveNotification(notification)
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/EdgexFoundry/core-metadata-go.git
[email protected]:EdgexFoundry/core-metadata-go.git
EdgexFoundry
core-metadata-go
core-metadata-go
master

搜索帮助