public static void Main() { var projectFolder = Application.Current.WorkingDirectory; RESTarConfig.Init ( port: 18290, uri: "/api", requireApiKey: true, configFilePath: projectFolder + "/Config.xml", entityResourceProviders: new[] { new SQLiteProvider($"{projectFolder}\\data.sqlite") }, protocolProviders: new[] { new ODataProtocolProvider() } ); IEnumerable <Superhero> CreateEvents(IEnumerable <Superhero> heroes) { foreach (var hero in heroes) { new SuperheroCreated(hero); yield return(hero); } } Events.EntityResource <Superhero> .PostInsert += CreateEvents; }
internal void RegisterBinaryTypes(IEnumerable <Type> binaryTypes) => binaryTypes .OrderBy(t => t.RESTarTypeName()) .ForEach(type => { var resource = (IResource)BuildBinaryMethod.MakeGenericMethod(type).Invoke(this, null); RESTarConfig.AddResource(resource); });
internal void RegisterEventTypes(IEnumerable <Type> eventTypes) => eventTypes .OrderBy(t => t.RESTarTypeName()) .ForEach(type => { var payloadType = type.GetGenericTypeParameters(typeof(Event <>))[0]; var resource = (IResource)BuildEventMethod.MakeGenericMethod(type, payloadType).Invoke(this, null); RESTarConfig.AddResource(resource); });
protected override IEnumerable <Option> GetOptions() => new[] { new Option ( command: "ReloadConfigFile", description: "Reloads the configuration file and updates the access rights for API keys", action: args => RESTarConfig.UpdateConfiguration() ) };
internal void RegisterTerminalTypes(List <Type> terminalTypes) { terminalTypes.OrderBy(t => t.RESTarTypeName()).ForEach(type => { var resource = (IResource)BuildTerminalMethod.MakeGenericMethod(type).Invoke(this, null); RESTarConfig.AddResource(resource); }); Shell.TerminalResource = Meta.TerminalResource <Shell> .Get; }
private bool RemoveResource(IResource resource) { if (resource is IEntityResource er && er.Provider == Id) { RESTarConfig.RemoveResource(resource); return(true); } return(false); }
public static void Main() { RESTarConfig.Init ( uri: "/rest", requireApiKey: true, allowAllOrigins: false, configFilePath: @"C:\Mopedo\mopedo\Mopedo.config" ); }
private void Swap() { Position = 0; var fileStream = RESTarConfig.MakeTempFile(); using (var memoryStream = (MemoryStream)Stream) memoryStream.WriteTo(fileStream); Stream = fileStream; Swapped = true; }
public static void Main() { var projectFolder = Application.Current.WorkingDirectory; RESTarConfig.Init ( port: 8282, uri: "/api", requireApiKey: true, configFilePath: projectFolder + "/Config.xml", entityResourceProviders: new[] { new SQLiteProvider($"{projectFolder}\\data_debug2") } ); // The 'port' argument sets the HTTP port on which to register the REST handlers // The 'uri' argument sets the root uri of the REST API // The 'requireApiKey' parameter is set to 'true'. API keys are required in all incoming requests. // The 'configFilePath' points towards the configuration file, which contains API keys. In this case, // this file is located in the project folder. // The 'resourceProviders' parameter is used for SQLite integration }
public static void Main() { #region Cleanup Db.SQL <RESTar.Dynamic.DynamicResource>("SELECT t FROM RESTar.Dynamic.DynamicResource t").ForEach(b => Db.TransactAsync(b.Delete)); Db.SQL <Webhook>("SELECT t FROM RESTar.Admin.Webhook t").ForEach(b => Db.TransactAsync(b.Delete)); Db.SQL <Base>("SELECT t FROM RESTarTester.Base t").ForEach(b => Db.TransactAsync(b.Delete)); Db.SQL <MyDict>("SELECT t FROM RESTarTester.MyDict t").ForEach(b => Db.TransactAsync(b.Delete)); Db.SQL <MyDict2>("SELECT t FROM RESTarTester.MyDict2 t").ForEach(b => Db.TransactAsync(b.Delete)); #endregion #region Handles and Init() bool wrstreamcalled = false; bool wrbytescalled = false; bool wrstringcalled = false; Handle.POST("/wrStream", (Request __r) => { Debug.Assert(__r.BodyBytes.Length == 16); wrstreamcalled = true; return(HttpStatusCode.OK); }); Handle.POST("/wrBytes", (Request __r) => { Debug.Assert(__r.BodyBytes.Length == 23); wrbytescalled = true; return(HttpStatusCode.OK); }); Handle.POST("/wrString", (Request __r) => { Debug.Assert(__r.Body == "This is the very important message!"); wrstringcalled = true; return(HttpStatusCode.OK); }); RESTarConfig.Init ( port: 9000, lineEndings: LineEndings.Windows, prettyPrint: true, allowAllOrigins: false, configFilePath: @"C:\Mopedo\mopedo\Mopedo.config" ); #endregion #region Create resources and hooks using (var dynamicResourceRequest = Context.Root.CreateRequest <RESTar.Dynamic.Resource>(POST)) { dynamicResourceRequest.Selector = () => new[] { new RESTar.Dynamic.Resource { Name = "wr1" }, new RESTar.Dynamic.Resource { Name = "wr2" }, new RESTar.Dynamic.Resource { Name = "wr3" }, new RESTar.Dynamic.Resource { Name = "wrResource1" } }; using (var drResult = dynamicResourceRequest.Evaluate()) { Debug.Assert(drResult is Change); } } using (var webhookRequest = Context.Root.CreateRequest <Webhook>(POST)) { webhookRequest.Selector = () => new[] { new Webhook { Destination = "/wr1", EventSelector = $"/{typeof(ENotification).FullName}" }, new Webhook { Destination = "/wr2", EventSelector = $"/{typeof(ENotification).FullName}" }, new Webhook { Destination = "http://*****:*****@"{""Id"": 1, ""Str"": ""Foogoo""}"), headers: new Dictionary <string, string>() { ["password"] = "******" }); var response5fail = Http.Request("POST", "http://*****:*****@"{""Id"": 2, ""Str"": ""Foogoo""}"), headers: new Dictionary <string, string>() { ["password"] = "******" }); var response6 = Http.Request("POST", "http://localhost:9000/rest/resource1//safepost=ObjectNo", Encoding.UTF8.GetBytes(onesJson), null); Debug.Assert(response1?.IsSuccessStatusCode == true); Debug.Assert(response2?.IsSuccessStatusCode == true); Debug.Assert(response3?.IsSuccessStatusCode == true); Debug.Assert(response4?.IsSuccessStatusCode == true); Debug.Assert(response5?.IsSuccessStatusCode == true); Debug.Assert(response5fail?.StatusCode == (HttpStatusCode)403); Debug.Assert(response6?.IsSuccessStatusCode == true); #endregion var a = ""; #region External source/destination inserts var resource1Url = "https://storage.googleapis.com/mopedo-web/resource1.json"; var esourceresponse1 = Http.Request ( method: "POST", uri: "http://localhost:9000/rest/resource1", body: null, headers: new Dictionary <string, string> { ["Source"] = "GET " + resource1Url } ); Debug.Assert(esourceresponse1?.IsSuccessStatusCode == true); var esourceresponse2 = Http.Request ( method: "POST", uri: "http://localhost:9000/rest/MyDict", body: null, headers: new Dictionary <string, string> { ["Source"] = "GET " + resource1Url } ); Debug.Assert(esourceresponse2?.IsSuccessStatusCode == true); var esourceresponse3 = Http.Request ( method: "POST", uri: "http://localhost:9000/rest/MyDict", body: null, headers: new Dictionary <string, string> { ["Source"] = "GET /resource1" } ); Debug.Assert(esourceresponse3?.IsSuccessStatusCode == true); var edestinationresponse1 = Http.Request ( method: "GET", uri: "http://localhost:9000/rest/resource1", headers: new Dictionary <string, string> { ["Destination"] = "POST /mydict" } ); Debug.Assert(edestinationresponse1?.IsSuccessStatusCode == true); var edestinationresponse2 = Http.Request ( method: "GET", uri: "http://localhost:9000/rest/mydict", headers: new Dictionary <string, string> { ["Destination"] = "POST http://localhost:9000/rest/resource1" } ); Debug.Assert(edestinationresponse2?.IsSuccessStatusCode == true); #endregion #region JSON GET var request = (HttpWebRequest)WebRequest.Create("http://localhost:9000/rest/resource1"); request.Method = "GET"; var response = (HttpWebResponse)request.GetResponse(); var rstream = response.GetResponseStream(); var streamreader = new StreamReader(rstream); var data = streamreader.ReadToEnd(); Debug.Assert(!string.IsNullOrWhiteSpace(data)); var jsonResponse1 = Http.Request("GET", "http://localhost:9000/rest/restartester.resource1"); var jsonResponse1view = Http.Request("GET", "http://localhost:9000/rest/resource1-myview"); var jsonResponse2 = Http.Request("GET", "http://localhost:9000/rest/resource2"); var jsonResponse3 = Http.Request("GET", "http://localhost:9000/rest/resource3"); var jsonResponse4 = Http.Request("GET", "http://localhost:9000/rest/resource4"); var jsonResponse4distinct = Http.Request("GET", "http://localhost:9000/rest/resource4//select=string&distinct=true"); var jsonResponse4extreme = Http.Request("GET", "http://localhost:9000/rest/resource4//add=datetime.day&select=datetime.day,datetime.month,string,string.length&order_desc=string.length&distinct=true"); var jsonResponse5format = Http.Request("GET", "http://localhost:9000/rest/resource4//add=datetime.day&select=datetime.day,datetime.month,string,string.length&order_desc=string.length&format=jsend&distinct=true"); var head = Http.Request("HEAD", "http://localhost:9000/rest/resource1//distinct=true"); var report = Http.Request("REPORT", "http://localhost:9000/rest/resource1//distinct=true"); Debug.Assert(jsonResponse1?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse1view?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse2?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse3?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse4?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse4distinct?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse4extreme?.IsSuccessStatusCode == true); Debug.Assert(jsonResponse5format?.IsSuccessStatusCode == true); #endregion #region GET Excel var headers = new Dictionary <string, string> { ["Accept"] = "application/restar-excel" }; var excelResponse1 = Http.Request("GET", "http://localhost:9000/rest/resource1", headers: headers); var excelResponse2 = Http.Request("GET", "http://localhost:9000/rest/resource2", headers: headers); var excelResponse3 = Http.Request("GET", "http://localhost:9000/rest/resource3", headers: headers); var excelResponse4 = Http.Request("GET", "http://localhost:9000/rest/resource4", headers: headers); Debug.Assert(excelResponse1?.IsSuccessStatusCode == true); Debug.Assert(excelResponse2?.IsSuccessStatusCode == true); Debug.Assert(excelResponse3?.IsSuccessStatusCode == true); Debug.Assert(excelResponse4?.IsSuccessStatusCode == true); #endregion #region POST Excel var excelbody = excelResponse1.Content.ReadAsByteArrayAsync().Result; var excelPostResponse1 = Http.Request("POST", "http://localhost:9000/rest/resource1", body: excelbody, contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); Debug.Assert(excelPostResponse1?.IsSuccessStatusCode == true); var webrequest = (HttpWebRequest)WebRequest.Create("http://localhost:9000/rest/resource1"); webrequest.Method = "POST"; webrequest.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; using (var str = webrequest.GetRequestStream()) using (var stream = new MemoryStream(excelbody)) stream.CopyTo(str); var webResponse = (HttpWebResponse)webrequest.GetResponse(); string _body; using (var reader = new StreamReader(webResponse.GetResponseStream())) _body = reader.ReadToEnd(); Debug.Assert(webResponse.StatusCode < HttpStatusCode.BadRequest); #endregion #region With conditions var conditionResponse1 = Http.Request("GET", "http://localhost:9000/rest/resource1/sbyte>=0&byte!=200&datetime>2001-01-01"); var conditionResponse2 = Http.Request("GET", "http://localhost:9000/rest/resource2/sbyte<=10&byte!=200&datetime>2001-01-01"); var conditionResponse3 = Http.Request("GET", "http://localhost:9000/rest/resource3/sbyte>0&byte!=200&datetime>2001-01-01"); var conditionResponse4 = Http.Request("GET", "http://localhost:9000/rest/resource4/resource1.string!=aboo&resource2!=null"); Debug.Assert(excelResponse1?.IsSuccessStatusCode == true); Debug.Assert(excelResponse2?.IsSuccessStatusCode == true); Debug.Assert(excelResponse3?.IsSuccessStatusCode == true); Debug.Assert(excelResponse4?.IsSuccessStatusCode == true); #endregion #region Internal requests var context = Context.Root; var g = context.CreateRequest <MyDict>(POST); g.Selector = () => { dynamic d = new MyDict(); d.Hej = "123"; d.Foo = 3213M; d.Goo = true; dynamic v = new MyDict(); v.Hej = "123"; v.Foo = 3213M; v.Goo = false; dynamic x = new MyDict(); x.Hej = "123"; x.Foo = 3213M; x.Goo = false; return(new MyDict[] { d, v, x }); }; var result = g.Evaluate(); Debug.Assert(result is InsertedEntities ie && ie.InsertedCount == 3); var g2 = context.CreateRequest <MyDict>(POST); dynamic d2 = new JObject(); d2.Hej = "123"; d2.Foo = 3213M; d2.Goo = true; dynamic v2 = new JObject(); v2.Hej = "123"; v2.Foo = 3213M; v2.Goo = false; dynamic x2 = new JObject(); x2.Hej = "123"; x2.Foo = 3213M; x2.Goo = false; var arr2 = new[] { d2, v2, x2 }; g2.SetBody(arr2); var result2 = g2.Evaluate(); Debug.Assert(result2 is InsertedEntities ie2 && ie2.InsertedCount == 3); var g5 = context.CreateRequest <MyDict>(POST); dynamic d5 = new JObject(); d5.Hej = "123"; d5.Foo = 3213M; d5.Goo = true; dynamic v5 = new JObject(); v5.Hej = "123"; v5.Foo = 3213M; v5.Goo = false; dynamic x5 = new JObject(); x5.Hej = "123"; x5.Foo = 3213M; x5.Goo = false; var arr5 = new[] { d5, v5, x5 }; g5.SetBody(arr5, ContentType.Excel); var result5 = g5.Evaluate(); Debug.Assert(result5 is InsertedEntities ie5 && ie5.InsertedCount == 3); var g3 = context.CreateRequest <MyDict>(POST); var d3 = new { Hej = "123", Foo = 3213M, Goo = true }; g3.SetBody(d3); var result3 = g3.Evaluate(); Debug.Assert(result3 is InsertedEntities ie3 && ie3.InsertedCount == 1); var g4 = context.CreateRequest <MyDict>(POST); var d4 = JsonConvert.SerializeObject(new { Hej = "123", Foo = 3213M, Goo = true }); g4.SetBody(d4); var result4 = g4.Evaluate(); Debug.Assert(result4 is InsertedEntities ie4 && ie4.InsertedCount == 1); var r1Cond = new Condition <Resource1>(nameof(Resource1.Sbyte), GREATER_THAN, 1); var r1 = context.CreateRequest <Resource1>(GET); r1.Conditions.Add(r1Cond); var r2 = context.CreateRequest <Resource2>(GET); var r3 = context.CreateRequest <Resource3>(GET); var r4 = context.CreateRequest <Resource4>(GET); var r6 = context.CreateRequest <Aggregator>(GET); r6.SetBody(new { A = "REPORT /admin.resource", B = new[] { "REPORT /admin.resource", "REPORT /admin.resource" } }); var r5 = context.CreateRequest <Resource1>(GET); var cond = new Condition <Resource1>("SByte", GREATER_THAN, 2); r5.Conditions.Add(cond); r5.Headers.Accept = ContentType.Excel; var res1 = r1.Evaluate().Serialize(); var res2 = r2.Evaluate().Serialize(); var res3 = r3.Evaluate().Serialize(); var res4 = r4.Evaluate().Serialize(); var res5 = r5.Evaluate().Serialize(); var res6 = r6.Evaluate().Serialize(); Debug.Assert(res5.Headers.ContentType == ContentType.Excel); Debug.Assert(res5.Body.Length > 1); Db.TransactAsync(() => { var x = new MyDict { ["Hej"] = "123", ["Foo"] = 3213M, ["Goo"] = false }; foreach (Resource1 asd in Db.SQL <Resource1>("SELECT t FROM RESTarTester.Resource1 t")) { asd.MyDict = x; } }); Do.Schedule(() => Db.TransactAsync(() => new MyDict() { ["Aaa"] = "Wook" }), TimeSpan.FromSeconds(10)).Wait(); DatabaseIndex.Register <MyDict2>("MyFineIdex", "$R"); Db.TransactAsync(() => { new MyDict2 { ["Snoo"] = 123, R = new Resource1 { Byte = 123, String = "Googfoo" } }; }); var byInternalSource = Http.Request("POST", "http://localhost:9000/rest/resource3", null, headers: new Dictionary <string, string> { ["Source"] = "GET /resource3" }); var internalRequest9 = Context.Root.CreateRequest <Resource1>(); var entities9 = internalRequest9.EvaluateToEntities(); Debug.Assert(entities9 is IEntities <Resource1> rement1 && rement1.Count() > 1 && entities9 is IEnumerable <Resource1>); var resource2Conditions = new Condition <Resource2>[] { new Condition <Resource2>(nameof(Resource2.Bool), EQUALS, false), new Condition <Resource2>(nameof(Resource2.Enum), EQUALS, MyEnum.D), new Condition <Resource2>(nameof(Resource2.BBool), EQUALS, false), new Condition <Resource2>(nameof(Resource2.Long), NOT_EQUALS, 42123), }; var internalRequest10 = Context.Root .CreateRequest <Resource1>() .WithConditions(resource2Conditions.Redirect <Resource1>( (direct: "BBool", to: "ABool"), (direct: "Long", to: "Foobooasd") )); var entities10 = internalRequest10.EvaluateToEntities(); Debug.Assert(entities10 is IEntities <Resource1> _rement1 && _rement1.Count() > 1 && entities10 is IEnumerable <Resource1>); var c = entities10.Count(); var c2 = entities10.Count(); var objectNo = entities10.FirstOrDefault().GetObjectNo(); var objectId = entities10.Skip(1).FirstOrDefault().GetObjectID(); var byObjectNo = Context.Root .CreateRequest <Resource1>() .WithConditions(new Condition <Resource1>("ObjectNo", EQUALS, objectNo)) .EvaluateToEntities() .FirstOrDefault(); var byObjectID = Context.Root .CreateRequest <Resource1>() .WithConditions(new Condition <Resource1>("ObjectID", EQUALS, objectId)) .EvaluateToEntities() .FirstOrDefault(); var byObjectIDThatDoesntExist = Context.Root .CreateRequest <Resource1>() .WithConditions(new Condition <Resource1>("ObjectID", EQUALS, new Stopwatch())) .EvaluateToEntities() .FirstOrDefault(); Debug.Assert(byObjectNo is Resource1); Debug.Assert(byObjectID is Resource1); Debug.Assert(byObjectIDThatDoesntExist == null); #endregion #region Remote requests var remoteContext = Context.Remote("http://localhost:9000/rest"); var remoteRequest = remoteContext.CreateRequest("/resource1", GET); var remoteResult = remoteRequest.Evaluate(); Debug.Assert(remoteResult is IEntities rement && rement.EntityCount > 1); #endregion #region OPTIONS var optionsResponse1 = Http.Request("OPTIONS", "http://localhost:9000/rest/resource1", null, headers: new Dictionary <string, string> { ["Origin"] = "https://fooboo.com/thingy" }); Debug.Assert(optionsResponse1?.IsSuccessStatusCode == true); Debug.Assert(optionsResponse1.Headers.TryGetValues("Access-Control-Allow-Origin", out var _vals) && _vals.First() == "https://fooboo.com/thingy"); Debug.Assert(optionsResponse1.Headers.TryGetValues("Vary", out var vvals) && vvals.First() == "Origin"); Debug.Assert(optionsResponse1?.Content.ReadAsStringAsync().Result.Length > 15); var optionsResponse2 = Http.Request("OPTIONS", "http://localhost:9000/rest/resource1", null, headers: new Dictionary <string, string> { ["Origin"] = "https://fooboo.com/invalid" }); Debug.Assert(optionsResponse2?.Headers.TryGetValues("Access-Control-Allow-Origin", out var vals) == false); var optionsResponse3 = Http.Request("OPTIONS", "http://localhost:9000/rest/resource1", null); Debug.Assert(optionsResponse3?.IsSuccessStatusCode == true); Debug.Assert(optionsResponse3?.Content.ReadAsStringAsync().Result.Length > 15); #endregion #region XML Debug.Assert(Http.Request("GET", "http://localhost:9000/rest/resource2", headers: new Dictionary <string, string> { ["Accept"] = "application/xml" }).IsSuccessStatusCode); #endregion #region Error triggers // Debug.Assert(Http.Request("GET", "http://localhost:9000/rest/x9").StatusCode == HttpStatusCode.NotFound); // Debug.Assert(Http.Request("GET", "http://localhost:9000/rest/resource1/bfa=1").StatusCode == HttpStatusCode.NotFound); // Debug.Assert(Http.Request("GET", "http://localhost:9000/rest/resource1//limit=foo").StatusCode == HttpStatusCode.BadRequest); // Debug.Assert(Http.Request("POST", "http://localhost:9000/rest/resource1/bfa=1").StatusCode == HttpStatusCode.NotFound); // Debug.Assert(Http.Request("POST", "http://localhost:9000/rest/resource1").StatusCode == HttpStatusCode.BadRequest); // Debug.Assert(Http.Request("PATCH", "http://localhost:9000/rest/resource1").StatusCode == HttpStatusCode.BadRequest); // Debug.Assert(Http.Request("POST", "http://localhost:9000/rest/myres", new byte[] {1, 2, 3}).StatusCode == HttpStatusCode.MethodNotAllowed); #endregion #region Events bool customraised = false; Events.Custom <ENotification> .Raise += (s, o) => { Debug.Assert(s == null); Debug.Assert(o.Payload.Message?.Length == "Some message 1".Length); customraised = true; }; var notifications = Db.Transact(() => new[] { new Notification { Message = "Some message 1" }, new Notification { Message = "Some message 2" }, new Notification { Message = "Some message 3" }, new Notification { Message = "Some message 4" }, new Notification { Message = "Some message 5" } }); var events = notifications .Select(item => new ENotification(item)) .Union(new IEvent[] { new EString("This is the very important message!"), new EBytes(new byte[] { 4, 5, 1, 2, 3, 2, 3, 1, 5, 5, 1, 5, 1, 2, 3, 1, 2, 3, 1, 2, 1, 21, 5 }), new EStream(new MemoryStream(new byte[] { 4, 5, 1, 6, 7, 1, 8, 6, 8, 5, 8, 5, 8, 6, 8, 5 })) }) .ToList(); // Raises all events foreach (dynamic e in events) { e.Invoke(); } Task.Delay(5000).ContinueWith(_ => { Debug.Assert(wrstreamcalled); Debug.Assert(wrbytescalled); Debug.Assert(wrstringcalled); Debug.Assert(customraised); }).Wait(); #endregion var done = true; }