public override async Task ExecuteFunction(IAsyncStreamReader <BundledRows> requestStream, IServerStreamWriter <BundledRows> responseStream, ServerCallContext context) { try { logger.Debug("ExecuteFunction was called"); var functionRequestHeaderStream = context.RequestHeaders.SingleOrDefault(header => header.Key == "qlik-functionrequestheader-bin"); if (functionRequestHeaderStream == null) { throw new Exception("ExecuteFunction called without Function Request Header in Request Headers."); } var functionRequestHeader = new FunctionRequestHeader(); functionRequestHeader.MergeFrom(new CodedInputStream(functionRequestHeaderStream.ValueBytes)); var commonHeader = context.RequestHeaders.ParseIMessageFirstOrDefault <CommonRequestHeader>(); logger.Info($"request from user: {commonHeader.UserId} for AppId: {commonHeader.AppId}"); await context.WriteResponseHeadersAsync(new Metadata { { "qlik-cache", "no-store" } }); var functionCall = functionRequestHeader.FunctionId; logger.Debug($"Function id: {functionCall}"); var row = GetParameter(requestStream); var input = GetParameterValue(0, row); string result = String.Empty; switch (functionCall) { case 1: result = input; break; default: result = "Unknown Function"; break; } logger.Debug($"Result: {result}"); await responseStream.WriteAsync(GetResult(result)); } catch (Exception ex) { logger.Error(ex, "ExecuteFunction has errors"); await responseStream.WriteAsync(GetResult("Error")); } finally { LogManager.Flush(); } }
//private static long _callCounter = 0; private static Dictionary <String, String> TraceServerCallContext(ServerCallContext context) { Dictionary <String, String> headerInfo = new Dictionary <String, String>(); var authContext = context.AuthContext; Logger.Trace($"ServerCallContext.Method : {context.Method}"); Logger.Trace($"ServerCallContext.Host : {context.Host}"); Logger.Trace($"ServerCallContext.Peer : {context.Peer}"); headerInfo.Add("Method", context.Method); headerInfo.Add("Host", context.Host); headerInfo.Add("Peer", context.Peer); foreach (var contextRequestHeader in context.RequestHeaders) { Logger.Trace( $"{contextRequestHeader.Key} : {(contextRequestHeader.IsBinary ? "<binary>" : contextRequestHeader.Value)}"); if (contextRequestHeader.Key == "qlik-functionrequestheader-bin") { var functionRequestHeader = new FunctionRequestHeader(); functionRequestHeader.MergeFrom(new CodedInputStream(contextRequestHeader.ValueBytes)); Logger.Trace($"FunctionRequestHeader.FunctionId : {functionRequestHeader.FunctionId}"); Logger.Trace($"FunctionRequestHeader.Version : {functionRequestHeader.Version}"); headerInfo.Add("FunctionId", functionRequestHeader.FunctionId.ToString()); headerInfo.Add("Version", functionRequestHeader.Version); } else if (contextRequestHeader.Key == "qlik-commonrequestheader-bin") { var commonRequestHeader = new CommonRequestHeader(); commonRequestHeader.MergeFrom(new CodedInputStream(contextRequestHeader.ValueBytes)); Logger.Trace($"CommonRequestHeader.AppId : {commonRequestHeader.AppId}"); Logger.Trace($"CommonRequestHeader.Cardinality : {commonRequestHeader.Cardinality}"); Logger.Trace($"CommonRequestHeader.UserId : {commonRequestHeader.UserId}"); headerInfo.Add("AppId", commonRequestHeader.AppId); headerInfo.Add("Cardinality", commonRequestHeader.Cardinality.ToString()); headerInfo.Add("UserId", commonRequestHeader.UserId); } else if (contextRequestHeader.Key == "qlik-scriptrequestheader-bin") { var scriptRequestHeader = new ScriptRequestHeader(); scriptRequestHeader.MergeFrom(new CodedInputStream(contextRequestHeader.ValueBytes)); Logger.Trace($"ScriptRequestHeader.FunctionType : {scriptRequestHeader.FunctionType}"); Logger.Trace($"ScriptRequestHeader.ReturnType : {scriptRequestHeader.ReturnType}"); int paramIdx = 0; foreach (var parameter in scriptRequestHeader.Params) { Logger.Trace($"ScriptRequestHeader.Params[{paramIdx}].Name : {parameter.Name}"); Logger.Trace($"ScriptRequestHeader.Params[{paramIdx}].DataType : {parameter.DataType}"); ++paramIdx; } Logger.Trace($"CommonRequestHeader.Script : {scriptRequestHeader.Script}"); } } Logger.Trace($"ServerCallContext.AuthContext.IsPeerAuthenticated : {authContext.IsPeerAuthenticated}"); Logger.Trace( $"ServerCallContext.AuthContext.PeerIdentityPropertyName : {authContext.PeerIdentityPropertyName}"); foreach (var authContextProperty in authContext.Properties) { var loggedValue = authContextProperty.Value; var firstLineLength = loggedValue.IndexOf('\n'); if (firstLineLength > 0) { loggedValue = loggedValue.Substring(0, firstLineLength) + "<truncated at linefeed>"; } Logger.Trace($"{authContextProperty.Name} : {loggedValue}"); } return(headerInfo); }
public override async Task ExecuteFunction(IAsyncStreamReader <BundledRows> requestStream, IServerStreamWriter <BundledRows> responseStream, ServerCallContext context) { Logger.Trace("-- ExecuteFunction --"); if (logType == "file") { logConnector = new FileAuditLogConnector(); } Dictionary <String, String> headerInfo = TraceServerCallContext(context); var functionRequestHeaderStream = context.RequestHeaders.SingleOrDefault(header => header.Key == "qlik-functionrequestheader-bin"); if (functionRequestHeaderStream == null) { throw new Exception("ExecuteFunction called without Function Request Header in Request Headers."); } var functionRequestHeader = new FunctionRequestHeader(); functionRequestHeader.MergeFrom(new CodedInputStream(functionRequestHeaderStream.ValueBytes)); //Logger.Trace($"FunctionRequestHeader.FunctionId String : {(FunctionConstant)functionRequestHeader.FunctionId}"); Guid g = LogRequest(logConnector, headerInfo["AppId"], headerInfo["UserId"]); switch (functionRequestHeader.FunctionId) { case (int)FunctionConstant.LogAsSeenStrCheck: { while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); var cacheMetadata = new Metadata { { new Metadata.Entry("qlik-cache", "no-store") } }; await context.WriteResponseHeadersAsync(cacheMetadata); foreach (var row in requestStream.Current.Rows) { Row resultRow = LogRow(logConnector, g, headerInfo["AppId"], headerInfo["UserId"], row.Duals[0].StrData, "√"); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } case (int)FunctionConstant.LogAsSeenStrEcho: { while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); var cacheMetadata = new Metadata { { new Metadata.Entry("qlik-cache", "no-store") } }; await context.WriteResponseHeadersAsync(cacheMetadata); foreach (var row in requestStream.Current.Rows) { Row resultRow = LogRow(logConnector, g, headerInfo["AppId"], headerInfo["UserId"], row.Duals[0].StrData, row.Duals[0].StrData); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } case (int)FunctionConstant.LogAsSeenCheck: { while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); var cacheMetadata = new Metadata { { new Metadata.Entry("qlik-cache", "no-store") } }; await context.WriteResponseHeadersAsync(cacheMetadata); foreach (var row in requestStream.Current.Rows) { Row resultRow = LogRow(logConnector, g, headerInfo["AppId"], headerInfo["UserId"], row.Duals[0].NumData, "√"); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } case (int)FunctionConstant.LogAsSeenEcho: { while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); var cacheMetadata = new Metadata { { new Metadata.Entry("qlik-cache", "no-store") } }; await context.WriteResponseHeadersAsync(cacheMetadata); foreach (var row in requestStream.Current.Rows) { Row resultRow = LogRow(logConnector, g, headerInfo["AppId"], headerInfo["UserId"], row.Duals[0].NumData, row.Duals[0].NumData); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } default: break; } logConnector.EndLogData(); Logger.Trace("-- (ExecuteFunction) --"); }
public override async Task ExecuteFunction(IAsyncStreamReader <BundledRows> requestStream, IServerStreamWriter <BundledRows> responseStream, ServerCallContext context) { if (Logger.IsTraceEnabled) { Logger.Trace("-- ExecuteFunction --"); TraceServerCallContext(context); } else { Logger.Debug("ExecuteFunction called"); } var functionRequestHeaderStream = context.RequestHeaders.SingleOrDefault(header => header.Key == "qlik-functionrequestheader-bin"); if (functionRequestHeaderStream == null) { throw new Exception("ExecuteFunction called without Function Request Header in Request Headers."); } var functionRequestHeader = new FunctionRequestHeader(); functionRequestHeader.MergeFrom(new CodedInputStream(functionRequestHeaderStream.ValueBytes)); Logger.Trace($"FunctionRequestHeader.FunctionId String : {(FunctionConstant)functionRequestHeader.FunctionId}"); switch (functionRequestHeader.FunctionId) { case (int)FunctionConstant.Add42: { while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); foreach (var row in requestStream.Current.Rows) { var resultRow = new Row(); resultRow.Duals.Add(new Dual { NumData = row.Duals[0].NumData + 42.0 }); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } case (int)FunctionConstant.SumOfAllNumbers: { double sum = 0.0; while (await requestStream.MoveNext()) { foreach (var row in requestStream.Current.Rows) { sum = sum + row.Duals.Select(d => d.NumData).Sum(); } } var resultBundle = new BundledRows(); var resultRow = new Row(); resultRow.Duals.Add(new Dual { NumData = sum }); resultBundle.Rows.Add(resultRow); await responseStream.WriteAsync(resultBundle); break; } case (int)FunctionConstant.Concatenate: { var requestAsList = await requestStream.ToListAsync(); var concatenatedStrings = String.Join(", ", requestAsList.SelectMany(bundledRows => bundledRows.Rows).SelectMany(row => row.Duals) .Select(dual => dual.StrData)); var resultBundle = new BundledRows(); var resultRow = new Row(); resultRow.Duals.Add(new Dual { StrData = concatenatedStrings }); resultBundle.Rows.Add(resultRow); await responseStream.WriteAsync(resultBundle); break; } case (int)FunctionConstant.CallCounter: { var currentIncrement = Interlocked.Increment(ref _callCounter); while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); foreach (var row in requestStream.Current.Rows) { var resultRow = new Row(); resultRow.Duals.Add(new Dual { NumData = currentIncrement }); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } case (int)FunctionConstant.CallCounterNoCache: { context.ResponseTrailers.Add("qlik-cache", "no-store"); var currentIncrement = Interlocked.Increment(ref _callCounter); while (await requestStream.MoveNext()) { var resultBundle = new BundledRows(); foreach (var row in requestStream.Current.Rows) { var resultRow = new Row(); resultRow.Duals.Add(new Dual { NumData = currentIncrement }); resultBundle.Rows.Add(resultRow); } await responseStream.WriteAsync(resultBundle); } break; } default: break; } Logger.Trace("-- (ExecuteFunction) --"); }