/// <summary> /// Stored Procedure를 수행하고, OUTPUT, RETURN_VALUE를 반환한다. /// </summary> /// <param name="request">요청 항목</param> /// <param name="responseDocument">응답 정보</param> protected virtual void ExecuteProcedure(XdsRequestItem request, XdsResponseDocument responseDocument) { if (IsDebugEnabled) { log.Debug("프로시저를 실행합니다... requestId=[{0}], procedure=[{1}], requestType=[{2}], responseType=[{3}]", request.Id, request.Query, request.RequestKind, request.ResponseKind); } try { var maxSequence = Math.Max(1, request.Values.Count); for (var seqId = 0; seqId < maxSequence; seqId++) { var adoParameters = PrepareParameters(request, seqId).ToArray(); using (var cmd = Ado.GetProcedureCommand(request.Query)) { Ado.ExecuteNonQuery(cmd, adoParameters); var response = responseDocument.AddResponseItem(XmlDataResponseKind.Scalar, request.Id, seqId); ExtractParameters(AdoTool.GetOutputParameters(Ado.Db, cmd), response, seqId); } } } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorException(string.Format("프로시저 실행에 실패했습니다. procedure=[{0}]", request.Query), ex); } throw; } if (IsDebugEnabled) { log.Debug("프로시저 실행에 성공했습니다. procedure=[{0}]", request.Query); } }
/// <summary> /// /// </summary> /// <param name="requestStream"></param> /// <param name="productName"></param> /// <param name="serializer"></param> /// <returns></returns> public static Stream ExecuteStreamInternal(Stream requestStream, string productName, ISerializer serializer) { XdsResponseDocument xdsResponse = null; MemoryStream result = null; try { Guard.Assert(requestStream != null && requestStream.Length > 0, "요청 정보가 없습니다."); CheckProductExists(productName); var xdsRequest = (XdsRequestDocument)serializer.Deserialize(requestStream.ToBytes()); xdsResponse = XmlDataServiceFacade.Execute(xdsRequest, productName); } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorException("예외가 발생했습니다.", ex); } if (xdsResponse == null) { xdsResponse = new XdsResponseDocument(); } xdsResponse.ReportError(ex); } finally { result = new MemoryStream(serializer.Serialize(xdsResponse)); } return(result); }
/// <summary> /// 응답 문서를 <see cref="XmlSerializer"/>를 이용해 직렬화를 수행하여 <see cref="XmlDocument"/>로 반환합니다. /// </summary> /// <param name="responseDocument">응답문서</param> /// <param name="enc">Encoding 방식</param> /// <returns>요청문서의 Xml 직렬화된 정보를 가진 <see cref="XmlDocument"/> 인스턴스</returns> public static XmlDocument ToXmlDocument(this XdsResponseDocument responseDocument, Encoding enc) { XmlDocument document; if (XmlTool.Serialize(responseDocument, out document)) { return(document); } return(new XmlDocument()); }
/// <summary> /// 지정된 예외 정보를 응답 문서(<see cref="XdsResponseDocument"/>)에 등록한다. /// </summary> /// <param name="responseDocument">응답 문서</param> /// <param name="ex">등록할 예외 정보</param> public static void ReportError(this XdsResponseDocument responseDocument, Exception ex) { if (ex != null) { responseDocument.Errors.AddError(ex); if (log.IsWarnEnabled) { log.WarnException("예외가 발생하여 응답문서에 예외정보를 추가했습니다.", ex); } } }
/// <summary> /// 응답문서를 XmlSerializer를 통해 스트림으로 빌드합니다. /// </summary> /// <param name="responseDocument">응답문서</param> /// <param name="enc">Encoding 방식</param> /// <returns>응답문서의 Xml 직렬화된 정보를 가진 Stream</returns> public static Stream ToStream(this XdsResponseDocument responseDocument, Encoding enc) { var stream = new MemoryStream(); XmlTool.Serialize(responseDocument, stream); if (stream.CanSeek && stream.Position != 0) { stream.Position = 0; } return(stream); }
/// <summary> /// aspx, ashx의 <see cref="HttpContext"/>로부터 XdsRequestDocument를 만들고, /// 처리를 수행 한 후, XdsResponseDocument를 HttpContext의 Response.OutputStream에 Write를 수행합니다. /// </summary> /// <param name="context"></param> public static void Execute(HttpContext context) { context.ShouldNotBeNull("context"); if (IsDebugEnabled) { log.Debug(@"Execution for request from HttpContext is starting..."); } var request = context.Request; var productName = request.GetProductName(); var compress = request.GetUseCompress(); var security = request.GetUseSecurity(); var serializer = XmlDataServiceTool.GetSerializer(compress, security); XdsResponseDocument result = null; try { CheckProductExists(productName); Guard.Assert(request.TotalBytes > 0, "처리할 요청정보가 제공되지 않았습니다."); var requestBytes = request.InputStream.ToBytes(); var xdsRequest = ((byte[])serializer.Deserialize(requestBytes)).ConvertToXdsRequestDocument(); // var xdsRequest = XmlTool.Deserialize<XdsRequestDocument>(request.InputStream); result = Execute(xdsRequest, productName); } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorException("요청처리 중 예외가 발생했습니다.", ex); } // 예외정보를 Client에게도 보낸다. result = result ?? new XdsResponseDocument(); result.ReportError(ex); } finally { if (result != null) { WriteResponse(context.Response, result, serializer); } } if (IsDebugEnabled) { log.Debug("Execution for request from HttpContext is finished!!!"); } }
/// <summary> /// 처리 결과를 Http Response에 쓴다. /// </summary> /// <param name="response"></param> /// <param name="xdsResponse"></param> /// <param name="serializer"></param> internal static void WriteResponse(HttpResponse response, XdsResponseDocument xdsResponse, ISerializer serializer) { response.Clear(); response.Buffer = true; response.Expires = -1; response.ContentEncoding = XmlTool.XmlEncoding; response.ContentType = "text/xml"; var responseBytes = serializer.Serialize(xdsResponse.ConvertToBytes()); response.OutputStream.Write(responseBytes, 0, responseBytes.Length); // XmlTool.Serialize(xdsResponse, response.OutputStream); }
public static XdsResponseDocument CreateResponseWithError(Exception ex) { var responseDoc = new XdsResponseDocument(); if (ex != null) { responseDoc.Errors.AddError(ex); if (log.IsWarnEnabled) { log.WarnException("예외가 발생하여 예외정보를 담은 응답문서를 생성했습니다.", ex); } } return(responseDoc); }
/// <summary> /// 요청정보중에 확인을 위해 응답정보에 조건들을 기록해둔다. /// </summary> /// <param name="request"></param> /// <param name="responseDocument"></param> private static void WriteRequestInfomation(XdsRequestItem request, XdsResponseDocument responseDocument) { var index = responseDocument.Responses.Count - 1; if (index >= 0) { responseDocument[index].PageSize = request.PageSize; responseDocument[index].PageNo = request.PageNo; responseDocument[index].Sort = request.Sort; responseDocument[index].TotalRecordCount = responseDocument[index].Records.Count; if (responseDocument[index].PageSize > 0) { responseDocument[index].PageCount = responseDocument[index].TotalRecordCount / responseDocument[index].PageSize + 1; } } }
/// <summary> /// 일반 Query문을 수행하여 DataSet을 받아서 ResponseDom 객체를 만든다. /// </summary> /// <param name="request">요청 항목</param> /// <param name="responseDocument">응답 정보</param> protected virtual void OpenQuery(XdsRequestItem request, XdsResponseDocument responseDocument) { request.ShouldNotBeNull("request"); if (IsDebugEnabled) { log.Debug("쿼리문을 수행하여 결과셋을 얻습니다... request Id=[{0}], query=[{1}], requestType=[{2}], responseType=[{3}], sort=[{4}]", request.Id, request.Query, request.RequestKind, request.ResponseKind, request.Sort); } try { var maxSequence = Math.Max(1, request.Values.Count); for (var seqId = 0; seqId < maxSequence; seqId++) { var adoParameters = PrepareParameters(request, seqId).ToArray(); using (var cmd = Ado.GetCommand(request.Query)) using (var pagingTable = Ado.ExecutePagingDataTable(cmd, Math.Max(0, request.PageNo - 1), request.PageSize, adoParameters)) using (var dv = pagingTable.Table.DefaultView) { if (request.Sort.IsNotWhiteSpace()) { dv.Sort = request.Sort; } responseDocument.Responses.AddResponseItem(dv, request.Id, seqId); } } } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorException(string.Format("쿼리문을 수행하여 결과셋을 얻는데 실패했습니다. query=[{0}]", request.Query), ex); } throw; } if (IsDebugEnabled) { log.Debug("쿼리문을 수행하여 결과셋을 얻는데 성공했습니다. query=[{0}]", request.Query); } }
/// <summary> /// 일반 SQL Query 문 중에 DDL 과 관련된 문장을 수행한다. (결과 SET이 필요없는 것) /// </summary> /// <param name="request">요청 항목</param> /// <param name="responseDocument">응답 정보</param> protected virtual void ExecuteQuery(XdsRequestItem request, XdsResponseDocument responseDocument) { if (IsDebugEnabled) { log.Debug("쿼리문장을 실행합니다... requestId=[{0}], queryString=[{1}], requestType=[{2}], responseType=[{3}]", request.Id, request.Query, request.RequestKind, request.ResponseKind); } try { var isScalar = request.ResponseKind == XmlDataResponseKind.Scalar; var maxSequence = Math.Max(1, request.Values.Count); for (var seqId = 0; seqId < maxSequence; seqId++) { var adoParameters = PrepareParameters(request, seqId).ToArray(); using (var cmd = Ado.GetSqlStringCommand(request.Query)) { var result = (isScalar) ? Ado.ExecuteScalar(cmd, adoParameters) : Ado.ExecuteNonQuery(cmd, adoParameters); var responseItem = responseDocument.AddResponseItem(request.ResponseKind, request.Id, seqId); if (isScalar) { responseItem.Fields.AddField("RETURN_VALUE", typeof(int).Name, 4); responseItem.Records.AddColumnArray(result); } } } } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorException(string.Format("쿼리 문 실행에 실패했습니다. query=[{0}]", request.Query), ex); } throw; } if (IsDebugEnabled) { log.Debug("쿼리문 실행에 성공했습니다. query=[{0}]", request.Query); } }
/// <summary> /// <paramref name="request"/> 요청에 대해, 처리를 수행합니다. /// </summary> /// <param name="request">요청항목</param> /// <param name="responseDocument">응답 정보</param> protected void DoProcessRequestItem(XdsRequestItem request, XdsResponseDocument responseDocument) { request.ShouldNotBeNull("request"); var isDataSet = (request.ResponseKind == XmlDataResponseKind.DataSet); switch (request.RequestKind) { case XmlDataRequestKind.StoredProc: if (isDataSet) { OpenProcedure(request, responseDocument); } else { ExecuteProcedure(request, responseDocument); } break; case XmlDataRequestKind.Query: if (isDataSet) { OpenQuery(request, responseDocument); } else { ExecuteQuery(request, responseDocument); } break; default: throw new NotSupportedException("지원하지 않는 요청 종류입니다. RequestType=" + request.RequestKind); } // 요청정보중에 확인을 위해 응답정보에 조건들을 기록해둔다. // if (isDataSet) { WriteRequestInfomation(request, responseDocument); } }
/// <summary> /// /// </summary> /// <param name="requestBytes"></param> /// <param name="productName"></param> /// <param name="serializer"></param> /// <returns></returns> public static byte[] Execute(byte[] requestBytes, string productName, ISerializer serializer) { if (productName.IsWhiteSpace()) { productName = AdoTool.DefaultDatabaseName; } XdsResponseDocument xdsResponse = null; byte[] result = null; try { Guard.Assert(requestBytes != null && requestBytes.Length > 0, "요청 정보가 없습니다."); XmlDataServiceFacade.CheckProductExists(productName); var requestData = (byte[])serializer.Deserialize(requestBytes); var xdsRequest = requestData.ConvertToXdsRequestDocument(XmlTool.XmlEncoding); xdsResponse = XmlDataServiceFacade.Execute(xdsRequest, productName); } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorException("예외가 발생했습니다.", ex); } if (xdsResponse == null) { xdsResponse = new XdsResponseDocument(); } xdsResponse.ReportError(ex); } finally { byte[] xdsResponseBytes; XmlTool.Serialize(xdsResponse, out xdsResponseBytes); result = serializer.Serialize(xdsResponseBytes); } return(result); }
public void VerifyXdsResponseDocument(XdsResponseDocument responseMsg) { responseMsg.Should().Not.Be.Null(); responseMsg.HasError.Should().Be.False(); }
/// <summary> /// 요청 정보를 병렬로 모두 수행합니다. /// </summary> protected override void ExecuteRequestCore(XdsRequestDocument requestDocument, XdsResponseDocument responseDocument) { if (requestDocument.IsParallelToolecute == false) { base.ExecuteRequestCore(requestDocument, responseDocument); return; } if (IsDebugEnabled) { log.Debug(@"요청을 병렬방식으로 수행합니다..."); } // 요청을 병렬로 처리합니다. requestDocument.Requests .AsParallel() .AsOrdered() .ForAll(request => DoProcessRequestItem(request, responseDocument)); if (IsDebugEnabled) { log.Info(@"모든 요청을 병렬 수행으로 처리했습니다."); } }
/// <summary> /// 요청정보를 실행하여 응답정보를 반환합니다. /// </summary> /// <param name="requestDocument">요청정보</param> /// <param name="commandTimeout">요청 처리 제한 시간 (단위 : seconds, 기본값 : 90)</param> /// <returns>요청 처리 응답정보</returns> public virtual XdsResponseDocument Execute(XdsRequestDocument requestDocument, int?commandTimeout) { if (IsDebugEnabled) { log.Debug("요청정보에 따른 Database 작업을 시작합니다..."); } requestDocument.ShouldNotBeNull("requestDocument"); if (requestDocument == null) { return(XmlDataTool.CreateResponseWithError(new InvalidOperationException(MsgConsts.NoRequestProvided))); } var responseDocument = new XdsResponseDocument(); TransactionScope txScope = null; try { if (IsDebugEnabled) { log.Debug("요청문서 분석 및 응답문서를 초기화 합니다."); } requestDocument.CopyRequestHeader(responseDocument); if (requestDocument.CommandTimeout > commandTimeout.GetValueOrDefault(90)) { commandTimeout = requestDocument.CommandTimeout; } if (requestDocument.Transaction) { if (IsDebugEnabled) { log.Debug("요청문서에 Transaction 적용 옵션이 설정되어 있습니다. TransactionScope를 이용하여, 전체 요청을 Transaction 하에서 실행합니다."); } txScope = AdoTool.CreateTransactionScope(TransactionScopeOption.Required, IsolationLevel.ReadCommitted); } //! 실제 요청 처리 ExecuteRequestCore(requestDocument, responseDocument); // Transaction을 Commit 한다 // if (txScope != null) { if (IsDebugEnabled) { log.Debug("Transaction Commit을 시작합니다..."); } txScope.Complete(); if (IsDebugEnabled) { log.Debug("Transaction Commit에 성공했습니다.!!!"); } } } catch (Exception ex) { responseDocument.ReportError(ex); } finally { if (txScope != null) { txScope.Dispose(); } } if (IsDebugEnabled) { log.Debug("모든 요청을 처리하고, ResponseDocument를 반환합니다."); } return(responseDocument); }
/// <summary> /// 요청 정보중에 응답정보로 다시 보내기 위해서 헤더 정보를 복사한다. /// </summary> /// <param name="requestDocument">요청문서</param> /// <param name="responseDocument">응답문서</param> public static void CopyRequestHeader(this XdsRequestDocument requestDocument, XdsResponseDocument responseDocument) { requestDocument.ShouldNotBeNull("requestDocument"); responseDocument.ShouldNotBeNull("responseDocument"); responseDocument.ConnectionString = requestDocument.ConnectionString; responseDocument.Transaction = requestDocument.Transaction; responseDocument.IsolationLevel = requestDocument.IsolationLevel; }
/// <summary> /// 요청에 대한 실제 작업을 수행합니다. /// </summary> protected virtual void ExecuteRequestCore(XdsRequestDocument requestDocument, XdsResponseDocument responseDocument) { if (IsDebugEnabled) { log.Debug("요청 정보를 옵션에 따라 동기적으로 실행합니다..."); } foreach (var request in requestDocument.Requests) { // 메소드인 경우는 QueryProvider를 이용하여, 실제 Query 문장으로 변경한다. // XmlDataTool.ConvertToQuery(Ado, request); ExecuteSimpleQuery(Ado, request.PreQueries); //! 실제 수행 DoProcessRequestItem(request, responseDocument); ExecuteSimpleQuery(Ado, request.PostQueries); } }