public void Start(Power firmware) { var config = new RestApiConfiguration(); config.AddHandler("GET", "/boot/ping", "is server alive") .ReturnNothing() .HandledBy(() => {}); config.AddHandler("GET", "/boot/firmware", "get firmware info") .ReturnJson() .HandledBy(() => firmware.GetFirmwareInfoAsJson()); config.AddHandler("PUT", "/boot/firmware", "update firmware") .ReturnJson() .HandledWithStreamBy((s) => firmware.UpdateFirmware(s)); config.AddHandler("POST", "/boot/sysinfo", "get system state") .ReturnJson() .HandledBy(() => HardwareInfo.Instance.GetSystemInfo()); config.AddHandler("POST", "/boot/diskinfo", "list content of filesystem") .ReturnJson() .HandledBy(() => HardwareInfo.Instance.GetDiskInfo()); config.AddHandler("GET", "/boot/networks", "list network information") .ReturnJson() .HandledBy(() => HardwareInfo.Instance.GetNetworkInterfaceInfo()); config.AddHandler("GET", "/boot/log/full", "get full log") .ReturnJson() .HandledBy(() => Logger.Instance.Full.GetLinesAsJson()); config.AddHandler("GET", "/boot/log/errors", "get error log") .ReturnJson() .HandledBy(() => Logger.Instance.Errors.GetLinesAsJson()); config.AddHandler("POST", "/boot/ntp/sync", "sync time with NTP") .ReturnJson() .HandledBy(() => { RealTimeClock.Instance.UpdateFromNTP(); var status = new JsonObject(); status.Add("time", DateTime.Now); return status; }); config.AddHandler("POST", "/boot/reboot", "reboot the device") .SetNotes("This will reboot the device and not return") .ReturnNothing() .HandledBy(() => firmware.Reboot()); var credentials = CredentialValidatorFactory.CreateSimpleValidator("ChickenHouse", "admin", "hnsefyk"); var webService = new WebService(c_servicePort, credentials, config); string prefix = Name + ": "; webService.Logging.OnLogInfo += message => Logger.Instance.LogInfo(prefix + message); webService.Logging.OnLogError += message => Logger.Instance.LogError(prefix + message); webService.Logging.OnLogException += (message, ex) => Logger.Instance.LogException(prefix + message, ex); webService.Start(); }
internal RestApi(RestApiConfiguration config) { ////// Sanity-check all rest handlers. They must have been given a handler. ////foreach (RestHandler handler in config.Handlers) ////{ //// if (handler.Handler == null) //// throw new InvalidOperationException("Missing handler for " + handler.DisplayName); ////} // todo: warn about missing api descriptions // Get builder's info _apiBasePath = config.ApiBasePath; // Prepare private handlers for swagger-documentation var priv = new RestApiConfiguration { ApiBasePath = _apiBasePath }; priv.AddHandler("GET", "", "Swagger UI") .ReturnsString("text/html") .HandledBy(GetApiIndex); priv.AddHandler("GET", "/api-docs", "API list") .ReturnsJson() .HandledBy(GetApiResourceListing); priv.AddHandler("GET", "/api-docs/{apiname}", "API description") .ReturnsJson() .HandledBy(GetApiDocs); // todo: // handle /images/throbber.gif // handle /favicon.ico foreach (RestHandler handler in config.Handlers) { var apiname = (config.FlattenApis ? "/all" : handler.ApiName); if (!_apis.Contains(apiname)) _apis[apiname] = new ArrayList(); (_apis[apiname] as ArrayList).Add(handler); } // Get the combined handlers _handlers = new RestHandler[config.Handlers.Count + priv.Handlers.Count]; priv.Handlers.CopyTo(_handlers, 0); config.Handlers.CopyTo(_handlers, priv.Handlers.Count); }
public void Start(Machinery machinery, DoorScheduler doorScheduler) { var config = new RestApiConfiguration(); config.AddHandler("GET", "/sys/ping", "is server alive") .ReturnsNothing() .HandledBy(() => { }); config.AddHandler("POST", "/sys/info", "get system state") .ReturnsJson() .HandledBy(() => HardwareInfo.Instance.GetSystemInfo()); config.AddHandler("POST", "/sys/disk", "list content of filesystem") .ReturnsJson() .HandledBy(() => HardwareInfo.Instance.GetDiskInfo()); config.AddHandler("GET", "/sys/network", "list network information") .ReturnsJson() .HandledBy(() => HardwareInfo.Instance.GetNetworkInterfaceInfo()); config.AddHandler("GET", "/sys/time", "get current local time") .ReturnsJson() .HandledBy(() => { var status = new JsonObject(); status.Add("time", DateTime.Now); return status; }); config.AddHandler("PUT", "/sys/time/{time}", "set current local time") .ReturnsNothing() .HandledBy((time) => { // todo //Goke.ChickenHouse.HAL.Hardware.Instance.Clock.SetTime( var x = time.Length; throw new NotImplementedException("set time is not implemented yet"); }); config.AddHandler("POST", "/sys/time/sync", "sync time with NTP") .ReturnsJson() .HandledBy(() => { RealTimeClock.Instance.UpdateFromNTP(); var status = new JsonObject(); status.Add("time", DateTime.Now); return status; }); config.AddHandler("POST", "/sys/reboot", "reboot the device") .SetNotes("This will reboot the device and not return") .ReturnsNothing() .HandledBy(() => MainBoard.Reboot()); config.AddHandler("GET", "/hw/doors/{doorname}", "get status for the door") .ReturnsJson() .HandledBy((doorname) => { var door = machinery.LookupDoorByName(doorname); var status = new JsonObject(); status.Add("name", door.Name); status.Add("status", EnumUtil.DoorStatusTostring(door.Status)); return status; }); config.AddHandler("POST", "/hw/doors/{doorname}/open", "open the door completely") .ReturnsNothing() .HandledBy((doorname) => { var door = machinery.LookupDoorByName(doorname); machinery.Sequencer.Enqueue(() => door.OpenCompletely()); }); config.AddHandler("POST", "/hw/doors/{doorname}/close", "close the door completely") .ReturnsNothing() .HandledBy((doorname) => { var door = machinery.LookupDoorByName(doorname); machinery.Sequencer.Enqueue(() => door.CloseCompletely()); }); config.AddHandler("POST", "/hw/doors/{doorname}/moveup/{millisec}", "move the door up") .ReturnsNothing() .HandledBy((doorname, millisec) => { var door = machinery.LookupDoorByName(doorname); var msec = int.Parse(millisec); machinery.Sequencer.Enqueue(() => door.MoveUp(msec)); }); config.AddHandler("POST", "/hw/doors/{doorname}/movedown/{millisec}", "move the door down") .ReturnsNothing() .HandledBy((doorname, millisec) => { var door = machinery.LookupDoorByName(doorname); var msec = int.Parse(millisec); machinery.Sequencer.Enqueue(() => door.MoveDown(msec)); }); config.AddHandler("POST", "/hw/doors/{doorname}/stop", "stop moving the door") .ReturnsNothing() .HandledBy((doorname) => { var door = machinery.LookupDoorByName(doorname); door.StopMoving(); // Stop immediately - don't go through sequencer! }); config.AddHandler("GET", "/hw/relays/{relayname}", "get state of relay") .ReturnsJson() .HandledBy((relayname) => { var relay = machinery.LookupRelayByName(relayname); var status = new JsonObject(); status.Add("name", relay.Name); status.Add("on", relay.On); return status; }); config.AddHandler("PUT", "/hw/relays/{relayname}/on", "turn relay on") .ReturnsNothing() .HandledBy((relayname) => { var relay = machinery.LookupRelayByName(relayname); relay.On = true; }); config.AddHandler("PUT", "/hw/relays/{relayname}/off", "turn relay off") .ReturnsNothing() .HandledBy((relayname) => { var relay = machinery.LookupRelayByName(relayname); relay.On = false; }); config.AddHandler("POST", "/admin/log/clear", "clear the entire log") .ReturnsNothing() .HandledBy(() => { Logger.Instance.Full.Clear(); Logger.Instance.Errors.Clear(); }); config.AddHandler("GET", "/admin/log/full", "get full log") .ReturnsStream() .HandledBy((context) => { context.Response.OutputStream.WriteByte((byte)'['); foreach (var line in Logger.Instance.Full.GetLines()) { var b = System.Text.Encoding.UTF8.GetBytes(Json.NETMF.JsonSerializer.SerializeObject(line)); context.Response.OutputStream.Write(b, 0, b.Length); context.Response.OutputStream.WriteByte((byte)','); } context.Response.OutputStream.WriteByte((byte)']'); }); config.AddHandler("GET", "/admin/log/errors", "get error log") .ReturnsJson() .HandledBy(() => { return Logger.Instance.Errors.GetLinesAsJson(); }); config.AddHandler("GET", "/config/schedule", "get the schedule") .ReturnsJson() .HandledBy(() => doorScheduler.GetScheduleAsJson()); var credentials = CredentialValidatorFactory.CreateSimpleValidator("Bootstrapper", "admin", "hnsefyk"); var webService = new WebService(c_servicePort, credentials, config); string prefix = Name + ": "; webService.Logging.OnLogInfo += message => Logger.Instance.LogInfo(prefix + message); webService.Logging.OnLogError += message => Logger.Instance.LogError(prefix + message); webService.Logging.OnLogException += (message, ex) => Logger.Instance.LogException(prefix + message, ex); webService.Start(); }