/// <summary> /// Вызвать компонент, написанный на Js /// </summary> /// <param name="componentName">название компонента который нужно вызвать</param> /// <param name="methodName">метод который нужно вызвать у данного компонента</param> /// <param name="methodPayload">Параметр, который нужно передать в метод компонента</param> public TResult CallExternalComponent <TResult>(string componentName, string methodName, object methodPayload) { using var context = GetContext(); var res = context.JsCallWorker.CallExternal(componentName, methodName, methodPayload); return(ZooSerializer.Deserialize <TResult>(res)); }
private async Task <CallOpenApiWorkerMethodResponse> CallResult(RemoteJsOpenApiDocs remoteApi, CallOpenApiWorkerMethod requestModel) { var responseRecord = await HttpClient.PostAsync(remoteApi.Description.HostUrl, remoteApi.Description.Name, HttpPaths.HandleCall, requestModel); ExecutionContext.ExecutionLogs.Add(new JsExecutionLog { EventIdName = EventIds.CallRemoteApi.CallLogged, Message = "Логгирование удаленного запроса", DataJson = ZooSerializer.Serialize(responseRecord) }); try { //Task<RemoteApiResponseRecord> PostAsync<TRequest>(string hostUrl, string hostName, string path, TRequest request) return(responseRecord.GetResult <CallOpenApiWorkerMethodResponse>()); } catch (Exception ex) { ExecutionContext.ExecutionLogs.Add(new JsExecutionLog { EventIdName = EventIds.CallRemoteApi.ResponseDeserializationError, Message = "Ошибка при дессериализации", DataJson = ZooSerializer.Serialize(responseRecord) }); return(new CallOpenApiWorkerMethodResponse { IsSucceeded = false, ExcepionData = ExcepionData.Create(ex) }); } }
/// <summary> /// Вызвать внутренний сервис, написанный на Js /// </summary> /// <param name="workerName">название класса рабочего который нужно вызвать</param> /// <param name="method">метод который нужно вызвать у данного рабочего</param> /// <param name="methodParams">Параметры метода</param> public TResult CallWorkerMethod <TResult>(string workerName, string method, params object[] methodParams) { using var context = GetContext(); var res = context.JsCallWorker.Call(workerName, method, methodParams); return(ZooSerializer.Deserialize <TResult>(res)); }
public async Task Test(int arg1, int arg2) { var serviceCollection = new ServiceCollection(); new JsExecutorBuilder(serviceCollection).AddExternalComponent(new ExternalJsComponent { ComponentName = "Test", Script = "function Calculator(model) { \n" + "return model.Arg1 + model.Arg2; \n }" }) .Build(); var jsExecutor = serviceCollection.BuildServiceProvider().GetRequiredService <JsExecutor>(); var script = $"var res = api.CallExternal('Test', 'Calculator', {{ 'Arg1': {arg1}, 'Arg2': {arg2} }}); \n"; script += "console.log(res)"; var result = await jsExecutor.RunScriptDetaiiled(script); Assert.IsTrue(result.IsSucceeded); Assert.IsTrue(result.ConsoleLogs.Count == 1); var logValue = result.ConsoleLogs.First().SerializedVariables.First(); var expectedRes = (double)(arg1 + arg2); var directCallResult = jsExecutor.CallExternalComponent <int>("Test", "Calculator", new { Arg1 = arg1, Arg2 = arg2 }); Assert.AreEqual(expectedRes, directCallResult); Assert.AreEqual(directCallResult, ZooSerializer.Deserialize <int>(logValue.DataJson)); }
public async Task Test1() { var serviceCollcetion = new ServiceCollection(); var script = $"var t = api.Call(\"{ProductGroupJsWorker.WorkerName}\"," + " \"AddProductToGroup\", { ProductGroupId: \"d8c8cf9b-1d9b-4199-a85e-615edd64b4d7\", ProductId: 1 });"; script += "\n console.log('Result', t)"; new JsExecutorBuilder(serviceCollcetion) .AddJsWorker(new ProductGroupJsWorker()) .Build(); var srvProvider = serviceCollcetion.BuildServiceProvider(); var executor = srvProvider.GetRequiredService <JsExecutor>(); var result = await executor.RunScriptDetaiiled(script); Assert.IsTrue(result.IsSucceeded); Assert.AreEqual(1, result.ConsoleLogs.Count); var log = result.ConsoleLogs.First(); var json = ZooSerializer.Serialize(ProductGroupJsWorker.AddProductToGroup(null)); Assert.AreEqual(log.SerializedVariables.Last().DataJson, json); }
/// <summary> /// Вызвать внутренний метод сервис /// </summary> /// <param name="workerName">название класса рабочего который нужно вызвать</param> /// <param name="method">метод который нужно вызвать у данного рабочего</param> /// <param name="methodParams">Параметры метода</param> public string Call(string workerName, string method, params dynamic[] methodParams) { var worker = Components.GetJsWorker(workerName, ExecutionContext); var res = worker.HandleCall(method, ServiceProvider, new JsWorkerMethodCallParameters(methodParams), ExecutionContext, Logger).Result; return ZooSerializer.Serialize(res); }
internal TResult GetResult <TResult>() { if (!IsSuccessfull()) { throw new Exception("Ответ не является успешным"); } return(ZooSerializer.Deserialize <TResult>(Response)); }
public T GetParameter <T>() { var param = _parameters[_currentIndex]; _currentIndex++; var json = ZooSerializer.Serialize(param); return(ZooSerializer.Deserialize <T>(json)); }
public void TestChangeFileName() { var serialaizer = new ZooSerializer(); //Путь к файлу до изменения Assert.AreEqual(@"..\..\..\Serialization\Zoo.xml", serialaizer.FileName); //Путь к файлу после изменения serialaizer.FileName = @"..\..\..\Serialization\NewZoo.xml"; Assert.AreEqual(@"..\..\..\Serialization\NewZoo.xml", serialaizer.FileName); }
/// <summary> /// Вызвать внешний сервис, определенный через Js /// </summary> /// <param name="remoteName"></param> /// <param name="workerName"></param> /// <param name="methodName"></param> /// <param name="methodParams"></param> /// <returns></returns> public async Task <string> CallRemoteWorkerMethod(string remoteName, string workerName, string methodName, params dynamic[] methodParams) { if (!RemoteDocs.ContainsKey(remoteName)) { throw WriteLogAndGetException(new JsExecutionLog { EventIdName = EventIds.CallRemoteApi.RemoteApiNotFound, Message = $"В системе нет зарегистрированного внешнего апи с именем '{remoteName}'", DataJson = null }); } var remoteApi = RemoteDocs[remoteName]; var worker = remoteApi.Docs.Workers.FirstOrDefault(x => x.WorkerName == workerName); if (worker == null) { throw WriteLogAndGetException(new JsExecutionLog { EventIdName = EventIds.CallRemoteApi.NoWorkerWithNameFound, Message = $"Во внешнем апи '{remoteName}' не зарегистрирован рабочий класс с именем '{workerName}'", DataJson = null }); } var method = worker.Methods.FirstOrDefault(x => x.MethodName == methodName); if (method == null) { throw new InvalidOperationException($"Во внешнем апи '{remoteName}' в рабочем классе с именем '{workerName}' не обнаружен метож '{methodName}'"); } var requestModel = new CallOpenApiWorkerMethod { WorkerName = workerName, MethodName = methodName, SerializedParameters = methodParams?.Select(ZooSerializer.Serialize).ToArray() ?? Array.Empty <string>() }; var callResult = await CallResult(remoteApi, requestModel); if (!callResult.IsSucceeded) { throw WriteLogAndGetException(new JsExecutionLog { EventIdName = EventIds.CallRemoteApi.CallNotSucceeded, Message = "Ошибка при выполнении удалленного запроса", DataJson = ZooSerializer.Serialize(callResult) }); } return(callResult.ResponseJson); }
public void TestSerializeZoo() { var serialaizer = new ZooSerializer(); //Успешная попытка сериализации пустого зоопарка var zoo = new Zoo("name", "address"); serialaizer.SerializeZoo(zoo); Assert.AreEqual(true, File.Exists(serialaizer.FileName)); var zoo2 = serialaizer.DeserializeZoo(); Assert.AreEqual(zoo.Name, zoo2.Name); Assert.AreEqual(zoo.Address, zoo2.Address); Assert.AreEqual(0, zoo2.GetListOfAviaries().Count); Assert.AreEqual(0, zoo2.GetListOfAnimals().Count); //Успешная попытка сериализации непустого зоопарка zoo.AddAviary(new Cage(CageType.WithRocks)); zoo.AddAviary(new Pool(PoolType.IndoorsPool)); zoo.AddAviary(new Yard(YardType.Plain)); zoo.SettleAnimal(new Mammal(MammalDetachment.Carnivora, "family1", "genus1", "species1"), zoo.GetListOfAviaries(AviaryType.Cage).First()); zoo.SettleAnimal(new Bird(BirdDetachment.Anseriformes, "family2", "genus2", "species2"), zoo.GetListOfAviaries(AviaryType.Pool).First()); zoo.SettleAnimal(new Mammal(MammalDetachment.Artiodactyla, "family3", "genus3", "species3"), zoo.GetListOfAviaries(AviaryType.Yard).First()); serialaizer.SerializeZoo(zoo); zoo2 = serialaizer.DeserializeZoo(); Assert.AreEqual(3, zoo2.GetListOfAviaries().Count); Assert.AreEqual(3, zoo2.GetListOfAnimals().Count); Assert.AreEqual(true, zoo2.GetListOfAviaries(AviaryType.Cage).All(aviary => (aviary as Cage).Kind == CageType.WithRocks)); Assert.AreEqual(true, zoo2.GetListOfAviaries(AviaryType.Pool).All(aviary => (aviary as Pool).Kind == PoolType.IndoorsPool)); Assert.AreEqual(true, zoo2.GetListOfAviaries(AviaryType.Yard).All(aviary => (aviary as Yard).Kind == YardType.Plain)); Assert.AreEqual(true, zoo2.GetListOfAnimals(AnimalClass.Mammal).Any(animal => (animal as Mammal).Detachment == MammalDetachment.Carnivora)); Assert.AreEqual(true, zoo2.GetListOfAnimals(AnimalClass.Bird).Any(animal => (animal as Bird).Detachment == BirdDetachment.Anseriformes)); Assert.AreEqual(true, zoo2.GetListOfAnimals(AnimalClass.Mammal).Any(animal => (animal as Mammal).Detachment == MammalDetachment.Artiodactyla)); //Неуспешная попытка сериализации несуществующего зоопарка try { serialaizer.SerializeZoo(null); Assert.Fail(); } catch (ArgumentException) { } //Неуспешная попытка сериализации зоопарка в файл с некорректным путем try { serialaizer.FileName = @"??"; serialaizer.SerializeZoo(zoo); Assert.Fail(); } catch (ArgumentException) { } }
private JsSerializedVariable ToJsSerializedVariable(object obj) { if (obj == null) { return(new JsSerializedVariable { DataJson = "null", TypeFullName = null }); } return(new JsSerializedVariable { DataJson = ZooSerializer.Serialize(obj), TypeFullName = obj.GetType().FullName }); }
/// <inheritdoc /> public Task <HttpResponseRecord> PostAsync <TRequest>(string hostUrl, string hostName, string path, TRequest request) { var json = ZooSerializer.Serialize(request); var url = $"{hostUrl}{path}"; var result = new HttpResponseRecord { HostName = hostName, HostUrl = hostUrl, RequestUrl = url, Request = json, RequestMethod = "POST" }; return(CallInner(result, httpClient => HttpClient.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json")))); }
public void TestFullVersionConstructor() { //Корректное создание сериализатора с правильным путем к файлу загрузки/выгрузки var serialaizer = new ZooSerializer(@"..\..\..\Serialization\NewZoo.xml"); Assert.AreEqual(@"..\..\..\Serialization\NewZoo.xml", serialaizer.FileName); //Попытка указать пустой путь к файлу для выгрузки/загрузки (будет использован путь по умолчанию) var serialaizer2 = new ZooSerializer(""); Assert.AreEqual(@"..\..\..\Serialization\Zoo.xml", serialaizer2.FileName); //Попытка указать некорректный путь к файлу для выгрузки/загрузки (будет использован путь по умолчанию) var serialaizer3 = new ZooSerializer(" "); Assert.AreEqual(@"..\..\..\Serialization\Zoo.xml", serialaizer3.FileName); }
private void DeserializeZoo() { Console.Clear(); var serializer = new ZooSerializer(); try { _zoo = serializer.DeserializeZoo(); Console.WriteLine("Зоопарк успешно десериализован из файла {0}", serializer.FileName); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine("Зоопарк не был десериализован"); } Console.WriteLine("------------------------------------------------"); Console.WriteLine("Нажмите любую клавишу для возврата в меню..."); Console.ReadKey(); }
public async Task CallAfterCall(double arg1, double arg2, double delimeter) { var serviceCollection = new ServiceCollection(); new JsExecutorBuilder(serviceCollection).AddExternalComponent(new ExternalJsComponent { ComponentName = "Test", Script = "function Calculator(model) { \n" + "var t = model.Arg1 + model.Arg2;\n" + "var s = api.CallExternal('Test2', 'CalculatorNew', { 'Arg1': t, 'Arg2': " + $"{delimeter}" + " });\n" + "return s;\n" + " }" }) .AddExternalComponent(new ExternalJsComponent { ComponentName = "Test2", Script = "function CalculatorNew(model) { \n" + "return model.Arg1 / model.Arg2; }" }) .Build(); var jsExecutor = serviceCollection.BuildServiceProvider().GetRequiredService <JsExecutor>(); var script = "var res = api.CallExternal('Test', 'Calculator', { 'Arg1': " + $"{arg1}, 'Arg2': {arg2}" + " });\n"; script += "console.log(res);\n"; var result = await jsExecutor.RunScriptDetaiiled(script); Assert.IsTrue(result.IsSucceeded); var resp = result; Assert.IsTrue(resp.ConsoleLogs.Count == 1); var logVar = resp.ConsoleLogs.First().SerializedVariables.First(); var directCallValue = jsExecutor.CallExternalComponent <double>("Test", "Calculator", new { Arg1 = arg1, Arg2 = arg2 }); var expectedValue = (arg1 + arg2) / delimeter; Assert.AreEqual(directCallValue, expectedValue); Assert.AreEqual(expectedValue, ZooSerializer.Deserialize <double>(logVar.DataJson)); }
/// <summary> /// /// </summary> /// <param name="componentName"></param> /// <param name="methodName"></param> /// <param name="methodPayLoad"></param> /// <returns></returns> private async Task<string> CallExternalUnSafe(string componentName, string methodName, object methodPayLoad) { var component = await Components.GetExternalComponent(componentName, ExecutionContext); var uid = $"n{Guid.NewGuid()}".Replace("-", "_"); var payloadJson = ZooSerializer.Serialize(methodPayLoad); var variableScript = $"{uid} = {payloadJson};"; var engine = ExecutionContext.CreateEngine(); var variable = engine.Execute(variableScript).GetValue(uid); var methodExpr = engine.Execute(component.Script).GetValue(methodName); if (methodExpr.Type == Jint.Runtime.Types.Undefined) { throw new Exception($"Метод '{methodName}' не найден в компоненте '{componentName}'"); } var resultJson = ZooSerializer.Serialize(methodExpr.Invoke(variable).ToObject()); ExecutionContext.ExecutionLogs.Add(new JsExecutionLog { EventIdName = EventIds.JsExecutorComponents.CallExternalComponentOnResult, Message = "Завершен вызов внешнего компонента", DataJson = JsonConvert.SerializeObject(new { ComponentName = componentName, MethodName = methodName, PayloadJson = payloadJson, ResultJson = resultJson }) }); return resultJson; }
/// <summary> /// Вызвать метод рабочего класса. /// <para></para> /// Данный метод не возвращает исключений. Его нужно испльзовать как внешюю точку доступа. /// </summary> /// <param name="requestModel"></param> /// <returns></returns> public CallOpenApiWorkerMethodResponse CallWorkerMethod(CallOpenApiWorkerMethod requestModel) { if (requestModel == null) { return(new CallOpenApiWorkerMethodResponse { IsSucceeded = false, ExcepionData = ExcepionData.Create(new Exception("request is null onjcet")) }); } var parameters = new JsWorkerMethodCallParametersFromSerialized(requestModel.SerializedParameters); try { var jsContext = GetContext(); using var scope = ServiceProvider.CreateScope(); var result = Components .GetJsWorker(requestModel.WorkerName, jsContext) .HandleCall(requestModel.MethodName, scope.ServiceProvider, parameters, jsContext, Logger); return(new CallOpenApiWorkerMethodResponse { IsSucceeded = true, ResponseJson = ZooSerializer.Serialize(result.Result) }); } catch (Exception ex) { Logger.LogError(ex, "CallWorkerMethod.Error"); return(new CallOpenApiWorkerMethodResponse { IsSucceeded = false, ExcepionData = ExcepionData.Create(ex) }); } }
/// <summary> /// Вызвать внешний сервис, определенный через Js /// </summary> /// <param name="componentName"></param> /// <param name="methodName"></param> /// <param name="methodPayLoad"></param> /// <returns></returns> public string CallExternal(string componentName, string methodName, object methodPayLoad) { try { var result = CallExternalUnSafe(componentName, methodName, methodPayLoad).GetAwaiter().GetResult(); return result; } catch (Exception ex) { var mes = $"Произошла ошибка при вызове внешнего компонента. Название внешнего компонента = '{componentName}'.\n " + $"Название метода = '{methodName}'.\n"; if (methodPayLoad != null) { mes += $"Параметр метода = {ZooSerializer.Serialize(methodPayLoad)}.\n "; } else { mes += $"Параметр метода = [Метод был вызван без параметра].\n "; } throw new Exception(mes + ex.Message); } }
public void TestCall(int param1, int param2, double expectedResult) { var services = new ServiceCollection(); new JsExecutorBuilder(services) .AddJsWorker(new CalculatorJsWorker()) .Build(); var srvProvider = services.BuildServiceProvider(); var jsExecutor = srvProvider.GetRequiredService <JsExecutor>(); var result = jsExecutor.CallWorkerMethod(new Models.OpenApi.CallOpenApiWorkerMethod { WorkerName = "Calculator", MethodName = "Divide", SerializedParameters = new string[] { param1.ToString(), param2.ToString() } }); Assert.IsTrue(result.IsSucceeded); var expetedDataResult = ZooSerializer.Serialize(expectedResult); Assert.AreEqual(expetedDataResult, result.ResponseJson); }
public void TestSimpleConstructor() { var serialaizer = new ZooSerializer(); Assert.AreEqual(@"..\..\..\Serialization\Zoo.xml", serialaizer.FileName); }