func main() { flag.Parse() config, err := loadConfig(*confPath) if err != nil { logger.Fatalf("Error reading config file %v: %v", *confPath, err) } r, err := setupRouter(config) if err != nil { logger.Fatal(err.Error()) } // Announce service using DNS-SD var bonjourCh chan<- bool if config.DnssdEnabled { bonjourCh, err = bonjour.Register(config.Description, catalog.DNSSDServiceType, "", config.BindPort, []string{fmt.Sprintf("uri=%s", config.ApiLocation)}, nil) if err != nil { logger.Printf("Failed to register DNS-SD service: %s", err.Error()) } else { logger.Println("Registered service via DNS-SD using type", catalog.DNSSDServiceType) defer func(ch chan<- bool) { ch <- true }(bonjourCh) } } // Setup signal catcher for the server's proper shutdown c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) go func() { for _ = range c { // sig is a ^C, handle it //TODO: put here the last will logic logger.Println("Stopped") os.Exit(0) } }() err = mime.AddExtensionType(".jsonld", "application/ld+json") if err != nil { logger.Println("ERROR: ", err.Error()) } // Configure the middleware n := negroni.New( negroni.NewRecovery(), negroni.NewLogger(), &negroni.Static{ Dir: http.Dir(config.StaticDir), Prefix: utils.StaticLocation, IndexFile: "index.html", }, ) // Mount router n.UseHandler(r) // Start listener endpoint := fmt.Sprintf("%s:%s", config.BindAddr, strconv.Itoa(config.BindPort)) logger.Printf("Starting standalone Service Catalog at %v%v", endpoint, config.ApiLocation) n.Run(endpoint) }
func main() { flag.Parse() if *confPath == "" { flag.Usage() os.Exit(1) } config, err := loadConfig(*confPath) if err != nil { logger.Printf("Failed to load configuration: %v\n", err) os.Exit(1) } // Agents' process manager agentManager := newAgentManager(config) // Configure MQTT publishing if required mqttPublisher := newMQTTPublisher(config) if mqttPublisher != nil { agentManager.setPublishingChannel(mqttPublisher.dataInbox()) go mqttPublisher.start() } // Start agents go agentManager.start() // Expose device's resources via REST (include statics and local catalog) restServer := newRESTfulAPI(config, agentManager.DataRequestInbox()) catalogStorage := catalog.NewMemoryStorage() go restServer.start(catalogStorage) // Parse device configurations devices := configureDevices(config) // register in local catalog registerInLocalCatalog(devices, config, catalogStorage) // register in remote catalogs regChannels, wg := registerInRemoteCatalog(devices, config) // Register this gateway as a service via DNS-SD var bonjourCh chan<- bool if config.DnssdEnabled { restConfig, _ := config.Protocols[ProtocolTypeREST].(RestProtocol) bonjourCh, err = bonjour.Register(config.Description, DNSSDServiceTypeDGW, "", config.Http.BindPort, []string{fmt.Sprintf("uri=%s", restConfig.Location)}, nil) if err != nil { logger.Printf("Failed to register DNS-SD service: %s", err.Error()) } else { logger.Println("Registered service via DNS-SD using type", DNSSDServiceTypeDGW) } } // Ctrl+C handling handler := make(chan os.Signal, 1) signal.Notify(handler, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) for sig := range handler { if sig == os.Interrupt { logger.Println("Caught interrupt signal...") break } } // Stop bonjour registration if bonjourCh != nil { bonjourCh <- true } // Shutdown all agentManager.stop() if mqttPublisher != nil { mqttPublisher.stop() } // Unregister in the remote catalog(s) for _, sigCh := range regChannels { // Notify if the routine hasn't returned already select { case sigCh <- true: default: } } wg.Wait() logger.Println("Stopped") os.Exit(0) }