- Add export API to interface
authorjw_wonny.cha <jw_wonny.cha@samsung.com>
Thu, 28 Mar 2019 12:36:52 +0000 (21:36 +0900)
committerjw_wonny.cha <jw_wonny.cha@samsung.com>
Thu, 28 Mar 2019 12:36:52 +0000 (21:36 +0900)
src/servicemgr/servicemgr.go [new file with mode: 0644]
src/servicemgr/servicemgr_test.go [new file with mode: 0644]

diff --git a/src/servicemgr/servicemgr.go b/src/servicemgr/servicemgr.go
new file mode 100644 (file)
index 0000000..bc5d86b
--- /dev/null
@@ -0,0 +1,141 @@
+package servicemgr
+
+import (
+       "encoding/json"
+       "errors"
+       "fmt"
+       "log"
+       "net"
+       "os/exec"
+       "strconv"
+       "strings"
+)
+
+// ExecuteApp function
+func ExecuteApp(target string, name string, args []string, notiChan chan string) (serviceID uint64, err error) {
+       appInfo := make(map[string]interface{})
+
+       serviceID = createServiceMap(name, notiChan)
+       appInfo[ConstKeyServiceID] = serviceID
+
+       if args != nil {
+               appInfo[ConstKeyUserArgs] = args
+       }
+       appInfo[ConstKeyServiceName] = name
+
+       if strings.Compare(target, getOutboundIP()) == 0 {
+               appInfo[ConstKeyNotiTargetURL] = ConstLocalTarget
+               err = executeLocalEnv(appInfo)
+       } else {
+               appInfo[ConstKeyNotiTargetURL] = ConstPrefixHTTP + target + ":" + strconv.Itoa(ConstWellknownPort)
+               err = executeRemoteEnv(appInfo, target)
+       }
+
+       return
+}
+
+// Run is trigger point executing binary
+func Run(distService map[string]interface{}) {
+       var serviceID uint64
+
+       switch distService[ConstKeyServiceID].(type) {
+       case uint64:
+               serviceID = distService[ConstKeyServiceID].(uint64)
+       case float64:
+               serviceID = uint64(distService[ConstKeyServiceID].(float64))
+       }
+
+       serviceName := distService[ConstKeyServiceName].(string)
+
+       var args []string
+       userArgs := distService[ConstKeyUserArgs]
+
+       if userArgs != nil {
+               switch userArgs.(type) {
+               case []string:
+                       for _, param := range userArgs.([]string) {
+                               args = append(args, param)
+                       }
+               case []interface{}:
+                       args = make([]string, len(userArgs.([]interface{})))
+                       for _, param := range userArgs.([]interface{}) {
+                               args = append(args, fmt.Sprint(param))
+                       }
+               }
+       } else {
+               args = nil
+       }
+       notificationTargetURL := distService[ConstKeyNotiTargetURL].(string)
+
+       service := Service{serviceID, serviceName, args, notificationTargetURL}
+
+       service.execute()
+}
+
+// HandleNoti is for handling notificiation from servie
+func HandleNoti(statusNoti map[string]interface{}) (err error) {
+       var serviceID uint64
+       switch statusNoti[ConstKeyServiceID].(type) {
+       case uint64:
+               serviceID = statusNoti[ConstKeyServiceID].(uint64)
+       case float64:
+               serviceID = uint64(statusNoti[ConstKeyServiceID].(float64))
+       }
+
+       notiChan, _ := getNotiChan(serviceID)
+
+       if notiChan == nil {
+               return
+       }
+
+       notiChan <- statusNoti[ConstKeyStatus].(string)
+       ServiceMap.Remove(serviceID)
+
+       return
+}
+
+func checkError(err error) bool {
+       if err != nil {
+               log.Println(err.Error())
+               return true
+       }
+       return false
+}
+
+func getOutboundIP() string {
+       conn, err := net.Dial("udp", "8.8.8.8:80")
+       if err != nil {
+               log.Fatal(err)
+       }
+       defer conn.Close()
+
+       localAddr := conn.LocalAddr().(*net.UDPAddr)
+
+       return localAddr.IP.String()
+}
+
+func executeLocalEnv(appInfo map[string]interface{}) (err error) {
+       //  check execution validation
+       _, err = exec.LookPath(appInfo[ConstKeyServiceName].(string))
+
+       if checkError(err) == false {
+               go Run(appInfo)
+       }
+
+       return
+}
+
+func executeRemoteEnv(appInfo map[string]interface{}, target string) (err error) {
+       reqBytes, _ := json.Marshal(appInfo)
+       executeTarget := target + ":" + strconv.Itoa(ConstWellknownPort) + ConstServiceExecuteURI
+
+       str, err := sendPostJSONMsg(executeTarget, reqBytes)
+
+       if err == nil {
+               if str == ConstServiceStatusFailed {
+                       err = errors.New("Failed")
+               }
+       }
+
+       return
+}
diff --git a/src/servicemgr/servicemgr_test.go b/src/servicemgr/servicemgr_test.go
new file mode 100644 (file)
index 0000000..c01c21f
--- /dev/null
@@ -0,0 +1,88 @@
+package servicemgr
+
+import (
+       "strings"
+       "testing"
+       "time"
+)
+
+var (
+       // targetRemoteDeviceAddr = "10.113.175.144"
+       targetLocalAddr = getOutboundIP()
+       serviceID       uint64
+)
+
+const (
+       serviceName  = "ls"
+       serviceName2 = "main2"
+)
+
+func init() {
+       InitServiceMap()
+}
+
+func retError(t *testing.T, err error) {
+       t.Helper()
+
+       if err != nil {
+               t.Error(err.Error())
+       }
+}
+
+func TestExecuteApp(t *testing.T) {
+       notiChan := make(chan string)
+
+       _, err := ExecuteApp(targetLocalAddr, serviceName, nil, notiChan)
+       retError(t, err)
+
+       time.Sleep(time.Millisecond * 10)
+}
+
+func TestExecuteAppWithArgs(t *testing.T) {
+       notiChan := make(chan string)
+
+       args := []string{"-ail"}
+       _, err := ExecuteApp(targetLocalAddr, serviceName, args, notiChan)
+       retError(t, err)
+
+       time.Sleep(time.Millisecond * 10)
+}
+
+func TestHandleNoti(t *testing.T) {
+       notiChan := make(chan string, 1)
+
+       id, err := ExecuteApp(targetLocalAddr, serviceName, nil, notiChan)
+       retError(t, err)
+
+       statusNotificationRequest := make(map[string]interface{})
+       statusNotificationRequest["ServiceID"] = id
+       statusNotificationRequest["Status"] = ConstServiceStatusFinished
+
+       HandleNoti(statusNotificationRequest)
+
+       select {
+       case str := <-notiChan:
+               t.Log(str)
+               if strings.Compare(ConstServiceStatusFinished, str) != 0 {
+                       t.Error()
+               }
+       }
+}
+
+// @ System Test
+// func systemtestExecuteRemoteApp(t *testing.T) {
+//     _, err := ExecuteApp(ConstPrefixHTTP+targetRemoteDeviceAddr, serviceName, nil, nil)
+//     retError(t, err)
+
+//     time.Sleep(time.Millisecond * 10)
+// }
+
+// func systemtestExecuteRemoteAppFailed(t *testing.T) {
+//     _, err := ExecuteApp(ConstPrefixHTTP+targetRemoteDeviceAddr, "main", nil, nil)
+
+//     if err.Error() != "Failed" {
+//             t.Error()
+//     }
+
+//     time.Sleep(time.Millisecond * 10)
+// }