Beispiel #1
0
// subscribe for notifications
func (service *Service) SubscribeNotifications(device *core.Device, timestamp string, timeout time.Duration) (listener *core.NotificationListener, err error) {
	if listener, ok := service.notificationListeners[device.Id]; ok {
		return listener, nil
	}

	// install new
	listener = core.NewNotificationListener()
	service.notificationListeners[device.Id] = listener

	go func(deviceId string) {
		log.Debugf("REST: start notification polling %q", deviceId)
		for {
			names := ""
			wait := "30"
			ntfs, err := service.PollNotifications(device, timestamp, names, wait, 60*time.Second)
			if err != nil {
				log.Warnf("REST: failed to poll notifications (error: %s)", err)
				// TODO: break? wait and try again?
			}
			if listener, ok := service.notificationListeners[deviceId]; ok {
				for _, ntf := range ntfs {
					log.Debugf("REST: got notification %s received", ntf)
					timestamp = ntf.Timestamp
					listener.C <- &ntf
				}
			} else {
				log.Debugf("REST: stop notification polling %q", deviceId)
				return // stop
			}
		}
	}(device.Id)

	return
}
Beispiel #2
0
// subscribe for commands
func (service *Service) SubscribeCommands(device *core.Device, timestamp string, timeout time.Duration) (listener *core.CommandListener, err error) {
	if listener, ok := service.commandListeners[device.Id]; ok {
		return listener, nil
	}

	// install new
	listener = core.NewCommandListener()
	service.commandListeners[device.Id] = listener

	go func(deviceId string) {
		log.Debugf("REST: start command polling %q", deviceId)
		for {
			names := ""
			wait := "30"
			cmds, err := service.PollCommands(device, timestamp, names, wait, 60*time.Second)
			if err != nil {
				log.Warnf("REST: failed to poll commands (error: %s)", err)
				// TODO: break? wait and try again?
			}
			if listener, ok := service.commandListeners[deviceId]; ok {
				for _, cmd := range cmds {
					log.Debugf("REST: got command %s received", cmd)
					timestamp = cmd.Timestamp
					listener.C <- &cmd
				}
			} else {
				log.Debugf("REST: stop command polling %q", deviceId)
				return // stop
			}
		}
	}(device.Id)

	return
}
// GetCommand() function get the command data.
func (service *Service) GetCommand(device *core.Device, commandId uint64, timeout time.Duration) (command *core.Command, err error) {
	log.Debugf("REST: getting command %q/%d...", device.Id, commandId)

	task, err := service.prepareGetCommand(device, commandId)
	if err != nil {
		log.Warnf("REST: failed to prepare /command/get task (error: %s)", err)
		return
	}

	select {
	case <-time.After(timeout):
		log.Warnf("REST: failed to wait %s for /command/get task", timeout)
		err = fmt.Errorf("timed out")

	case task = <-service.doAsync(task):
		command = &core.Command{Id: commandId}
		err = service.processGetCommand(task, command)
		if err != nil {
			log.Warnf("REST: failed to process /command/get task (error: %s)", err)
			return
		}
	}

	return
}
Beispiel #4
0
// Do a request/task asynchronously
func (service *Service) doAsync(task Task) <-chan Task {
	ch := make(chan Task, 1)

	go func() {
		defer func() { ch <- task }()

		log.Tracef("REST: sending: %+v", task.request)
		task.response, task.err = service.client.Do(task.request)
		if task.err != nil {
			log.Warnf("REST: failed to do %s %s request (error: %s)",
				task.request.Method, task.request.URL, task.err)
			return
		}
		log.Tracef("REST: got %s %s response: %+v",
			task.request.Method, task.request.URL, task.response)

		// read body
		defer task.response.Body.Close()
		task.body, task.err = ioutil.ReadAll(task.response.Body)
		if task.err != nil {
			log.Warnf("REST: failed to read %s %s response body (error: %s)",
				task.request.Method, task.request.URL, task.err)
			return
		}

		log.Debugf("REST: got %s %s body: %s",
			task.request.Method, task.request.URL, string(task.body))
	}()

	return ch
}
// InsertCommand() function inserts the device command.
func (service *Service) InsertCommand(device *core.Device, command *core.Command, timeout time.Duration) (err error) {
	log.Debugf("REST: inserting command %q to %q...", command.Name, device.Id)

	task, err := service.prepareInsertCommand(device, command)
	if err != nil {
		log.Warnf("REST: failed to prepare /command/insert task (error: %s)", err)
		return
	}

	select {
	case <-time.After(timeout):
		log.Warnf("REST: failed to wait %s for /command/insert task", timeout)
		err = fmt.Errorf("timed out")

	case task = <-service.doAsync(task):
		err = service.processInsertCommand(task, command)
		if err != nil {
			log.Warnf("REST: failed to process /command/insert task (error: %s)", err)
			return
		}
	}

	return
}
// GetCommand() function poll the commands.
func (service *Service) PollCommands(device *core.Device, timestamp, names, waitTimeout string, timeout time.Duration) (commands []core.Command, err error) {
	log.Debugf("REST: polling commands %q, timestamp:%q...", device.Id, timestamp)

	task, err := service.preparePollCommand(device, timestamp, names, waitTimeout)
	if err != nil {
		log.Warnf("REST: failed to prepare /command/poll task (error: %s)", err)
		return
	}

	select {
	case <-time.After(timeout):
		log.Warnf("REST: failed to wait %s for /command/poll task", timeout)
		err = fmt.Errorf("timed out")

	case task = <-service.doAsync(task):
		commands, err = service.processPollCommand(task)
		if err != nil {
			log.Warnf("REST: failed to process /command/poll task (error: %s)", err)
			return
		}
	}

	return
}
// DeleteDevice() function deletes the device.
func (service *Service) DeleteDevice(device *core.Device, timeout time.Duration) (err error) {
	log.Debugf("REST: deleting device %q...", device.Id)

	task, err := service.prepareDeleteDevice(device)
	if err != nil {
		log.Warnf("REST: failed to prepare /device/delete task (error: %s)", err)
		return
	}

	select {
	case <-time.After(timeout):
		log.Warnf("REST: failed to wait %s for /device/delete task", timeout)
		err = fmt.Errorf("timed out")

	case task = <-service.doAsync(task):
		err = service.processDeleteDevice(task)
		if err != nil {
			log.Warnf("REST: failed to process /device/delete task (error: %s)", err)
			return
		}
	}

	return
}