diff --git a/32-platform/platform/http/server.go b/32-platform/platform/http/server.go new file mode 100644 index 0000000..c42e89f --- /dev/null +++ b/32-platform/platform/http/server.go @@ -0,0 +1,74 @@ +package http + +import ( + "fmt" + "net/http" + "platform/config" + "platform/logging" + "platform/pipeline" + "sync" +) + +type pipelineAdaptor struct { + pipeline.RequestPipeline +} + +func (p pipelineAdaptor) ServeHTTP(writer http.ResponseWriter, request *http.Request) { + err := p.ProcessRequest(request, writer) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } +} + +func Serve(pl pipeline.RequestPipeline, cfg config.Configuration, logger logging.Logger) *sync.WaitGroup { + wg := sync.WaitGroup{} + adaptor := pipelineAdaptor{RequestPipeline: pl} + + serveHttp(cfg, logger, &wg, &adaptor) + serveHttps(cfg, logger, &wg, &adaptor) + + return &wg +} + +func serveHttp(cfg config.Configuration, logger logging.Logger, wg *sync.WaitGroup, adaptor *pipelineAdaptor) { + enableHttp := cfg.GetBoolDefault("http:enableHTTP", true) + if !enableHttp { + return + } + httpPort := cfg.GetIntDefault("http:port", 5000) + httpName := cfg.GetStringDefault("http:name", "localhost") + logger.Debugf("Starting HTTP server on port %v:%d", httpName, httpPort) + wg.Add(1) + go func() { + url := fmt.Sprintf("%v:%v", httpName, httpPort) + err := http.ListenAndServe(url, adaptor) + if err != nil { + panic(err) + } + }() +} + +func serveHttps(cfg config.Configuration, logger logging.Logger, wg *sync.WaitGroup, adaptor *pipelineAdaptor) { + enableHttps := cfg.GetBoolDefault("http:enableHTTPS", false) + if !enableHttps { + return + } + httpsPort := cfg.GetIntDefault("http:httpsPort", 5500) + httpsName := cfg.GetStringDefault("http:httpsName", "localhost") + certFile, cfOk := cfg.GetString("http:httpsCert") + keyFile, kfOk := cfg.GetString("http:httpsKey") + if cfOk && kfOk { + logger.Debugf("Starting HTTPS server on port %v:%d", httpsName, httpsPort) + wg.Add(1) + go func() { + url := fmt.Sprintf("%v:%v", httpsName, httpsPort) + err := http.ListenAndServeTLS(url, certFile, keyFile, adaptor) + if err != nil { + panic(err) + } + }() + } else { + panic("HTTPS certificate or key file setting not found") + } +} diff --git a/32-platform/platform/logging_config_test.go b/32-platform/platform/logging_config_test.go index 06ab7d0..f01b9fc 100644 --- a/32-platform/platform/logging_config_test.go +++ b/32-platform/platform/logging_config_test.go @@ -1 +1,76 @@ package main + +import ( + "platform/config" + "platform/logging" + "platform/services" + "testing" +) + +func writeMessage(logger logging.Logger, cfg config.Configuration) { + section, ok := cfg.GetSection("main") + if !ok { + logger.Panicf("Config section not found %v", "main") + return + } + message, ok := section.GetString("message") + if !ok { + logger.Panicf("Config value not found %v", "message") + return + } + logger.Info(message) + + messages, ok := cfg.GetSectionSlice("messages") + if !ok { + logger.Panicf("Config section not found %v", "messages") + return + } + for _, item := range messages { + itemMessage, itemOk := item.GetString("message") + if !itemOk { + logger.Panicf("Config value not found %v", "messages.message") + return + } + logger.Info(itemMessage) + } +} + +func TestServices1(t *testing.T) { + // 注册服务 + services.RegisterDefaultService() + // 获取配置服务 + var cfg config.Configuration + err := services.GetService(&cfg) + if err != nil { + panic(err) + } + // 获取日志服务 + var logger logging.Logger + err = services.GetService(&logger) + if err != nil { + panic(err) + } + // 写入日志 + writeMessage(logger, cfg) +} + +func TestServices2(t *testing.T) { + // 注册服务 + services.RegisterDefaultService() + _, err := services.Call(writeMessage) + if err != nil { + panic(err) + } + + val := struct { + message string + logging.Logger + }{ + message: "Hello from the struct", + } + err = services.Populate(&val) + if err != nil { + panic(err) + } + val.Logger.Debug(val.message) +} diff --git a/32-platform/platform/main.go b/32-platform/platform/main.go index 80af0b6..a7378c4 100644 --- a/32-platform/platform/main.go +++ b/32-platform/platform/main.go @@ -1,79 +1,11 @@ package main import ( - "platform/config" - "platform/logging" + "platform/placeholder" "platform/services" ) -func writeMessage(logger logging.Logger, cfg config.Configuration) { - section, ok := cfg.GetSection("main") - if !ok { - logger.Panicf("Config section not found %v", "main") - return - } - message, ok := section.GetString("message") - if !ok { - logger.Panicf("Config value not found %v", "message") - return - } - logger.Info(message) - - messages, ok := cfg.GetSectionSlice("messages") - if !ok { - logger.Panicf("Config section not found %v", "messages") - return - } - for _, item := range messages { - itemMessage, itemOk := item.GetString("message") - if !itemOk { - logger.Panicf("Config value not found %v", "messages.message") - return - } - logger.Info(itemMessage) - } -} - -func main1() { - // 注册服务 - services.RegisterDefaultService() - // 获取配置服务 - var cfg config.Configuration - err := services.GetService(&cfg) - if err != nil { - panic(err) - } - // 获取日志服务 - var logger logging.Logger - err = services.GetService(&logger) - if err != nil { - panic(err) - } - // 写入日志 - writeMessage(logger, cfg) -} - -func main2() { - // 注册服务 - services.RegisterDefaultService() - _, err := services.Call(writeMessage) - if err != nil { - panic(err) - } - - val := struct { - message string - logging.Logger - }{ - message: "Hello from the struct", - } - err = services.Populate(&val) - if err != nil { - panic(err) - } - val.Logger.Debug(val.message) -} - func main() { - main2() + services.RegisterDefaultService() + placeholder.Start() } diff --git a/32-platform/platform/pipeline/pipeline.go b/32-platform/platform/pipeline/pipeline.go index 531fd2f..0dc3a8b 100644 --- a/32-platform/platform/pipeline/pipeline.go +++ b/32-platform/platform/pipeline/pipeline.go @@ -11,7 +11,7 @@ var emptyPipeline RequestPipeline = func(*ComponentContext) { // CreatePipeline 创建管道 func CreatePipeline(components ...MiddlewareComponent) RequestPipeline { f := emptyPipeline - for i := len(components) - 1; i <= 0; i-- { + for i := len(components) - 1; i >= 0; i-- { currentComponent := components[i] nextFunc := f f = func(context *ComponentContext) { diff --git a/32-platform/platform/placeholder/startup.go b/32-platform/platform/placeholder/startup.go new file mode 100644 index 0000000..83c77db --- /dev/null +++ b/32-platform/platform/placeholder/startup.go @@ -0,0 +1,29 @@ +package placeholder + +import ( + "platform/http" + "platform/pipeline" + "platform/pipeline/basic" + "platform/services" + "sync" +) + +func createPipeline() pipeline.RequestPipeline { + return pipeline.CreatePipeline( + &basic.ServicesComponent{}, + &basic.LoggingComponent{}, + &basic.ErrorComponent{}, + &basic.StaticFileComponent{}, + &SimpleMessageComponent{}, + ) +} + +func Start() { + results, err := services.Call(http.Serve, createPipeline()) + if err == nil { + wg := results[0].(*sync.WaitGroup) + wg.Wait() + } else { + panic(err) + } +}