service.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package main
  2. import (
  3. "context"
  4. "crypto/md5"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "os"
  11. "os/signal"
  12. "strconv"
  13. "strings"
  14. "time"
  15. api "github.com/willie68/schematic-service-go/api"
  16. "github.com/willie68/schematic-service-go/health"
  17. "github.com/willie68/schematic-service-go/internal/crypt"
  18. consulApi "github.com/hashicorp/consul/api"
  19. config "github.com/willie68/schematic-service-go/config"
  20. "github.com/willie68/schematic-service-go/logging"
  21. "github.com/willie68/schematic-service-go/model"
  22. "github.com/go-chi/chi"
  23. "github.com/go-chi/chi/middleware"
  24. "github.com/go-chi/render"
  25. flag "github.com/spf13/pflag"
  26. )
  27. /*
  28. apiVersion implementing api version for this service
  29. */
  30. const apiVersion = "1"
  31. const servicename = "gomicro"
  32. var port int
  33. var sslport int
  34. var system string
  35. var serviceURL string
  36. var registryURL string
  37. var apikey string
  38. var ssl bool
  39. var configFile string
  40. var serviceConfig config.Config
  41. var consulAgent *consulApi.Agent
  42. var log logging.ServiceLogger
  43. func init() {
  44. // variables for parameter override
  45. ssl = false
  46. log.Info("init service")
  47. flag.IntVarP(&port, "port", "p", 0, "port of the http server.")
  48. flag.IntVarP(&sslport, "sslport", "t", 0, "port of the https server.")
  49. flag.StringVarP(&system, "systemid", "s", "", "this is the systemid of this service. Used for the apikey generation")
  50. flag.StringVarP(&configFile, "config", "c", config.File, "this is the path and filename to the config file")
  51. flag.StringVarP(&serviceURL, "serviceURL", "u", "", "service url from outside")
  52. flag.StringVarP(&registryURL, "registryURL", "r", "", "registry url where to connect to consul")
  53. }
  54. func routes() *chi.Mux {
  55. myHandler := api.NewSysAPIHandler(serviceConfig.SystemID, apikey)
  56. baseURL := fmt.Sprintf("/api/v%s", apiVersion)
  57. router := chi.NewRouter()
  58. router.Use(
  59. render.SetContentType(render.ContentTypeJSON),
  60. middleware.Logger,
  61. middleware.DefaultCompress,
  62. middleware.Recoverer,
  63. myHandler.Handler,
  64. )
  65. router.Route("/", func(r chi.Router) {
  66. r.Mount(baseURL+"/config", api.ConfigRoutes())
  67. r.Mount("/health", health.Routes())
  68. })
  69. return router
  70. }
  71. func healthRoutes() *chi.Mux {
  72. router := chi.NewRouter()
  73. router.Use(
  74. render.SetContentType(render.ContentTypeJSON),
  75. middleware.Logger,
  76. middleware.DefaultCompress,
  77. middleware.Recoverer,
  78. )
  79. router.Route("/", func(r chi.Router) {
  80. r.Mount("/health", health.Routes())
  81. })
  82. return router
  83. }
  84. func main() {
  85. log.Info("starting server")
  86. flag.Parse()
  87. config.File = configFile
  88. if err := config.Load(); err != nil {
  89. log.Alertf("can't load config file: %s", err.Error())
  90. }
  91. serviceConfig = config.Get()
  92. initConfig()
  93. initGraylog()
  94. healthCheckConfig := health.CheckConfig(serviceConfig.HealthCheck)
  95. health.InitHealthSystem(healthCheckConfig)
  96. defer log.Close()
  97. if serviceConfig.SystemID == "" {
  98. log.Fatal("system id not given, can't start! Please use config file or -s parameter")
  99. }
  100. gc := crypt.GenerateCertificate{
  101. Organization: "MCS Media Computer Spftware",
  102. Host: "127.0.0.1",
  103. ValidFor: 10 * 365 * 24 * time.Hour,
  104. IsCA: false,
  105. EcdsaCurve: "P256",
  106. Ed25519Key: true,
  107. }
  108. if serviceConfig.Sslport > 0 {
  109. ssl = true
  110. log.Info("ssl active")
  111. }
  112. importData()
  113. api.SystemID = serviceConfig.SystemID
  114. apikey = getApikey()
  115. api.APIKey = apikey
  116. log.Infof("systemid: %s", serviceConfig.SystemID)
  117. log.Infof("apikey: %s", apikey)
  118. log.Infof("ssl: %t", ssl)
  119. log.Infof("serviceURL: %s", serviceConfig.ServiceURL)
  120. if serviceConfig.RegistryURL != "" {
  121. log.Infof("registryURL: %s", serviceConfig.RegistryURL)
  122. }
  123. router := routes()
  124. walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
  125. log.Infof("%s %s", method, route)
  126. return nil
  127. }
  128. if err := chi.Walk(router, walkFunc); err != nil {
  129. log.Alertf("Logging err: %s", err.Error())
  130. }
  131. log.Info("Health routes")
  132. healthRouter := healthRoutes()
  133. if err := chi.Walk(healthRouter, walkFunc); err != nil {
  134. log.Alertf("Logging err: %s", err.Error())
  135. }
  136. var sslsrv *http.Server
  137. if ssl {
  138. tlsConfig, err := gc.GenerateTLSConfig()
  139. if err != nil {
  140. log.Alertf("logging err: %s", err.Error())
  141. }
  142. sslsrv = &http.Server{
  143. Addr: "0.0.0.0:" + strconv.Itoa(serviceConfig.Sslport),
  144. WriteTimeout: time.Second * 15,
  145. ReadTimeout: time.Second * 15,
  146. IdleTimeout: time.Second * 60,
  147. Handler: router,
  148. TLSConfig: tlsConfig,
  149. }
  150. go func() {
  151. log.Infof("starting https server on address: %s", sslsrv.Addr)
  152. if err := sslsrv.ListenAndServeTLS("", ""); err != nil {
  153. log.Alertf("error starting server: %s", err.Error())
  154. }
  155. }()
  156. }
  157. // own http server for the healthchecks
  158. srv := &http.Server{
  159. Addr: "0.0.0.0:" + strconv.Itoa(serviceConfig.Port),
  160. WriteTimeout: time.Second * 15,
  161. ReadTimeout: time.Second * 15,
  162. IdleTimeout: time.Second * 60,
  163. Handler: healthRouter,
  164. }
  165. go func() {
  166. log.Infof("starting http server on address: %s", srv.Addr)
  167. if err := srv.ListenAndServe(); err != nil {
  168. log.Alertf("error starting server: %s", err.Error())
  169. }
  170. }()
  171. if serviceConfig.RegistryURL != "" {
  172. initRegistry()
  173. }
  174. c := make(chan os.Signal, 1)
  175. signal.Notify(c, os.Interrupt)
  176. <-c
  177. log.Info("waiting for clients")
  178. ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
  179. defer cancel()
  180. srv.Shutdown(ctx)
  181. if ssl {
  182. sslsrv.Shutdown(ctx)
  183. }
  184. log.Info("finished")
  185. os.Exit(0)
  186. }
  187. func initGraylog() {
  188. log.GelfURL = serviceConfig.Logging.Gelfurl
  189. log.GelfPort = serviceConfig.Logging.Gelfport
  190. log.SystemID = serviceConfig.SystemID
  191. log.InitGelf()
  192. }
  193. func initRegistry() {
  194. //register to consul, if configured
  195. consulConfig := consulApi.DefaultConfig()
  196. consulURL, err := url.Parse(serviceConfig.RegistryURL)
  197. consulConfig.Scheme = consulURL.Scheme
  198. consulConfig.Address = fmt.Sprintf("%s:%s", consulURL.Hostname(), consulURL.Port())
  199. consulClient, err := consulApi.NewClient(consulConfig)
  200. if err != nil {
  201. log.Alertf("can't connect to consul. %v", err)
  202. }
  203. consulAgent = consulClient.Agent()
  204. check := new(consulApi.AgentServiceCheck)
  205. check.HTTP = fmt.Sprintf("%s/health/health", serviceConfig.ServiceURL)
  206. check.Timeout = (time.Minute * 1).String()
  207. check.Interval = (time.Second * 30).String()
  208. check.TLSSkipVerify = true
  209. serviceDef := &consulApi.AgentServiceRegistration{
  210. Name: servicename,
  211. Check: check,
  212. }
  213. err = consulAgent.ServiceRegister(serviceDef)
  214. if err != nil {
  215. log.Alertf("can't register to consul. %s", err)
  216. time.Sleep(time.Second * 60)
  217. }
  218. }
  219. func initConfig() {
  220. if port > 0 {
  221. serviceConfig.Port = port
  222. }
  223. if sslport > 0 {
  224. serviceConfig.Sslport = sslport
  225. }
  226. if system != "" {
  227. serviceConfig.SystemID = system
  228. }
  229. if serviceURL != "" {
  230. serviceConfig.ServiceURL = serviceURL
  231. }
  232. }
  233. func getApikey() string {
  234. value := fmt.Sprintf("%s_%s", servicename, serviceConfig.SystemID)
  235. apikey := fmt.Sprintf("%x", md5.Sum([]byte(value)))
  236. return strings.ToLower(apikey)
  237. }
  238. func importData() {
  239. jsonFile, err := os.Open("Y:/temp/backup/schematic/LIVE/5a9fee1e355aa72fe619e54c/schematic.json")
  240. // if we os.Open returns an error then handle it
  241. if err != nil {
  242. fmt.Println(err)
  243. }
  244. fmt.Println("Successfully Opened users.json")
  245. // defer the closing of our jsonFile so that we can parse it later on
  246. defer jsonFile.Close()
  247. byteValue, _ := ioutil.ReadAll(jsonFile)
  248. fmt.Println(string(byteValue))
  249. var schematic model.Schematic
  250. err = json.Unmarshal(byteValue, &schematic)
  251. if err != nil {
  252. fmt.Printf("%v", err)
  253. }
  254. fmt.Println("*****")
  255. data, err := json.Marshal(schematic)
  256. if err != nil {
  257. fmt.Printf("%v", err)
  258. }
  259. fmt.Println(string(data))
  260. fmt.Println("*****")
  261. panic(1)
  262. }