This repository has been archived by the owner on Nov 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
util.go
184 lines (164 loc) · 4.64 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package gophercloud
import (
"fmt"
"net/url"
"path/filepath"
"reflect"
"strconv"
"strings"
"time"
"runtime"
"path"
)
// WaitFor polls a predicate function, once per second, up to a timeout limit.
// This is useful to wait for a resource to transition to a certain state.
// To handle situations when the predicate might hang indefinitely, the
// predicate will be prematurely cancelled after the timeout.
// Resource packages will wrap this in a more convenient function that's
// specific to a certain resource, but it can also be useful on its own.
func WaitFor(timeout int, predicate func() (bool, error)) error {
type WaitForResult struct {
Success bool
Error error
}
start := time.Now().Unix()
for {
// If a timeout is set, and that's been exceeded, shut it down.
if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) {
return fmt.Errorf("A timeout occurred")
}
time.Sleep(1 * time.Second)
var result WaitForResult
ch := make(chan bool, 1)
go func() {
defer close(ch)
satisfied, err := predicate()
result.Success = satisfied
result.Error = err
}()
select {
case <-ch:
if result.Error != nil {
return result.Error
}
if result.Success {
return nil
}
// If the predicate has not finished by the timeout, cancel it.
case <-time.After(time.Duration(timeout) * time.Second):
return fmt.Errorf("A timeout occurred")
}
}
}
// NormalizeURL is an internal function to be used by provider clients.
//
// It ensures that each endpoint URL has a closing `/`, as expected by
// ServiceClient's methods.
func NormalizeURL(url string) string {
if !strings.HasSuffix(url, "/") {
return url + "/"
}
return url
}
// NormalizePathURL is used to convert rawPath to a fqdn, using basePath as
// a reference in the filesystem, if necessary. basePath is assumed to contain
// either '.' when first used, or the file:// type fqdn of the parent resource.
// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml
func NormalizePathURL(basePath, rawPath string) (string, error) {
u, err := url.Parse(rawPath)
if err != nil {
return "", err
}
// if a scheme is defined, it must be a fqdn already
if u.Scheme != "" {
return u.String(), nil
}
// if basePath is a url, then child resources are assumed to be relative to it
bu, err := url.Parse(basePath)
if err != nil {
return "", err
}
var basePathSys, absPathSys string
if bu.Scheme != "" {
basePathSys = filepath.FromSlash(bu.Path)
absPathSys = filepath.Join(basePathSys, rawPath)
bu.Path = filepath.ToSlash(absPathSys)
return bu.String(), nil
}
absPathSys = filepath.Join(basePath, rawPath)
u.Path = filepath.ToSlash(absPathSys)
if err != nil {
return "", err
}
u.Scheme = "file"
return u.String(), nil
}
// InitStructWithDefaultTag,Initialize the structure instance using the structure tag.
func InitStructWithDefaultTag(bean interface{}) {
configType := reflect.TypeOf(bean)
for i := 0; i < configType.Elem().NumField(); i++ {
field := configType.Elem().Field(i)
defaultValue := field.Tag.Get("default")
if defaultValue == "" {
continue
}
setter := reflect.ValueOf(bean).Elem().Field(i)
switch field.Type.String() {
case "int":
intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intValue)
case "time.Duration":
intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intValue)
case "string":
setter.SetString(defaultValue)
case "bool":
boolValue, _ := strconv.ParseBool(defaultValue)
setter.SetBool(boolValue)
}
}
}
// IsInStrSlice, Determine if the string is in the array.
func IsInStrSlice(sliceStr []string, s string) bool {
for _, v := range sliceStr {
if v == s {
return true
}
}
return false
}
// EnableDebug, SDK log switch defaults value is false.
var EnableDebug bool
// Logger, define the logger struct.
type Logger struct {
DebugEnable bool `default:"false"`
}
// Debug, Format the log information and print the information to the console.
func (log *Logger) Debug(format string, v ...interface{}) {
if log.DebugEnable {
msg := fmt.Sprintf("[DEBUG] "+format, v...)
writeMsg(msg)
}
}
func writeMsg(msg string) {
_, file, line, ok := runtime.Caller(2)
if !ok {
file = "???"
line = 0
}
_, filename := path.Split(file)
msg = fmt.Sprintf("[%s:%s] %s", filename, strconv.FormatInt(int64(line), 10), msg)
printMsg(msg)
}
//printMsg
func printMsg(msg string) {
when := time.Now().Format("2006-01-02 15:04:05")
buf := []byte(fmt.Sprintf("[%s] ", when))
fmt.Println(string(append(append(buf, msg...))))
}
// GetLogger ,Return log initialization structure instance.
func GetLogger() (*Logger) {
log := new(Logger)
log.DebugEnable = EnableDebug
return log
}