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 main() { app := cli.App("System-healthcheck", "A service that report on current VM status at __health") hostPath = app.String(cli.StringOpt{ Name: "hostPath", Value: "", Desc: "The dir path of the mounted host fs (in the container)", EnvVar: "SYS_HC_HOST_PATH", }) checks = append(checks, diskFreeChecker{20}.Checks()...) checks = append(checks, memoryChecker{15}.Checks()...) checks = append(checks, loadAverageChecker{}.Checks()...) checks = append(checks, ntpChecker{}.Checks()...) checks = append(checks, tcpChecker{}.Checks()...) mux := mux.NewRouter() mux.HandleFunc("/__health", fthealth.Handler("myserver", "a server", checks...)) log.Printf("Starting http server on 8080\n") err := http.ListenAndServe(":8080", mux) if err != nil { panic(err) } }
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 setupServiceHandlers(ah authorHandler) http.Handler { r := mux.NewRouter() r.HandleFunc(status.PingPath, status.PingHandler) r.HandleFunc(status.PingPathDW, status.PingHandler) r.HandleFunc(status.BuildInfoPath, status.BuildInfoHandler) r.HandleFunc(status.BuildInfoPathDW, status.BuildInfoHandler) r.HandleFunc("/__health", v1a.Handler("Curated Authors Transformer", "Checks for accessing Bertha", ah.HealthCheck())) r.HandleFunc(status.GTGPath, ah.GoodToGo) r.HandleFunc("/transformers/authors", ah.refreshCache).Methods("POST") r.HandleFunc("/transformers/authors/__count", ah.getAuthorsCount).Methods("GET") r.HandleFunc("/transformers/authors/__ids", ah.getAuthorsUuids).Methods("GET") r.HandleFunc("/transformers/authors/{uuid}", ah.getAuthorByUuid).Methods("GET") return r }
func main() { app := cli.App("people-api-neo", "A RESTful API for managing People in neo4j") neoURL := app.StringOpt("neo-url", "http://localhost:7474/db/data", "neo4j endpoint URL") port := app.IntOpt("port", 8080, "Port to listen on") batchSize := app.IntOpt("batchSize", 1024, "Maximum number of statements to execute per batch") graphiteTCPAddress := app.StringOpt("graphiteTCPAddress", "", "Graphite TCP address, e.g. graphite.ft.com:2003. Leave as default if you do NOT want to output to graphite (e.g. if running locally)") graphitePrefix := app.StringOpt("graphitePrefix", "", "Prefix to use. Should start with content, include the environment, and the host name. e.g. content.test.people.rw.neo4j.ftaps58938-law1a-eu-t") logMetrics := app.BoolOpt("logMetrics", false, "Whether to log metrics. Set to true if running locally and you want metrics output") app.Action = func() { db, err := neoism.Connect(*neoURL) if err != nil { log.Fatal(err) } batchRunner := neoutils.NewBatchCypherRunner(neoutils.StringerDb{db}, *batchSize) peopleDriver := people.NewCypherPeopleService(batchRunner, db) peopleDriver.Initialise() baseftrwapp.OutputMetricsIfRequired(*graphiteTCPAddress, *graphitePrefix, *logMetrics) engs := map[string]baseftrwapp.Service{ "people": peopleDriver, } var checks []v1a.Check for _, e := range engs { checks = append(checks, makeCheck(e, batchRunner)) } baseftrwapp.RunServer(engs, v1a.Handler("ft-people_rw_neo4j ServiceModule", "Writes 'people' to Neo4j, usually as part of a bulk upload done on a schedule", checks...), *port, "ft-people_rw_neo4j", "local") } app.Run(os.Args) }
func main() { app := cli.App("subjetcs-rw-neo4j", "A RESTful API for managing Subjects in neo4j") neoURL := app.String(cli.StringOpt{ Name: "neo-url", Value: "http://localhost:7474/db/data", Desc: "neo4j endpoint URL", EnvVar: "NEO_URL", }) graphiteTCPAddress := app.String(cli.StringOpt{ Name: "graphite-tcp-address", Value: "", Desc: "Graphite TCP address, e.g. graphite.ft.com:2003. Leave as default if you do NOT want to output to graphite (e.g. if running locally", EnvVar: "GRAPHITE_TCP_ADDRESS", }) graphitePrefix := app.String(cli.StringOpt{ Name: "graphite-prefix", Value: "", Desc: "Prefix to use. Should start with content, include the environment, and the host name. e.g. coco.pre-prod.subjects-rw-neo4j.1", EnvVar: "GRAPHITE_PREFIX", }) port := app.Int(cli.IntOpt{ Name: "port", Value: 8080, Desc: "Port to listen on", EnvVar: "PORT", }) batchSize := app.Int(cli.IntOpt{ Name: "batch-size", Value: 1024, Desc: "Maximum number of statements to execute per batch", EnvVar: "BATCH_SIZE", }) logMetrics := app.Bool(cli.BoolOpt{ Name: "log-metrics", Value: false, Desc: "Whether to log metrics. Set to true if running locally and you want metrics output", EnvVar: "LOG_METRICS", }) app.Action = func() { conf := neoutils.DefaultConnectionConfig() conf.BatchSize = *batchSize db, err := neoutils.Connect(*neoURL, conf) if err != nil { log.Errorf("Could not connect to neo4j, error=[%s]\n", err) } subjectsDriver := subjects.NewCypherSubjectsService(db) subjectsDriver.Initialise() baseftrwapp.OutputMetricsIfRequired(*graphiteTCPAddress, *graphitePrefix, *logMetrics) endpoints := map[string]baseftrwapp.Service{ "subjects": subjectsDriver, } var checks []v1a.Check for _, e := range endpoints { checks = append(checks, makeCheck(e, db)) } baseftrwapp.RunServer(endpoints, v1a.Handler("ft-subjects_rw_neo4j ServiceModule", "Writes 'subjects' to Neo4j, usually as part of a bulk upload done on a schedule", checks...), *port, "subjects-rw-neo4j", "local") } app.Run(os.Args) }
func main() { app := cli.App("roles-rw-neo4j", "A RESTful API for managing Membership Roles in neo4j") neoURL := app.String(cli.StringOpt{ Name: "neo-url", Value: "http://localhost:7474/db/data", Desc: "neo4j endpoint URL", EnvVar: "NEO_URL", }) graphiteTCPAddress := app.String(cli.StringOpt{ Name: "graphiteTCPAddress", Value: "", Desc: "Graphite TCP address, e.g. graphite.ft.com:2003. Leave as default if you do NOT want to output to graphite (e.g. if running locally", EnvVar: "GRAPHITE_ADDRESS", }) graphitePrefix := app.String(cli.StringOpt{ Name: "graphitePrefix", Value: "", Desc: "Prefix to use. Should start with content, include the environment, and the host name. e.g. coco.pre-prod.roles-rw-neo4j.1 or content.test.roles.rw.neo4j.ftaps58938-law1a-eu-t", EnvVar: "GRAPHITE_PREFIX", }) port := app.Int(cli.IntOpt{ Name: "port", Value: 8080, Desc: "Port to listen on", EnvVar: "APP_PORT", }) batchSize := app.Int(cli.IntOpt{ Name: "batchSize", Value: 1024, Desc: "Maximum number of statements to execute per batch", EnvVar: "BATCH_SIZE", }) logMetrics := app.Bool(cli.BoolOpt{ Name: "logMetrics", Value: false, Desc: "Whether to log metrics. Set to true if running locally and you want metrics output", EnvVar: "LOG_METRICS", }) env := app.String(cli.StringOpt{ Name: "env", Value: "local", Desc: "environment this app is running in", }) app.Action = func() { conf := neoutils.DefaultConnectionConfig() conf.BatchSize = *batchSize db, err := neoutils.Connect(*neoURL, conf) if err != nil { log.Errorf("Could not connect to neo4j, error=[%s]\n", err) } rolesDriver := roles.NewCypherDriver(db) rolesDriver.Initialise() baseftrwapp.OutputMetricsIfRequired(*graphiteTCPAddress, *graphitePrefix, *logMetrics) services := map[string]baseftrwapp.Service{ "roles": rolesDriver, } var checks []v1a.Check for _, service := range services { checks = append(checks, makeCheck(service, db)) } baseftrwapp.RunServerWithConf(baseftrwapp.RWConf{ Services: services, HealthHandler: v1a.Handler("ft-roles_rw_neo4j ServiceModule", "Writes 'roles' to Neo4j, usually as part of a bulk upload done on a schedule", checks...), Port: *port, ServiceName: "roles-rw-neo4j", Env: *env, EnableReqLog: false, }) } log.SetLevel(log.InfoLevel) log.Infof("Application started with args %s", os.Args) app.Run(os.Args) }
func main() { app := cli.App("annotations-rw-neo4j", "A RESTful API for managing Annotations in neo4j") neoURL := app.String(cli.StringOpt{ Name: "neo-url", Value: "http://localhost:7474/db/data", Desc: "neo4j endpoint URL", EnvVar: "NEO_URL", }) graphiteTCPAddress := app.String(cli.StringOpt{ Name: "graphiteTCPAddress", Value: "", Desc: "Graphite TCP address, e.g. graphite.ft.com:2003. Leave as default if you do NOT want to output to graphite (e.g. if running locally", EnvVar: "GRAPHITE_ADDRESS", }) graphitePrefix := app.String(cli.StringOpt{ Name: "graphitePrefix", Value: "", Desc: "Prefix to use. Should start with content, include the environment, and the host name. e.g. coco.pre-prod.roles-rw-neo4j.1 or content.test.people.rw.neo4j.ftaps58938-law1a-eu-t", EnvVar: "GRAPHITE_PREFIX", }) port := app.Int(cli.IntOpt{ Name: "port", Value: 8080, Desc: "Port to listen on", EnvVar: "APP_PORT", }) batchSize := app.Int(cli.IntOpt{ Name: "batchSize", Value: 1024, Desc: "Maximum number of statements to execute per batch", EnvVar: "BATCH_SIZE", }) logMetrics := app.Bool(cli.BoolOpt{ Name: "logMetrics", Value: false, Desc: "Whether to log metrics. Set to true if running locally and you want metrics output", EnvVar: "LOG_METRICS", }) logLevel := app.String(cli.StringOpt{ Name: "log-level", Value: "INFO", Desc: "Logging level (DEBUG, INFO, WARN, ERROR)", EnvVar: "LOG_LEVEL", }) platformVersion := app.String(cli.StringOpt{ Name: "platformVersion", Value: "", Desc: "Annotation source platform. Possible values are: v1 or v2.", EnvVar: "PLATFORM_VERSION", }) app.Action = func() { parsedLogLevel, err := log.ParseLevel(*logLevel) if err != nil { log.WithFields(log.Fields{"logLevel": logLevel, "err": err}).Fatal("Incorrect log level") } log.SetLevel(parsedLogLevel) log.Infof("annotations-rw-neo4j will listen on port: %d, connecting to: %s", *port, *neoURL) conf := neoutils.DefaultConnectionConfig() conf.BatchSize = *batchSize db, err := neoutils.Connect(*neoURL, conf) if err != nil { log.Fatalf("Error connecting to neo4j %s", err) } annotationsService := annotations.NewCypherAnnotationsService(db, *platformVersion) httpHandlers := httpHandlers{annotationsService} // Healthchecks and standards first http.HandleFunc("/__health", v1a.Handler("Annotations RW Healthchecks", "Checks for accessing neo4j", httpHandlers.HealthCheck())) http.HandleFunc(status.PingPath, status.PingHandler) http.HandleFunc(status.PingPathDW, status.PingHandler) http.HandleFunc(status.BuildInfoPath, status.BuildInfoHandler) http.HandleFunc(status.BuildInfoPathDW, status.BuildInfoHandler) gtgChecker := make([]gtg.StatusChecker, 0) gtgChecker = append(gtgChecker, func() gtg.Status { if err := httpHandlers.AnnotationsService.Check(); err != nil { return gtg.Status{GoodToGo: false, Message: err.Error()} } return gtg.Status{GoodToGo: true} }) http.HandleFunc(status.GTGPath, status.NewGoodToGoHandler(gtg.FailFastParallelCheck(gtgChecker))) r := router(httpHandlers) http.Handle("/", r) baseftrwapp.OutputMetricsIfRequired(*graphiteTCPAddress, *graphitePrefix, *logMetrics) if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil); err != nil { log.Fatalf("Unable to start server: %v", err) } } log.Infof("Application started with args %s", os.Args) 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) }