func TestRouter(t *testing.T) { managmentAPIDests, err := mgmtapi.NewManagementAPIDestinations() if err != nil { t.Fatalf("NewManagementAPIDestinations: %s", err) } for n, testEntry := range routerTestData { centralDB := newMockCentralDB(testEntry.hosts) availableHosts := avail.NewMockAvailability(testEntry.availableHosts) router := NewRouter(managmentAPIDests, centralDB, availableHosts) req, err := http.NewRequest(testEntry.method, testEntry.uri, testEntry.body) if err != nil { t.Fatalf("http.NewRequest %s", err) } for key := range testEntry.headers { req.Header[key] = testEntry.headers[key] } req.Host = req.Header.Get(canonicalHostKey) hostPort, err := router.Route(requestID, req) if testEntry.expectedError != nil { if err == nil { t.Fatalf("Route %d %s, expecting error %s", n, testEntry.testName, testEntry.expectedError) } routerErr, ok := err.(RouterError) if !ok { t.Fatalf("Route %d %s Unexpected error type: %T %s", n, testEntry.testName, err, err) } if routerErr.HTTPCode() != testEntry.expectedError.HTTPCode() { t.Fatalf("Route %d %s Unexpected HTTP Status: %s expecting %s", n, testEntry.testName, routerErr, testEntry.expectedError) } } else if err != nil { t.Fatalf("Route %d %s, unexpected error %s", n, testEntry.testName, err) } else if hostPort != testEntry.expectedHostPort { t.Fatalf("Route %d %s Unexpected host:port: %s expecting %s", n, testEntry.testName, hostPort, testEntry.expectedHostPort) } } }
// main entry point for webdirector func main() { var err error fog.Info("program starts") // set up a signal handling channel signalChannel := make(chan os.Signal) signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) if profilePath := os.Getenv("WEBDIRECTOR_CPU_PROFILE_PATH"); profilePath != "" { profileFile, err := os.Create(profilePath) if err != nil { fog.Critical("os.Create(%s) failed %s", profilePath, err) } fog.Info("writing CPU profile data to %s", profilePath) pprof.StartCPUProfile(profileFile) defer pprof.StopCPUProfile() } useTLS := os.Getenv("NIMBUS_IO_SERVICE_SSL") == "1" fog.Info("TLS = %t", useTLS) listenAddress, err := getListenAddress() if err != nil { fog.Critical("error getListenAddress %s", err) } fog.Info("webdirector listens to %s", listenAddress) var listener net.Listener if useTLS { if listener, err = getTLSListener(listenAddress); err != nil { fog.Critical("Unable to create TLS listener: %s", err) } } else { if listener, err = getTCPListener(listenAddress); err != nil { fog.Critical("Unable to create TCP listener: %s", err) } } managmentAPIDests, err := mgmtapi.NewManagementAPIDestinations() if err != nil { fog.Critical("NewManagementAPIDestinations: %s", err) } centralDB := centraldb.NewCentralDB() availableHosts, err := avail.NewAvailability() if err != nil { fog.Critical("NewAvailability: %s", err) } router := routing.NewRouter(managmentAPIDests, centralDB, availableHosts) fog.Info("NIMBUS_IO_SERVICE_DOMAIN = '%s'", os.Getenv("NIMBUS_IO_SERVICE_DOMAIN")) fog.Info("NIMBUSIO_WEB_PUBLIC_READER_PORT = '%s'", os.Getenv("NIMBUSIO_WEB_PUBLIC_READER_PORT")) fog.Info("NIMBUSIO_WEB_WRITER_PORT = '%s'", os.Getenv("NIMBUSIO_WEB_WRITER_PORT")) listenerChan := make(chan net.Conn, listenerChanCapacity) go func() { for { connection, err := listener.Accept() if err != nil { fog.Error("listener.Accept() %s", err) close(listenerChan) break } listenerChan <- connection } }() for running := true; running; { select { case signal := <-signalChannel: fog.Info("terminated by signal: %v", signal) running = false case conn, ok := <-listenerChan: if ok { fog.Info("connection from %s", conn.RemoteAddr().String()) go handleConnection(router, conn) } else { running = false } } } listener.Close() fog.Info("program terminates") }