func runServer(neoURL string, port string, cacheDuration string, env string) { if duration, durationErr := time.ParseDuration(cacheDuration); durationErr != nil { log.Fatalf("Failed to parse cache duration string, %v", durationErr) } else { organisations.CacheControlHeader = fmt.Sprintf("max-age=%s, public", strconv.FormatFloat(duration.Seconds(), 'f', 0, 64)) } conf := neoutils.ConnectionConfig{ BatchSize: 1024, Transactional: false, HTTPClient: &http.Client{ Transport: &http.Transport{ MaxIdleConnsPerHost: 100, }, Timeout: 1 * time.Minute, }, BackgroundConnect: true, } db, err := neoutils.Connect(neoURL, &conf) if err != nil { log.Fatalf("Error connecting to neo4j %s", err) } organisations.OrganisationDriver = organisations.NewCypherDriver(db, env) servicesRouter := mux.NewRouter() // Healthchecks and standards first servicesRouter.HandleFunc("/__health", v1a.Handler("PublicOrganisationsRead Healthchecks", "Checks for accessing neo4j", organisations.HealthCheck())) servicesRouter.HandleFunc("/__gtg", organisations.GoodToGo) // Then API specific ones: servicesRouter.HandleFunc("/organisations/{uuid}", organisations.GetOrganisation).Methods("GET") servicesRouter.HandleFunc("/organisations/{uuid}", organisations.MethodNotAllowedHandler) var monitoringRouter http.Handler = servicesRouter monitoringRouter = httphandlers.TransactionAwareRequestLoggingHandler(log.StandardLogger(), monitoringRouter) monitoringRouter = httphandlers.HTTPMetricsHandler(metrics.DefaultRegistry, monitoringRouter) // The following endpoints should not be monitored or logged (varnish calls one of these every second, depending on config) // The top one of these build info endpoints feels more correct, but the lower one matches what we have in Dropwizard, // so it's what apps expect currently same as ping, the content of build-info needs more definition //using http router here to be able to catch "/" http.HandleFunc(status.PingPath, status.PingHandler) http.HandleFunc(status.PingPathDW, status.PingHandler) http.HandleFunc(status.BuildInfoPath, status.BuildInfoHandler) http.HandleFunc(status.BuildInfoPathDW, status.BuildInfoHandler) http.HandleFunc("/__gtg", organisations.GoodToGo) http.Handle("/", monitoringRouter) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatalf("Unable to start server: %v", err) } }
func RunServerWithConf(conf RWConf) { for path, service := range conf.Services { err := service.Initialise() if err != nil { log.Fatalf("Service for path %s could not startup, err=%s", path, err) } } if conf.Env != "local" { f, err := os.OpenFile("/var/log/apps/"+conf.ServiceName+"-go-app.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err == nil { log.SetOutput(f) log.SetFormatter(&log.TextFormatter{DisableColors: true}) } else { log.Fatalf("Failed to initialise log file, %v", err) } defer f.Close() } var m http.Handler m = router(conf.Services, conf.HealthHandler) if conf.EnableReqLog { m = httphandlers.TransactionAwareRequestLoggingHandler(log.StandardLogger(), m) } m = httphandlers.HTTPMetricsHandler(metrics.DefaultRegistry, m) http.Handle("/", m) log.Printf("listening on %d", conf.Port) log.Println(http.ListenAndServe(fmt.Sprintf(":%d", conf.Port), nil).Error()) log.Printf("exiting on %s", conf.ServiceName) }
func setupServiceHandler(sc ServiceConfig, metricsHandler Metrics, contentHandler ContentHandler) *mux.Router { r := mux.NewRouter() r.Path("/content-preview/{uuid}").Handler(handlers.MethodHandler{"GET": oldhttphandlers.HTTPMetricsHandler(metricsHandler.registry, oldhttphandlers.TransactionAwareRequestLoggingHandler(logrus.StandardLogger(), contentHandler))}) r.Path(httphandlers.BuildInfoPath).HandlerFunc(httphandlers.BuildInfoHandler) r.Path(httphandlers.PingPath).HandlerFunc(httphandlers.PingHandler) r.Path("/__health").Handler(handlers.MethodHandler{"GET": http.HandlerFunc(fthealth.Handler(sc.serviceName, serviceDescription, sc.nativeContentSourceCheck(), sc.transformerServiceCheck()))}) r.Path("/__metrics").Handler(handlers.MethodHandler{"GET": http.HandlerFunc(metricsHttpEndpoint)}) return r }
func router(hh httpHandlers) http.Handler { servicesRouter := mux.NewRouter() servicesRouter.Headers("Content-type: application/json") // Then API specific ones: servicesRouter.HandleFunc("/content/{uuid}/annotations", hh.GetAnnotations).Methods("GET") servicesRouter.HandleFunc("/content/{uuid}/annotations", hh.PutAnnotations).Methods("PUT") servicesRouter.HandleFunc("/content/{uuid}/annotations", hh.DeleteAnnotations).Methods("DELETE") servicesRouter.HandleFunc("/content/annotations/__count", hh.CountAnnotations).Methods("GET") var monitoringRouter http.Handler = servicesRouter monitoringRouter = httphandlers.TransactionAwareRequestLoggingHandler(log.StandardLogger(), monitoringRouter) monitoringRouter = httphandlers.HTTPMetricsHandler(metrics.DefaultRegistry, monitoringRouter) return monitoringRouter }
func main() { app := cli.App("curated-authors-transformer", "A RESTful API for transforming Bertha Curated Authors to UP People JSON") port := app.Int(cli.IntOpt{ Name: "port", Value: 8080, Desc: "Port to listen on", EnvVar: "PORT", }) berthaSrcUrl := app.String(cli.StringOpt{ Name: "bertha-source-url", Value: "{url}", Desc: "The URL of the Bertha Authors JSON source", EnvVar: "BERTHA_SOURCE_URL", }) app.Action = func() { log.Info("App started!!!") bs, err := newBerthaService(*berthaSrcUrl) if err != nil { log.Error(err) panic(err) } ah := newAuthorHandler(bs) h := setupServiceHandlers(ah) http.Handle("/", httphandlers.HTTPMetricsHandler(metrics.DefaultRegistry, httphandlers.TransactionAwareRequestLoggingHandler(log.StandardLogger(), h))) log.Infof("Listening on [%d].\n", *port) errServe := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil) if errServe != nil { log.Printf("Web server failed: [%v].\n", errServe) } } app.Run(os.Args) }
func main() { app := cli.App("subjects-transformer", "A RESTful API for transforming TME Subjects to UP json") username := app.String(cli.StringOpt{ Name: "tme-username", Value: "", Desc: "TME username used for http basic authentication", EnvVar: "TME_USERNAME", }) password := app.String(cli.StringOpt{ Name: "tme-password", Value: "", Desc: "TME password used for http basic authentication", EnvVar: "TME_PASSWORD", }) token := app.String(cli.StringOpt{ Name: "token", Value: "", Desc: "Token to be used for accessing TME", EnvVar: "TOKEN", }) baseURL := app.String(cli.StringOpt{ Name: "base-url", Value: "http://localhost:8080/transformers/subjects/", Desc: "Base url", EnvVar: "BASE_URL", }) tmeBaseURL := app.String(cli.StringOpt{ Name: "tme-base-url", Value: "https://tme.ft.com", Desc: "TME base url", EnvVar: "TME_BASE_URL", }) port := app.Int(cli.IntOpt{ Name: "port", Value: 8080, Desc: "Port to listen on", EnvVar: "PORT", }) maxRecords := app.Int(cli.IntOpt{ Name: "maxRecords", Value: int(10000), Desc: "Maximum records to be queried to TME", EnvVar: "MAX_RECORDS", }) slices := app.Int(cli.IntOpt{ Name: "slices", Value: int(10), Desc: "Number of requests to be executed in parallel to TME", EnvVar: "SLICES", }) tmeTaxonomyName := "Subjects" app.Action = func() { client := getResilientClient() mf := new(subjectTransformer) s, err := newSubjectService(tmereader.NewTmeRepository(client, *tmeBaseURL, *username, *password, *token, *maxRecords, *slices, tmeTaxonomyName, &tmereader.KnowledgeBases{}, mf), *baseURL, tmeTaxonomyName, *maxRecords) if err != nil { log.Errorf("Error while creating SubjectsService: [%v]", err.Error()) } h := newSubjectsHandler(s) m := mux.NewRouter() // The top one of these feels more correct, but the lower one matches what we have in Dropwizard, // so it's what apps expect currently same as ping m.HandleFunc(status.PingPath, status.PingHandler) m.HandleFunc(status.PingPathDW, status.PingHandler) m.HandleFunc(status.BuildInfoPath, status.BuildInfoHandler) m.HandleFunc(status.BuildInfoPathDW, status.BuildInfoHandler) m.HandleFunc("/__health", v1a.Handler("Subjects Transformer Healthchecks", "Checks for accessing TME", h.HealthCheck())) m.HandleFunc("/__gtg", h.GoodToGo) m.HandleFunc("/transformers/subjects", h.getSubjects).Methods("GET") m.HandleFunc("/transformers/subjects/__ids", h.getIds).Methods("GET") m.HandleFunc("/transformers/subjects/__count", h.getCount).Methods("GET") m.HandleFunc("/transformers/subjects/__reload", h.reload).Methods("POST") m.HandleFunc("/transformers/subjects/{uuid}", h.getSubjectByUUID).Methods("GET") http.Handle("/", m) log.Printf("listening on %d", *port) http.ListenAndServe(fmt.Sprintf(":%d", *port), httphandlers.HTTPMetricsHandler(metrics.DefaultRegistry, httphandlers.TransactionAwareRequestLoggingHandler(log.StandardLogger(), m))) } app.Run(os.Args) }