qconf.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. package qconf
  2. //#cgo LDFLAGS: -L/usr/local/qconf/lib/ -lm
  3. /*
  4. #cgo LDFLAGS: -lqconf -lm
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. struct string_vector
  8. {
  9. int count; // the number of services
  10. char **data; // the array of services
  11. };
  12. typedef struct string_vector string_vector_t;
  13. typedef struct qconf_node
  14. {
  15. char *key;
  16. char *value;
  17. } qconf_node;
  18. typedef struct qconf_batch_nodes
  19. {
  20. int count;
  21. qconf_node *nodes;
  22. } qconf_batch_nodes;
  23. int qconf_init();
  24. int qconf_destroy();
  25. int init_string_vector(string_vector_t *nodes);
  26. int destroy_string_vector(string_vector_t *nodes);
  27. int init_qconf_batch_nodes(qconf_batch_nodes *bnodes);
  28. int destroy_qconf_batch_nodes(qconf_batch_nodes *bnodes);
  29. int qconf_get_conf(const char *path, char *buf, int buf_len, const char *idc);
  30. int qconf_get_allhost(const char *path, string_vector_t *nodes, const char *idc);
  31. int qconf_get_host(const char *path, char *buf, int buf_len, const char *idc);
  32. int qconf_get_batch_conf(const char *path, qconf_batch_nodes *bnodes, const char *idc);
  33. int qconf_get_batch_keys(const char *path, string_vector_t *nodes, const char *idc);
  34. */
  35. import "C"
  36. import (
  37. "errors"
  38. "fmt"
  39. "reflect"
  40. "unsafe"
  41. )
  42. type Errno int
  43. func (e Errno) Error() string {
  44. s := errText[e]
  45. if s == "" {
  46. return fmt.Sprintf("unknown errno %d", int(e))
  47. }
  48. return s
  49. }
  50. var errText = map[Errno]string{
  51. -1: "Execute failure!",
  52. 1: "Error parameter!",
  53. 2: "Failed to malloc memory!",
  54. 3: "Failed to set share memory!",
  55. 4: "Failed to get zookeeper host!",
  56. 5: "Failed to get idc!",
  57. 6: "Buffer not enough!",
  58. 7: "Illegal data type!",
  59. 8: "Illegal data format!",
  60. 10: "Failed to find key on given idc!",
  61. 11: "Failed to open dump file!",
  62. 12: "Failed to open tmp dump file!",
  63. 13: "Failed to find key in dump!",
  64. 14: "Failed to rename dump!",
  65. 15: "Failed to write dump!",
  66. 16: "Same with the value in share memory!",
  67. 20: "Configure item error : out of range!",
  68. 21: "Configure item error : not number!",
  69. 22: "Configure item error : further characters exists!",
  70. 30: "Configure item error : invalid ip!",
  71. 31: "Configure item error : invalid port!",
  72. 40: "No message exist in message queue!",
  73. 41: "Length of message in the queue is too large!",
  74. 71: "Error hostname!",
  75. }
  76. var (
  77. ErrOther error = Errno(-1)
  78. ErrQconfParam error = Errno(1)
  79. ErrQconfMem error = Errno(2)
  80. ErrQconfTblSet error = Errno(3)
  81. ErrQconfGetHost error = Errno(4)
  82. ErrQconfGetIdc error = Errno(5)
  83. ErrQconfBufNotEnough error = Errno(6)
  84. ErrQconfDataType error = Errno(7)
  85. ErrQconfDataFormat error = Errno(8)
  86. ErrQconfNotFound error = Errno(10)
  87. ErrQconfOpenDump error = Errno(11)
  88. ErrQconfOpenTmpDump error = Errno(12)
  89. ErrQconfNotInDump error = Errno(13)
  90. ErrQconfRenameDump error = Errno(14)
  91. ErrQconfWriteDump error = Errno(15)
  92. ErrQconfSameValue error = Errno(16)
  93. ErrQconfOutOfRange error = Errno(20)
  94. ErrQconfNotNumber error = Errno(21)
  95. ErrQconfOtherCharacter error = Errno(22)
  96. ErrQconfInvalidIp error = Errno(30)
  97. ErrQconfInvalidPort error = Errno(31)
  98. ErrQconfNoMessage error = Errno(40)
  99. ErrQconfE2Big error = Errno(41)
  100. ErrQconfHostname error = Errno(71)
  101. )
  102. const (
  103. QCONF_DRIVER_GO_VERSION = "1.2.1"
  104. QCONF_CONF_BUF_INIT_MAX_LEN = 2 * 1024
  105. QCONF_CONF_BUF_MAX_LEN = 1024 * 1024
  106. QCONF_CONF_BUF_MULTIPLE = 8
  107. QCONF_HOST_BUF_MAX_LEN = 256
  108. QCONF_OK = 0
  109. QCONF_ERR_BUF_NOT_ENOUGH = 6
  110. )
  111. //func init(){
  112. // ret := C.qconf_init()
  113. // if QCONF_OK != ret {
  114. // panic(ret)
  115. // }
  116. //}
  117. func initQconf() error {
  118. ret := C.qconf_init()
  119. if QCONF_OK != ret {
  120. return errors.New(fmt.Sprintf("%v", ret))
  121. }
  122. return nil
  123. }
  124. func convertToGoSlice(nodes *C.string_vector_t) []string {
  125. length := int((*nodes).count)
  126. hdr := reflect.SliceHeader{
  127. Data: uintptr(unsafe.Pointer((*nodes).data)),
  128. Len: length,
  129. Cap: length,
  130. }
  131. charp_nodes := *(*[]*C.char)(unsafe.Pointer(&hdr))
  132. go_nodes := []string{}
  133. for i := 0; i < length; i++ {
  134. go_host := C.GoString(charp_nodes[i])
  135. go_nodes = append(go_nodes, go_host)
  136. }
  137. return go_nodes
  138. }
  139. func convertToGoMap(bnodes *C.qconf_batch_nodes) map[string]string {
  140. length := int((*bnodes).count)
  141. hdr := reflect.SliceHeader{
  142. Data: uintptr(unsafe.Pointer((*bnodes).nodes)),
  143. Len: length,
  144. Cap: length,
  145. }
  146. qconf_nodes := *(*[]C.qconf_node)(unsafe.Pointer(&hdr))
  147. go_nodes := map[string]string{}
  148. for i := 0; i < length; i++ {
  149. go_key := C.GoString(qconf_nodes[i].key)
  150. go_value := C.GoString(qconf_nodes[i].value)
  151. go_nodes[go_key] = go_value
  152. }
  153. return go_nodes
  154. }
  155. func GetConf(key string, idc string) (string, error) {
  156. c_key := C.CString(key)
  157. defer C.free(unsafe.Pointer(c_key))
  158. var ret int
  159. var c_ptr_value *C.char
  160. slice_length := QCONF_CONF_BUF_INIT_MAX_LEN
  161. for ret = QCONF_ERR_BUF_NOT_ENOUGH; ret == QCONF_ERR_BUF_NOT_ENOUGH && slice_length <= QCONF_CONF_BUF_MAX_LEN; slice_length *= QCONF_CONF_BUF_MULTIPLE {
  162. c_value := make([]C.char, slice_length)
  163. c_ptr_value = (*C.char)(unsafe.Pointer(&(c_value[0])))
  164. if idc == "" {
  165. ret = int(C.qconf_get_conf(c_key, c_ptr_value, C.int(slice_length), nil))
  166. } else {
  167. c_idc := C.CString(idc)
  168. defer C.free(unsafe.Pointer(c_idc))
  169. ret = int(C.qconf_get_conf(c_key, c_ptr_value, C.int(slice_length), c_idc))
  170. }
  171. }
  172. if QCONF_OK != ret {
  173. cur_err := Errno(ret)
  174. return "", cur_err
  175. }
  176. go_value := C.GoString(c_ptr_value)
  177. return go_value, nil
  178. }
  179. func GetHost(key string, idc string) (string, error) {
  180. c_key := C.CString(key)
  181. defer C.free(unsafe.Pointer(c_key))
  182. var c_host [QCONF_HOST_BUF_MAX_LEN]C.char
  183. c_ptr_host := (*C.char)(unsafe.Pointer(&(c_host[0])))
  184. var ret int
  185. if idc == "" {
  186. ret = int(C.qconf_get_host(c_key, c_ptr_host, QCONF_HOST_BUF_MAX_LEN, nil))
  187. } else {
  188. c_idc := C.CString(idc)
  189. defer C.free(unsafe.Pointer(c_idc))
  190. ret = int(C.qconf_get_host(c_key, c_ptr_host, QCONF_HOST_BUF_MAX_LEN, c_idc))
  191. }
  192. if QCONF_OK != ret {
  193. cur_err := Errno(ret)
  194. return "", cur_err
  195. }
  196. go_host := C.GoString(c_ptr_host)
  197. return go_host, nil
  198. }
  199. func GetAllHost(key string, idc string) ([]string, error) {
  200. c_key := C.CString(key)
  201. defer C.free(unsafe.Pointer(c_key))
  202. var nodes C.string_vector_t
  203. init_ret := C.init_string_vector(&nodes)
  204. if QCONF_OK != init_ret {
  205. cur_err := Errno(init_ret)
  206. return nil, cur_err
  207. }
  208. defer C.destroy_string_vector(&nodes)
  209. var ret int
  210. if idc == "" {
  211. ret = int(C.qconf_get_allhost(c_key, &nodes, nil))
  212. } else {
  213. c_idc := C.CString(idc)
  214. defer C.free(unsafe.Pointer(c_idc))
  215. ret = int(C.qconf_get_allhost(c_key, &nodes, c_idc))
  216. }
  217. if QCONF_OK != ret {
  218. cur_err := Errno(ret)
  219. return nil, cur_err
  220. }
  221. go_nodes := convertToGoSlice(&nodes)
  222. return go_nodes, nil
  223. }
  224. func GetBatchConf(key string, idc string) (map[string]string, error) {
  225. c_key := C.CString(key)
  226. defer C.free(unsafe.Pointer(c_key))
  227. var bnodes C.qconf_batch_nodes
  228. init_ret := C.init_qconf_batch_nodes(&bnodes)
  229. if QCONF_OK != init_ret {
  230. cur_err := Errno(init_ret)
  231. return nil, cur_err
  232. }
  233. defer C.destroy_qconf_batch_nodes(&bnodes)
  234. var ret int
  235. if idc == "" {
  236. ret = int(C.qconf_get_batch_conf(c_key, &bnodes, nil))
  237. } else {
  238. c_idc := C.CString(idc)
  239. defer C.free(unsafe.Pointer(c_idc))
  240. ret = int(C.qconf_get_batch_conf(c_key, &bnodes, c_idc))
  241. }
  242. if QCONF_OK != ret {
  243. cur_err := Errno(ret)
  244. return nil, cur_err
  245. }
  246. go_nodes := convertToGoMap(&bnodes)
  247. return go_nodes, nil
  248. }
  249. func GetBatchKeys(key string, idc string) ([]string, error) {
  250. c_key := C.CString(key)
  251. defer C.free(unsafe.Pointer(c_key))
  252. var nodes C.string_vector_t
  253. init_ret := C.init_string_vector(&nodes)
  254. if QCONF_OK != init_ret {
  255. cur_err := Errno(init_ret)
  256. return nil, cur_err
  257. }
  258. defer C.destroy_string_vector(&nodes)
  259. var ret int
  260. if idc == "" {
  261. ret = int(C.qconf_get_batch_keys(c_key, &nodes, nil))
  262. } else {
  263. c_idc := C.CString(idc)
  264. defer C.free(unsafe.Pointer(c_idc))
  265. ret = int(C.qconf_get_batch_keys(c_key, &nodes, c_idc))
  266. }
  267. if QCONF_OK != ret {
  268. cur_err := Errno(ret)
  269. return nil, cur_err
  270. }
  271. go_nodes := convertToGoSlice(&nodes)
  272. return go_nodes, nil
  273. }
  274. func Version() (string, error) {
  275. return QCONF_DRIVER_GO_VERSION, nil
  276. }