public static Hashtable GetReplyDataWhenNoTidWasFound(ITID tid, MessageHeaders headers) { OperationContext ctx = OperationContext.Current; IClientChannel channel = null; if (ctx == null && ctx.Channel is IClientChannel) { channel = (IClientChannel)ctx.Channel; } Hashtable mapProps = new Hashtable(); mapProps[TIDField.MESSAGESEQNUMBER] = ASAMessageInspectionHelper.GetMessageSeqNumberFromIncomingHeaders() + 1; ASAMessageInspectionHelper.WriteMessageSeqNumToIncomingHeaders((int)mapProps[TIDField.MESSAGESEQNUMBER]); mapProps[TIDField.CORRELATIONID] = ASATIDHelper.GetTIDCorrelationID(); mapProps[TIDField.OPERATIONNAME] = GetOperationName(headers); // --> try to get from SOAP Action, but will probably be empty. mapProps[TIDField.SENTDT] = DateTime.UtcNow; //dont' know when it was actually sentin this scenario, so our best guess is "now". // desintination = this machine mapProps[TIDField.DESTINATION] = GetReceivingMessageDestination(headers, channel); // source --> in message? mapProps[TIDField.SOURCE] = GetReceivingMessageSource(headers); // set reply = true // set synch = true mapProps[TIDField.SYNCH] = GetSyncFlag(channel, (string)mapProps[TIDField.OPERATIONNAME]); mapProps[TIDField.REPLY] = true; if (ctx != null) { mapProps[TIDField.USERNAME] = GetUsername(); } //mapProps[TIDField.MESSAGEID] = GetMessageID(headers); //<-- this is set by TID.CreateTID() //mapProps[TIDField.ORIGINATIONDT] = GetOriginationDt(headers); //<-- this is set by TID.CreateTID() //mapProps[TIDField.RECEIVEDDT] = GetReceivedDt(headers); //<-- this is set by TID.CreateTID() and again later by GetRecvTID() //mapProps[TIDField.MESSAGEVERSION] = GetMessageVersion(svcEndpoint); //--> no svc endpoint to get this from in context. //mapProps[TIDField.SERVICENAME] = GetServiceName(svcEndpoint); //--> no svc endpoint to get this from in context. if (OperationContext.Current == null) { mapProps[TIDField.EXPIREDT] = GetExpireDt((DateTime)tid.Get(TIDField.ORIGINATIONDT), channel.OperationTimeout); } return(mapProps); }
// Provide a fault. The Message fault parameter can be replaced, or set to // null to suppress reporting a fault. public void ProvideFault(Exception error, MessageVersion version, ref Message msg) { _mSELDao = (ISELDao)ContextHelper.GetContextObject("SELDAO"); ASAException translatedException = new ASAException(); //catch all, in case error comes into EHF without being translated if (error is ASAException) { translatedException = (ASAException)error; } else { ASAExceptionTranslator afterThrowingTranslator = new ASAExceptionTranslator(); translatedException = afterThrowingTranslator.Translate(error); } string tidCorrelationID = ASATIDHelper.GetTIDCorrelationID(); if (error != null && error is NoMatchingObjectException) { msg = BuildErrorMessage <ASAFaultDetail>(version, "Server", tidCorrelationID, translatedException.Error_FaultString, translatedException.Error_DetailMessage); } else if (error != null && error is ServiceRequestValidationException) { msg = BuildErrorMessage <ASAFaultDetail>(version, "Server", tidCorrelationID, translatedException.Error_FaultString + ": " + translatedException.Error_DetailMessage, translatedException.Error_DetailMessage); } else if (error != null && error is ServiceReplyValidationException) { msg = BuildErrorMessage <ASAFaultDetail>(version, "Server", tidCorrelationID, translatedException.Error_FaultString, translatedException.Error_DetailMessage); } else if (error != null && error is ASADemogBusinessException) { //QC 1690-1693 handle new exception types msg = BuildErrorMessage <ASADemogFaultDetail>(version, "Server", tidCorrelationID, translatedException.Error_FaultString + ": " + translatedException.Error_DetailMessage, translatedException.Error_DetailMessage); } else if (error != null && error is ASABusinessException) { //QC 1690-1693 handle new exception types msg = BuildErrorMessage <ASABusinessFaultDetail>(version, "Server", tidCorrelationID, translatedException.Error_FaultString + ": " + translatedException.Error_DetailMessage, translatedException.Error_DetailMessage); } else if (error != null && error is Exception) { switch (translatedException.ExceptionType) { case "ASADataAccessException": case "ASAUnknownException": case "ASA.ExcErrCodeUnavail": { msg = BuildErrorMessage <ASAFaultDetail>(version, "Server", tidCorrelationID, translatedException.BusinessDescription, translatedException.Original_Message); break; } default: { msg = BuildErrorMessage <ASAFaultDetail>(version, "Server", tidCorrelationID, translatedException.Error_FaultString, translatedException.Error_DetailMessage); break; } } } Log.Error(msg); #region add message to the LogException tables string payload = string.Empty; if (Payload.ContainsMessagePayLoad(tidCorrelationID)) { payload = Payload.GetMessagePayLoad(tidCorrelationID); } //LogEvent logEventRec = new LogEvent(); LogException logExceptionRec = new LogException(); logExceptionRec.CreatedBy = (ASATIDHelper.GetTIDUsername() != "") ? ASATIDHelper.GetTIDUsername() : "ASA_USER"; logExceptionRec.CreatedDate = DateTime.Now; logExceptionRec.Payload = payload.ToString(); logExceptionRec.ExceptionStack = error.StackTrace; logExceptionRec.Correlationid = new Guid(tidCorrelationID); logExceptionRec.ExceptionErrorid = translatedException.ExceptionError_id; long eventID; try { //_mSELDao.AddLogExceptionRecord(logExceptionRec, out eventID); Log.Error(payload); Log.Error(logExceptionRec); } catch (Exception ex) { //if there is an error logging the record to the DB, write payload to log file Log.Error(payload); } #endregion }
/// <summary> /// o BeforeSendReply(): This method will be used to audit TID information before /// sending a reply message to the client. This method will: /// - Retrieve TID information from the header of the received message /// - Update TID fields for situation of a reply being sent. /// This will be done by the ASAMessageInspectionHelper.GetBeforeSendReplyData() method. /// - Call the TID class’ GetSendTID() method /// - send TID xml to the Logger for auditing. /// </summary> /// <param name="reply"></param> /// <param name="correlationState"></param> public void BeforeSendReply(ref Message reply, object correlationState, ServiceDescription svcDescription) { try { //if the SOAP envelope of the request is 'None", then someone is just trying to get the mex endpoint. // we dont want to audit for that. if (Parameters.Instance.EnableServiceResponseAudit == true) { //load Parameters with ASA settings Parameters.Instance.SectionName = "asa"; if (reply.Version.Envelope != System.ServiceModel.EnvelopeVersion.None) { OperationContext opCtx = OperationContext.Current; ITID tid = TIDFactory.GetTIDFromMessage(opCtx.IncomingMessageHeaders); // update the TID if (tid != null) { //populate hashtable with fields needed before sending request message. Hashtable mapProps = ASAMessageInspectionHelper.GetBeforeSendReplyData(tid, opCtx.IncomingMessageHeaders, svcDescription); //call update the tid for sending. tid = TIDFactory.GetSendTID(tid, mapProps); //put the TID into the outgoing Message object. MessageHeaders headers = reply.Headers; ASAMessageInspectionHelper.AddTIDHeader(tid, ref headers); // Check for config file entry "Enable_ServiceResponseAudit" //audit the TID information in 'tid' using the new ASA Logger string strTID = ASAMessageInspectionHelper.GetTIDString(headers); Log.LogTID(strTID); //remove message payload from dictionary Payload.RemoveMessagePayLoad(ASATIDHelper.GetTIDCorrelationID()); } else { //Log error Log.Error("TID object was not created properly by this interception point:" + reply.Headers.To.ToString(), this.strCorrelationIDForLogging.ToString());//TODO: get URI of this service here. } } } // Fix for defect 391 Parameters.Instance.SectionName = "asa"; bool enableForcedGarbageCollection = Parameters.Instance.GetBoolValue("EnableForcedGarbageCollection", false); if (enableForcedGarbageCollection) { GC.Collect(2, GCCollectionMode.Forced); } } catch (ASAException exASA) { // log exception, then swallow it. Log.Error("Error in BeforeSendReply:" + exASA.Message + " Error_code:" + exASA.ExceptionError_id, exASA); } catch (Exception ex) { // log exception, then swallow it. Log.Error("Error in BeforeSendReply", ex); } }
// // _____________ _____________ // | | 1 2 | | // | |-------------->| | // | Client | | WCF Service | // | |<--------------| | // | | 4 3 | | // ------------- ------------- // // #1 = "BeforeSendRequest", which happens in the ASAClientMessageInspector // #2 = "AfterReceiveRequest", which happens in the ASADispatchMessageInspector // #3 = "BeforeSendReply", which happens in the ASADispatchMessageInspector // #4 = "AfterReceiveReply", which happens in the ASAClientMessageInspector #region IDispatchMessageInspector interception methods /// <summary> /// o AfterReceiveRequest(): This method will be used to audit TID information /// upon receiving a request from the client. This method will: /// - Retrieve TID information from the header of the received message /// - Update TID fields for situation of a request being received. /// This will be done by the ASAMessageInspectionHelper.GetAfterReceivedRequestData() method. /// - Call the TID class’ GetRecvTID() method /// - send TID xml to the Logger for auditing. /// </summary> /// <param name="request"></param> /// <param name="channel"></param> /// <param name="instanceContext"></param> /// <returns></returns> public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext, ServiceDescription svcDescription) { try { //if the SOAP envelope of the request is 'None", then someone is just trying to get the mex endpoint. // we dont want to audit for that. if (request.Version.Envelope != System.ServiceModel.EnvelopeVersion.None) { //load Parameters with ASA settings Parameters.Instance.SectionName = "asa"; if (Parameters.Instance.EnableServiceRequestAudit == true) { OperationContext opCtx = OperationContext.Current; ITID tid = TIDFactory.GetTIDFromMessage(request.Headers); if (tid == null) { // the caller did not supply a TID. Let's populate one with the info available to us. tid = ASAMessageInspectionHelper.CreateNewTID(); //create a new TID object MessageHeaders headers = request.Headers; ASAMessageInspectionHelper.AddParamListFromMessageToTID(tid, headers); ASAMessageInspectionHelper.AddMissingDefaultDataToTID(tid, headers, svcDescription); ASAMessageInspectionHelper.AddTIDHeader(tid, ref headers); } // update the TID if (tid != null) { //Add message payload to dictionary Payload.AddMessagePayLoad(ASATIDHelper.GetTIDCorrelationID(), request.ToString()); //populate hashtable with fields that need to be updated after receiving request message. Hashtable mapProps = ASAMessageInspectionHelper.GetAfterReceiveRequestData(tid, request.Headers, channel); //call update the tid for sending. tid = TIDFactory.GetRecvTID(request.Headers, mapProps); //put this TID into the outgoing Message object. MessageHeaders headers = opCtx.IncomingMessageHeaders; ASAMessageInspectionHelper.AddTIDHeader(tid, ref headers); // Check for config file entry "Enable_ServiceRequestAudit" //audit the TID information in 'tid' using the new ASA Logger string strTID = ASAMessageInspectionHelper.GetTIDString(headers); Log.LogTID(strTID); } else { //Log error Log.Error("TID object was not created properly by the caller of this service:" + channel.RemoteAddress.Uri.ToString(), this.strCorrelationIDForLogging.ToString()); } if (Parameters.Instance.GetBoolValue("Enable_Authorization", false) == true) { AuthorizationManager.CheckAccess(TID.ASATIDHelper.GetTIDUsername(), request.Headers.Action); } } } } catch (ASAException exASA) { // log exception, then swallow it. Log.Error("Error in AfterReceiveRequest:" + exASA.Message + " Error_code:" + exASA.ExceptionError_id, exASA); } catch (ApplicationException exApp) { // log exception Log.Error("Error in AfterReceiveRequest", exApp); throw exApp; } catch (Exception ex) { // log exception, then swallow it. Log.Error("Error in AfterReceiveRequest", ex); } return(null); }