func GetAppDB(name string) (appDB.Info, error) {
	info, err := appQuery.Get(name)
	if err != nil {
		log.Warn(err.Error())
	}
	return info, err
}
GetAppDB returns information corresponding to the service application name
package configuremgr
import (
	"errors"
	"fmt"
	"github.com/lf-edge/edge-home-orchestration-go/internal/common/logmgr"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
	types "github.com/lf-edge/edge-home-orchestration-go/internal/common/types/configuremgrtypes"
	appDB "github.com/lf-edge/edge-home-orchestration-go/internal/db/bolt/application"
	"github.com/fsnotify/fsnotify"
	"gopkg.in/ini.v1"
)
const logPrefix = "Configuremgr"
type Notifier interface {
	Notify(serviceinfo types.ServiceInfo)
}
type Watcher interface {
	Watch(notifier Notifier)
}
type ConfigureMgr struct {
	confpath string
	execType string
}
var (
	appQuery        appDB.DBInterface
	configuremgrObj *ConfigureMgr
	log             = logmgr.GetInstance()
)
func init() {
	appQuery = appDB.Query{}
	configuremgrObj = new(ConfigureMgr)
}
func GetInstance(configPath, execType string) *ConfigureMgr {
	configuremgrObj.confpath = configPath
	configuremgrObj.execType = execType
	return configuremgrObj
}
func (cfgMgr ConfigureMgr) SetConfigPath(configPath string) error {
	_, err := os.Stat(configPath)
	if err == nil {
		configuremgrObj.confpath = configPath
	} else {
		log.Warn("no config file path")
	}
	return err
}
func (cfgMgr ConfigureMgr) Watch(notifier Notifier) {
	files, err := ioutil.ReadDir(cfgMgr.confpath)
	if err != nil {
		log.Fatal(err)
	}
	for _, f := range files {
		info, err := getServiceInfo(cfgMgr.confpath + "/" + f.Name())
		if err == nil {
			notifier.Notify(info)
		}
	}
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		for {
			select {
			case event := <-watcher.Events:
				log.Debug("event:", event)
				switch event.Op {
				case fsnotify.Create, fsnotify.Write:
					_, dirName := filepath.Split(event.Name)
					confFileName := fmt.Sprint(event.Name, "/", dirName, ".conf")
					log.Debug("IsConfExist:", confFileName)
					isConfExist := false
					for i := 0; i < 5; i++ {
						if _, err := os.Stat(confFileName); !os.IsNotExist(err) {
							isConfExist = true
							break
						}
						time.Sleep(time.Second * 1)
					}
					if !isConfExist {
						log.Warn(confFileName, "does not exist")
						continue
					}
					info, err := getServiceInfo(event.Name)
					if err == nil {
						notifier.Notify(info)
					}
				case fsnotify.Remove:
				}
			case err := <-watcher.Errors:
				if err != nil {
					log.Warn("error:", err)
				}
			}  
		}  
	}()
	err = watcher.Add(cfgMgr.confpath)
	if err != nil {
		log.Fatal(err)
	}
	log.Info("start watching for", cfgMgr.confpath)
	log.Debug("configuremgr watcher register end")
}
func getServiceInfo(path string) (types.ServiceInfo, error) {
	confPath, err := getdirname(path)
	if err != nil {
		log.Warn("wrong libPath or confPath")
		return types.ServiceInfo{}, err
	}
	cfg, err := ini.Load(confPath)
	if err != nil {
		log.Debug("Fail to read ", confPath, "file, err = ", err)
		return types.ServiceInfo{}, err
	}
	serviceName := cfg.Section("ServiceInfo").Key("ServiceName").String()
	executableName := cfg.Section("ServiceInfo").Key("ExecutableFileName").String()
	allowedRequesterName := cfg.Section("ServiceInfo").Key("AllowedRequester").Strings(",")
	execType := cfg.Section("ServiceInfo").Key("ExecType").String()
	execCmd := cfg.Section("ServiceInfo").Key("ExecCmd").Strings(" ")
	log.Debug("[configuremgr] ServiceName:", serviceName)
	log.Debug("[configuremgr] ExecutableFileName:", executableName)
	log.Debug("[configuremgr] AllowedRequester:", allowedRequesterName)
	log.Debug("[configuremgr] ExecType:", execType)
	log.Debug("[configuremgr] ExecCmd:", execCmd)
	if execType != configuremgrObj.execType {
		log.Warn("Type of ", serviceName, " is not ", configuremgrObj.execType)
		return types.ServiceInfo{}, errors.New("execution type mismatch")
	}
	ret := types.ServiceInfo{
		ServiceName:        serviceName,
		ExecutableFileName: executableName,
		AllowedRequester:   allowedRequesterName,
		ExecType:           execType,
		ExecCmd:            execCmd,
	}
	appInfo := appDB.Info{
		ServiceName:        serviceName,
		ExecutableFileName: executableName,
		AllowedRequester:   allowedRequesterName,
		ExecType:           execType,
		ExecCmd:            execCmd,
	}
	setAppDB(appInfo)
	return ret, nil
}
func getdirname(path string) (confPath string, err error) {
	idx := strings.LastIndex(path, "/")
	if idx == (len(path) - 1) {
		path = path[:len(path)-1]
	}
	dirname := path[strings.LastIndex(path, "/")+1:]
	confPath = path + "/" + dirname + ".conf"
	for i := 0; i < 5; i++ {
		if _, err = os.Stat(confPath); err == nil {
			return
		}
		time.Sleep(time.Second * 1)
	}
	return "", err
}
func setAppDB(appInfo appDB.Info) {
	err := appQuery.Set(appInfo)
	if err != nil {
		log.Warn(err.Error())
	}
}