/// <summary> /// Создает екземпляры Запросов от контекста каждого объекта в Индексе /// </summary> /// <param name="templateElement">Метод с параметрами</param> private bool MakeRequestsFromObjIndex(xmlElement templateElement) { string XqueryForObjects = templateElement.GetAttribute("XqueryForObjects"); var objcs = Class.XQuery(XqueryForObjects); xmlDocument objs = new xmlDocument(objcs); if (objs.Root == null) { return(false); } foreach (var node in objs.Root.ChildElements) { Object sourceObject = GetSourceTargetObject(node); xmlDocument sourceXmlDocument = new xmlDocument(sourceObject.Root.XML); UpdateTemplateObject(sourceXmlDocument); if (sourceXmlDocument.Root.XQuery(templateElement.GetAttribute("NeedWork")) == "False") { continue; } // Формируем запрос к сторонней БД if (CreateAndFillRequest(sourceObject, sourceXmlDocument, templateElement)) { sourceObject.Save(sourceXmlDocument.Root.XML); } } return(true); }
/// <summary> /// Установка файлов в данные запроса /// </summary> /// <param name="fileList">Список файлов</param> /// <param name="fileKey">Ключ для параметров запроса</param> /// <param name="multipartFormDataContent">Поток для записи данных</param> private void SetFiles(string fileList, string fileKey, MultipartFormDataContent multipartFormDataContent) { if (sourceObject == null || sourceObject.IsDisposed) { throw new Exception("АпиКоннектор: Не удалось загрузить список файлов для отправки. Не установлен объект-контекст отправки"); } if (string.IsNullOrEmpty(fileList)) { return; } xmlDocument fileListDoc = new xmlDocument(fileList); foreach (xmlElement node in fileListDoc.Root.ChildElements) { try { fileElement = node; string filePath = GetFilePath(fileKey, multipartFormDataContent); } catch (Exception e) { Messages.showException(e); } } }
/// <summary> /// Подключает нужный выд запроса, создает его екземпляр и отправляет запрос /// </summary> /// <param name="paramsDoc">xmlDocument с параметрами по которым будет выполнятся запрос</param> /// <param name="sourceObject">Объект от которого выполняется REST запрос</param> internal void Connect(xmlDocument paramsDoc, Object sourceObject) { sourceObject.XmlDoc = null; sourceObject.Recalc(); // Обход найденных методов foreach (xmlElement sourceElement in paramsDoc.Root.ChildElements) { if (!String.IsNullOrEmpty(sourceElement.GetAttribute("XqueryForObjects"))) { Path = Class.FullId; SetSourceObj(); MakeRequestsFromObjIndex(sourceElement); } else { try { MakeSimpleRequests(sourceObject, sourceElement); } catch (System.IO.FileNotFoundException e) { Messages.showException(e); } } } }
/// <summary> /// Установка данных запросов /// </summary> /// <param name="sourceXmlDocument">xmlDocument от которого отправляется запрос</param> /// <param name="templateElement">xmlElement с входящими настройками запроса</param> /// <param name="request">экземпляр запроса</param> private void SetRequestData(xmlDocument sourceXmlDocument, xmlElement templateElement, Request request) { string RequestFormat = templateElement.GetAttribute("RequestFormat"); string dataContent = ""; if (templateElement.GetAttribute("MethodQuery") != "") { dataContent = sourceXmlDocument.Root.XQuery(templateElement.GetAttribute("MethodQuery")); } if (request.ContentType == "multipart/form-data") { //Устанавливаем данные для multipart/form-data-запросов request.DataContent = request.SetMultipartFormData(); } if (string.IsNullOrEmpty(RequestFormat) || RequestFormat == "XML" || RequestFormat == "Without conversion") { //Устанавливаем данные для POST-запросов request.SetData(dataContent); } else { if (!string.IsNullOrEmpty(dataContent)) { XmlDocument doc = new XmlDocument(); doc.LoadXml(dataContent); dataContent = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.None, true); request.SetData(dataContent.Replace(",null", "")); } } }
/// <summary> /// Создает екземпляры Запросов от контекста каждого объекта в Индексе /// </summary> /// <param name="sourceElement">Метод с параметрами</param> void MakeRequestsFromObjIndex(xmlElement sourceElement) { string XqueryForObjects = sourceElement.GetAttribute("XqueryForObjects"); var objcs = Class.XQuery(XqueryForObjects); xmlDocument objs = new xmlDocument(objcs); if (objs.Root == null) { return; } foreach (var i in objs.Root.ChildElements) { Object CurrentObj = GetCurrentTargetObject(i); UpdateSourceObject(CurrentObj); if (CurrentObj.XQuery(sourceElement.GetAttribute("NeedWork")) == "False") { continue; } Request request = new Request(SourceObject, CurrentObj, sourceElement) { TargetClass = Class }; SetRequestData(CurrentObj, sourceElement, request); Session.ExecuteQuery(request); } }
/// <summary> /// Подключает нужный выд запроса, создает его екземпляр и отправляет запрос /// </summary> /// <param name="paramsDoc">xmlDocument с параметрами по которым будет выполнятся запрос</param> /// <param name="sourceObject">Объект от которого выполняется REST запрос</param> internal void Connect(Object sourceObject, xmlDocument paramsDoc) { bool needSave = false; xmlDocument sourceXmlDocument = new xmlDocument(sourceObject.Root.XML); // Обход найденных объектов ApiConnector`a с параметрами foreach (xmlElement templateElement in paramsDoc.Root.ChildElements) { if (!String.IsNullOrEmpty(templateElement.GetAttribute("XqueryForObjects"))) { Path = Class.FullId; SetSourceObj(); MakeRequestsFromObjIndex(templateElement); } else { try { needSave = needSave || MakeSimpleRequests(sourceObject, sourceXmlDocument, templateElement); } catch (System.IO.FileNotFoundException e) { Messages.showException(e); } } } if (needSave) { sourceObject.Save(sourceXmlDocument.Root.XML); } }
/// <summary> /// Производит поиск методов ApiConnector`a которые работаю по таймеру(ByTimer) /// </summary> void AfterTimer() { try { Path = Class.FullId; SetSourceObj(); // Выбираем все методы, содержащие ByTimer if (SourceObject.Root.XQuery("//Params[contains(@EventType,'ByTimer')]") == null) { Messages.showException(new Exception("Не найдено объекта класса ApiConnector для исполнения запроса от даного класса")); return; } xmlDocument paramsDoc = new xmlDocument( "<PARAMS>" + SourceObject.Root.XQuery("//Params[contains(@EventType,'ByTimer')]") + "</PARAMS>" ); Connect(paramsDoc, SourceObject); } catch (Exception ex) { Messages.showMessage("АпиКоннектор , Не удалось отправить запрос по таймеру, " + ex.Message); } }
/// <summary> /// Обновление Объекта /// </summary> /// <param name="sourceXmlDocument">Документ с даными дляобновления</param> private void UpdateTemplateObject(xmlDocument sourceXmlDocument) { using (new UpdateObject(TemplateObject)) { TemplateObject.Root.SetAttribute("ObjDate", sourceXmlDocument.Root.XQuery(TemplateObject.GetAttrValue("XquryObj"))); } // Сохраняем изменения в статическом объекте TemplateObject.Save(); }
/// <summary> /// Создание запроса и заполение его данными /// </summary> /// <param name="sourceObject">Объект от которого отправляется запрос</param> /// <param name="sourceXmlDocument">xmlDocument от которого отправляется запрос</param> /// <param name="templateElement">xmlElement с входящими настройками запроса</param> /// <returns></returns> private bool CreateAndFillRequest(Object sourceObject, xmlDocument sourceXmlDocument, xmlElement templateElement) { Request request = new Request(sourceObject, TemplateObject, sourceXmlDocument, templateElement) { TargetClass = Class }; SetRequestData(sourceXmlDocument, templateElement, request); // Выполняем запрос к сторонней БД return(Session.ExecuteQuery(request)); }
/// <summary> /// Производит обработку и конвертацию ответу ответа /// </summary> /// <param name="request">REST Запрос</param> /// <param name="responseBody">Тело ответа</param> /// <returns>Строка ответа REST запроса</returns> internal static string ResponseProcessing(Request request, string responseBody) { xmlDocument xDoc = new xmlDocument(ConvertingResponce(request, responseBody)); ApiLogger.Log(request.SourceObject, request.SourceElement, xDoc, request.URL, request.DataString); if (request.TargetObject != null) { WriteResponce(xDoc, request); } return(responseBody); }
/// <summary> /// Производит запись ответа от сервера в вызывающий объект /// </summary> /// <param name="xDoc">Документ от которого будет сохранятся объект</param> /// <param name="request">Запрос</param> internal static void WriteResponse(xmlDocument xDoc, Request request) { string XQuryOneObj = request.TemplateElement.GetAttribute("XquryXML").Replace("[#OBJXML#]", request.SourceXmlDocument.Root.XML); string NewXML = xDoc.XQuery(XQuryOneObj); request.SourceXmlDocument.ReplaceChild(new xmlDocument(NewXML).Root, request.SourceXmlDocument.Root); string AfterSaveXQ = request.TemplateElement.GetAttribute("AfterSaveXQ"); if (!string.IsNullOrEmpty(AfterSaveXQ)) { xDoc.XQuery(AfterSaveXQ.Replace("[#OBJXML#]", request.SourceXmlDocument.Root.XML)); } }
/// <summary> /// Производит запись ответа от сервера в вызывающий объект /// </summary> /// <param name="xDoc">Документ от которого будет сохранятся объект</param> /// <param name="request">Запрос</param> internal static void WriteResponce(xmlDocument xDoc, Request request) { string XQuryOneObj = request.SourceElement.GetAttribute("XquryXML").Replace("[#OBJXML#]", request.TargetObject.XML); string NewXML = xDoc.XQuery(XQuryOneObj); request.TargetObject.Save(NewXML); string AfterSaveXQ = request.SourceElement.GetAttribute("AfterSaveXQ"); if (!string.IsNullOrEmpty(AfterSaveXQ)) { xDoc.XQuery(AfterSaveXQ.Replace("[#OBJXML#]", request.TargetObject.XML)); } }
/// <summary> /// Конвертация в JSON /// </summary> /// <param name="responce">Ответ запроса</param> /// <param name="type">Тип в который нужно конвертировать</param> /// <returns>Возвращает конвертированый ответ</returns> static string ConvertTo(string responce, string type) { string convertingResponce = responce; if (type == "JSON") { // Пишем в лог URL запроса, данные запроса, ответ от сервера XNode node = JsonConvert.DeserializeXNode(responce, "Root"); xmlDocument xDoc = new xmlDocument(node.ToString()); convertingResponce = xDoc.XML; } return(convertingResponce); }
/// <summary> /// /// </summary> /// <param name="sourceObject">Объект от которого отправляется запрос</param> /// <param name="sourceXmlDocument">xmlDocument от которого отправляется запрос</param> /// <param name="templateElement">xmlElement с входящими настройками запроса</param> /// <returns></returns> private bool MakeSimpleRequests(Object sourceObject, xmlDocument sourceXmlDocument, xmlElement templateElement) { if (sourceXmlDocument.Root.XQuery(templateElement.GetAttribute("NeedWork")) == "False") { Messages.showMessage("АпиКоннектор: NeedWork = false. XQ - " + templateElement.GetAttribute("NeedWork")); return(false); } Messages.showMessage("АпиКоннектор: Выполнение запроса NeedWork. XQ - " + templateElement.GetAttribute("NeedWork")); if (!string.IsNullOrEmpty(TemplateObject.GetAttrValue("XquryObj"))) { UpdateTemplateObject(sourceXmlDocument); } // Формируем запрос к сторонней БД return(CreateAndFillRequest(sourceObject, sourceXmlDocument, templateElement)); }
internal Request(Object sourceObject, Object templateObject, xmlDocument sourceXmlDocument, xmlElement templateElem) { clientHendler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return(true); }; httpClient = new HttpClient(clientHendler); TemplateObject = templateObject; SourceObject = sourceObject; SourceXmlDocument = sourceXmlDocument; TemplateElement = templateElem; ContentType = TemplateElement.GetAttribute("ContentType"); MethodType = TemplateElement.GetAttribute("MethodDispatch"); SetHeaders(); }
/// <summary> /// Возвращает объект класса APIConnector /// </summary> private void SetSourceObj() { if (SourceClass == null) { ErrorProvider.ShowError("Ошибка при получении SourceObject. Отсутствует SourceClass", "Ошибка при получении свойства"); return; } Class APIConnectorClass = Domain.GetClass(IdAPIConnectorClass); // Поиск объекта в APIConnector'е по FullId вызывающего объекта xmlDocument xDoc = new xmlDocument( APIConnectorClass.XQuery("PACK/OBJECT[@IsActive='True']/Target[contains('" + Path + "',@link)]/..") ); TemplateObject = APIConnectorClass.FindObject(xDoc.SelectElement("OBJECT")); }
/// <summary> /// Производит поиск методов ApiConnector`a которые работаю по таймеру(ByTimer) /// </summary> private void AfterTimer() { Path = Class.FullId; SetSourceObj(); // Выбираем все методы, содержащие ByTimer if (TemplateObject.Root.XQuery("//Params[contains(@EventType,'ByTimer')]") == null) { Messages.showException(new Exception("Не найдено объекта класса ApiConnector для исполнения запроса от даного класса")); return; } xmlDocument paramsDoc = new xmlDocument( "<PARAMS>" + TemplateObject.Root.XQuery("//Params[contains(@EventType,'ByTimer')]") + "</PARAMS>" ); Connect(TemplateObject, paramsDoc); }
/// <summary> /// Запись Лога об успешном выполнении /// </summary> /// <param name="SourceObj">Объект ApiConnector`a c параметрами REST запроса</param> /// <param name="SourceElement">Елемент объекта ApiConnector`a c параметрами REST запроса</param> /// <param name="xDoc">xmlDocument ответа</param> /// <param name="RequestURL">URL Запроса</param> /// <param name="RequestData">Данные Запроса</param> internal static void Log(Object SourceObj, xmlElement SourceElement, xmlDocument xDoc, string RequestURL, string RequestData) { // Выполняем поиск объекта для ведения логов Class cls = SourceObj.Class.Domain.FindClass(SourceObj.Root.XQuery("string(LogClass/@link)")); string Xqury = SourceElement.GetAttribute("LogXqury"); string LogXml = xDoc.XQuery(Xqury); if (cls != null) { if (!String.IsNullOrEmpty(LogXml)) { CreateLog(cls, RequestURL, RequestData, LogXml); } else { CreateLog(cls, RequestURL, RequestData, xDoc); } } }
/// <summary> /// Производит обработку и конвертацию ответу ответа /// </summary> /// <param name="request">REST Запрос</param> /// <param name="responseBody">Тело ответа</param> /// <returns>Строка ответа REST запроса</returns> internal static bool ResponseProcessing(Request request, string responseBody) { xmlDocument xDoc = new xmlDocument(ConvertingResponce(request, responseBody)); string requestData; if (request.DataContent == null) { requestData = ""; } else { requestData = request.DataContent.ToString(); } ApiLogger.Log(request.TemplateObject, request.TemplateElement, xDoc, request.URL, requestData); if (request.SourceXmlDocument != null) { WriteResponse(xDoc, request); return(true); } return(false); }
/// <summary> /// Записывает данные запроса с тыпом File /// </summary> /// <param name="writingStream">Поток для записи данных в байты</param> void WriteFileParams(Stream writingStream) { string fileHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; using (xmlNodeList fileList = template.SelectNodes("FormDatas[@Type='File' or @Type='FileLibrary']")) { foreach (xmlElement fileParam in fileList) { string fileKey = GetParamKey(fileParam); string fileValue = GetParamValue(fileParam); if (string.IsNullOrEmpty(fileValue)) { continue; } xmlDocument fileListDoc = new xmlDocument(fileValue); foreach (xmlElement node in fileListDoc.Root.ChildElements) { try { string filePath = GetFilePath(node); string fileName = filePath.Split('\\')[filePath.Split('\\').Length - 1]; writingStream.Write(boundarybytes, 0, boundarybytes.Length); byte[] fileHeaderbytes = Encoding.UTF8.GetBytes(string.Format(fileHeaderTemplate, fileName, fileName, "application/octet-stream")); writingStream.Write(fileHeaderbytes, 0, fileHeaderbytes.Length); writingStream.Write(fileBytes, 0, fileBytes.Length); } catch (Exception e) { Messages.showException(e); } } } } }
/// <summary> /// Создание лога с ответом /// </summary> /// <param name="cls">Класс в котором нужно создать лог</param> /// <param name="requestURL">URL Запроса</param> /// <param name="requestData">Данные Запроса</param> /// <param name="xDoc">Документ ответа запроса</param> internal static void CreateLog(Class cls, string requestURL, string requestData, xmlDocument xDoc) { // Создём новый объект в логах Object logObject = cls.CreateObject(); logObject.Root.SetAttribute("Response", xDoc.XML); logObject.Root.SetAttribute("RequestURL", requestURL); logObject.Root.SetAttribute("RequestData", requestData); // Сохраняем объект логов logObject.Save(); }