public static Bundle CreateBundle(ICollection <DtoResource> ResourceList, Bundle.BundleType BundleType, IPyroRequestUri RequestUri, int SearchTotal, int PagesTotal, int PageRequested, Paging.IPagingSupport IPagingSupport, Uri SearchPerformedUri = null) { var FhirBundle = new Bundle() { Type = Bundle.BundleType.Searchset }; FhirBundle.Type = BundleType; FhirBundle.Total = SearchTotal; //Paging IPagingSupport.SetBundlePagnation(FhirBundle, RequestUri.FhirRequestUri.OriginalString, PagesTotal, PageRequested, SearchPerformedUri); foreach (DtoResource DtoResource in ResourceList) { Bundle.EntryComponent oResEntry = new Bundle.EntryComponent(); if (DtoResource.IsDeleted == false) { try { oResEntry.Resource = FhirResourceSerializationSupport.DeSerializeFromGZip(DtoResource.Resource); } catch (Exception oExec) { string Message = string.Format("Internal Server Error: Serialization of a Resource retrieved from the servers database failed. The record details were: Key: {0}, ResourceVersion: {1}, Received: {2}. The parser exception error was '{3}", DtoResource.FhirId, DtoResource.Version, DtoResource.Received.ToString(), oExec.Message); OperationOutcome OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Exception, Message); throw new PyroException(System.Net.HttpStatusCode.InternalServerError, OpOutcome, Message); } } oResEntry.FullUrl = string.Join("/", RequestUri.FhirRequestUri.UriPrimaryServiceRoot.OriginalString, DtoResource.ResourceType.GetLiteral(), DtoResource.FhirId); if (BundleType == Bundle.BundleType.History) { oResEntry.FullUrl = string.Join("/", oResEntry.FullUrl); if (DtoResource.ResourceType.HasValue && DtoResource.ResourceType.HasValue) { oResEntry.Request = new Bundle.RequestComponent(); oResEntry.Request.Method = DtoResource.Method; switch (DtoResource.Method) { case Bundle.HTTPVerb.GET: oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version); break; case Bundle.HTTPVerb.POST: oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version); break; case Bundle.HTTPVerb.PUT: oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version); break; case Bundle.HTTPVerb.DELETE: oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(DtoResource.Method.ToString(), (int)DtoResource.Method, typeof(Bundle.HTTPVerb)); } } } if (BundleType == Bundle.BundleType.Searchset) { oResEntry.Search = new Bundle.SearchComponent(); oResEntry.Search.Mode = Bundle.SearchEntryMode.Match; if (DtoResource is DtoIncludeResource) { oResEntry.Search.Mode = Bundle.SearchEntryMode.Include; } oResEntry.Link = new List <Bundle.LinkComponent>(); } FhirBundle.Entry.Add(oResEntry); } return(FhirBundle); }
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { var IResourceServiceFactory = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IResourceServiceFactory)) as IResourceServiceFactory; var IUnitOfWork = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IUnitOfWork)) as IUnitOfWork; var IRequestMetaFactory = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IRequestMetaFactory)) as IRequestMetaFactory; var IResourceServices = IResourceServiceFactory.Create <IResourceServices>(); var ICommonFactory = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(ICommonFactory)) as ICommonFactory; var IPyroRequestUriFactory = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IPyroRequestUriFactory)) as IPyroRequestUriFactory; var IGlobalProperties = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IGlobalProperties)) as IGlobalProperties; var IResourceTriggerService = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IResourceTriggerService)) as IResourceTriggerService; var IPyroFhirResource = actionExecutedContext.ActionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(Common.PyroHealthFhirResource.IPyroFhirResource)) as Common.PyroHealthFhirResource.IPyroFhirResource; using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { try { var PyroCodeSystem = IPyroFhirResource.CodeSystem.PyroFhirServerCodeSystem; DateTime dtStart = (DateTime)actionExecutedContext.Request.Properties[DateTimeKey]; System.Diagnostics.Stopwatch stopwatch = (System.Diagnostics.Stopwatch)actionExecutedContext.Request.Properties[StopwatchKey]; stopwatch.Stop(); TimeSpan duration = stopwatch.Elapsed; IPyroRequestUri DtoRequestUri = IPyroRequestUriFactory.CreateFhirRequestUri(); DtoRequestUri.FhirRequestUri.Parse(actionExecutedContext.Request.RequestUri.OriginalString); // use owin context so we can self host (i.e. avoid System.Web.HttpContext.Current) var owinContext = actionExecutedContext.Request.GetOwinContext(); string machineName = System.Environment.MachineName; string httpVerb = actionExecutedContext.Request.Method.ToString(); string ipAddress = owinContext.Request.RemoteIpAddress; string controllerName = actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName; string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName; bool successfulRequest = (actionExecutedContext.Exception == null); System.Web.Http.Routing.IHttpRouteData route = actionExecutedContext.ActionContext.ControllerContext.RouteData; // Get the resource base string baseUri = DtoRequestUri.FhirRequestUri.UriPrimaryServiceRoot.OriginalString; // Create the Security Event Object AuditEvent Audit = new AuditEvent(); Audit.Meta = new Meta(); Audit.Meta.Tag = new List <Coding>() { PyroCodeSystem.GetCoding(Common.PyroHealthFhirResource.CodeSystems.PyroFhirServer.Codes.Protected) }; if (actionExecutedContext.Request.Method == HttpMethod.Put) { Audit.Action = AuditEvent.AuditEventAction.U; } else if (actionExecutedContext.Request.Method == HttpMethod.Post) { Audit.Action = AuditEvent.AuditEventAction.C; } else if (actionExecutedContext.Request.Method == HttpMethod.Delete) { Audit.Action = AuditEvent.AuditEventAction.D; } else { Audit.Action = AuditEvent.AuditEventAction.R; } Audit.Recorded = DateTimeOffset.Now; Audit.Outcome = AuditEvent.AuditEventOutcome.N0; if (!successfulRequest) { // log error if (actionExecutedContext.Exception is PyroException) { var fse = actionExecutedContext.Exception as PyroException; if ((int)fse.HttpStatusCode >= 500) { Audit.Outcome = AuditEvent.AuditEventOutcome.N8; } else if ((int)fse.HttpStatusCode >= 400) { Audit.Outcome = AuditEvent.AuditEventOutcome.N4; } } else { Audit.Outcome = AuditEvent.AuditEventOutcome.N8; } } Audit.Type = new Coding() { System = "http://hl7.org/fhir/security-event-type", Code = "rest", Display = "Restful Operation" }; Audit.Subtype = new List <Coding>(); if (actionExecutedContext.Request.Method == HttpMethod.Put) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "update", Display = "update" }); } else if (actionExecutedContext.Request.Method == HttpMethod.Post) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "create", Display = "create" }); } else if (actionExecutedContext.Request.Method == HttpMethod.Delete) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "delete", Display = "delete" }); } else if (actionExecutedContext.Request.Method == HttpMethod.Options) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "read", Display = "read" }); } else if (route.Values.ContainsKey("ResourceName") && route.Values.ContainsKey("id") && route.Values.ContainsKey("vid")) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "vread", Display = "vread" }); } else if (route.Values.ContainsKey("ResourceName") && route.Values.ContainsKey("id")) { if (owinContext.Request.Uri.OriginalString.Contains("_history")) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "history-instance", Display = "history-instance" }); } else { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "read", Display = "read" }); } } else if (route.Values.ContainsKey("ResourceName")) { if (owinContext.Request.Uri.OriginalString.Contains("_history")) { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "history-type", Display = "history-type" }); } else { Audit.Subtype.Add(new Coding() { System = "http://hl7.org/fhir/restful-interaction", Code = "search-type", Display = "search-type" }); } } Audit.Agent.Add(new AuditEvent.AgentComponent()); // se.Participant[0].UserId = ""; // se.Participant[0].AltId = owinContext.Authentication.; if (owinContext.Authentication.User != null && owinContext.Authentication.User.Identity.IsAuthenticated) { Audit.Agent[0].Name = owinContext.Authentication.User.Identity.Name; // read additional details from the identity claims if (owinContext.Authentication.User.Identity is System.Security.Claims.ClaimsIdentity ci) { var claim = ci.Claims.Where(c => c.Type == "name").FirstOrDefault(); if (claim != null) { Audit.Agent[0].Name = claim.Value; } claim = ci.Claims.Where(c => c.Type == "sub").FirstOrDefault(); if (claim != null) { Audit.Agent[0].AltId = claim.Value; } if (ci.Claims.Any(c => c.Type == "author_only_access" && c.Value == "true")) { Audit.Agent[0].Role = new List <CodeableConcept> { new CodeableConcept(null, "author_only_access") }; } } } Audit.Agent[0].Requestor = true; Audit.Agent[0].Network = new AuditEvent.NetworkComponent() { Address = ipAddress, Type = AuditEvent.AuditEventAgentNetworkType.N2 }; Audit.Source = new AuditEvent.SourceComponent { Site = "Cloud", Identifier = new Identifier(null, actionExecutedContext.Request.RequestUri.GetLeftPart(UriPartial.Authority)) }; Audit.Source.Type.Add(new Coding() { System = "http://hl7.org/fhir/ValueSet/audit-source-type", Code = "3", Display = "Web Server" }); if (route.Values.ContainsKey("ResourceName") && route.Values.ContainsKey("id")) { string relativeUri = String.Format("{0}/{1}", route.Values["ResourceName"] as string, route.Values["id"] as string); if (route.Values.ContainsKey("vid")) { relativeUri += "/_history/" + route.Values["vid"] as string; } Audit.Entity = new List <AuditEvent.EntityComponent> { new AuditEvent.EntityComponent() { Name = actionExecutedContext.Request.RequestUri.ToString(), Reference = new ResourceReference() { Url = new Uri(relativeUri, UriKind.Relative) }, Type = new Coding() { System = "http://hl7.org/fhir/object-type", Code = "1", Display = "Person" } } }; if (actionExecutedContext.Request.Properties.ContainsKey(Attributes.ActionLogAttribute.ResourceIdentityKey)) { string reference = actionExecutedContext.Request.Properties[Attributes.ActionLogAttribute.ResourceIdentityKey] as string; if (!string.IsNullOrEmpty(reference)) { Audit.Entity[0].Reference.Reference = reference; } } } else { Audit.Entity = new List <AuditEvent.EntityComponent> { new AuditEvent.EntityComponent() { Name = actionExecutedContext.Request.RequestUri.ToString(), Description = baseUri == null ? owinContext.Request.Uri.OriginalString : owinContext.Request.Uri.OriginalString.Replace(baseUri, ""), Type = new Coding() { System = "http://hl7.org/fhir/object-type", Code = "1", Display = "Person" } } }; if (actionExecutedContext.Request.Properties.ContainsKey(Attributes.ActionLogAttribute.ResourceIdentityKey)) { string reference = actionExecutedContext.Request.Properties[Attributes.ActionLogAttribute.ResourceIdentityKey] as string; if (!string.IsNullOrEmpty(reference)) { Audit.Entity[0].Reference = new ResourceReference() { Reference = reference } } ; } } IHtmlGenerationSupport Narative = ICommonFactory.CreateFhirNarativeGenerationSupport(); Narative.NewValuePairList("Time", string.Format("{0} ({1:f3} sec)", dtStart, duration.TotalSeconds)); Narative.AppendValuePairList(actionExecutedContext.Request.Method.ToString(), string.Format("{0}", HttpUtility.HtmlEncode(baseUri == null ? owinContext.Request.Uri.OriginalString : owinContext.Request.Uri.OriginalString.Replace(baseUri, "")))); Narative.AppendValuePairList("BaseUri", baseUri); Narative.AppendValuePairList("From", ipAddress); if (owinContext.Authentication.User != null && owinContext.Authentication.User.Identity.IsAuthenticated) { Narative.AppendValuePairList("User", owinContext.Authentication.User.ToString()); } else { Narative.AppendValuePairList("User", "(anonymous)"); } if (Audit.Outcome != AuditEvent.AuditEventOutcome.N0) { Audit.OutcomeDesc = actionExecutedContext.Exception.Message; Narative.AppendValuePairList("Error", actionExecutedContext.Exception.Message); } Audit.Text = new Narrative { Div = Narative.Generate(), Status = Narrative.NarrativeStatus.Generated }; // Add custom PyroHealth event data Audit.AddExtension("http://pyrohealth.net/extention/AuditEvent/TimeTaken", new FhirDecimal((decimal)duration.TotalMilliseconds)); if (IGlobalProperties.FhirAuditEventLogRequestData) { var requestDataObj = new AuditEvent.EntityComponent { Identifier = new Identifier(null, "RequestData"), Name = actionExecutedContext.Request.RequestUri.ToString(), Description = "Orginial Request Data", Type = new Coding() { System = "http://hl7.org/fhir/object-type", Code = "4", Display = "RequestData" }, Detail = new List <AuditEvent.DetailComponent>() }; var DetailComponent = new AuditEvent.DetailComponent(); requestDataObj.Detail.Add(DetailComponent); string RequestData = GetRequestData(actionExecutedContext); if (!string.IsNullOrWhiteSpace(RequestData)) { DetailComponent.Value = Encoding.UTF8.GetBytes(RequestData); Audit.Entity.Add(requestDataObj); } } if (IGlobalProperties.FhirAuditEventLogResponseData) { var responseDataObj = new AuditEvent.EntityComponent { Identifier = new Identifier(null, "ResponseData"), Name = actionExecutedContext.Request.RequestUri.ToString(), Description = "Orginial Response Data", Type = new Coding() { System = "http://hl7.org/fhir/object-type", Code = "4", Display = "ResponseData" }, Detail = new List <AuditEvent.DetailComponent>() }; var DetailComponent = new AuditEvent.DetailComponent(); responseDataObj.Detail.Add(DetailComponent); string ResponseData = GetResponseData(actionExecutedContext); if (!string.IsNullOrWhiteSpace(ResponseData)) { DetailComponent.Value = Encoding.UTF8.GetBytes(ResponseData); Audit.Entity.Add(responseDataObj); } } //Will only log if Debug logging is enabled. DebugLogRequestResource(actionExecutedContext); //Commit to Database Pyro.Common.RequestMetadata.IRequestMeta IRequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{ResourceType.AuditEvent}"); IResourceTriggerService.TriggersActive = false; IResourceServiceOutcome ResourceServiceOutcome = IResourceServices.Post(Audit, IRequestMeta); IResourceTriggerService.TriggersActive = true; //IResourceServiceOutcome ResourceServiceOutcome = IResourceServices.SetResource(Audit, DtoRequestUri, RestEnum.CrudOperationType.Create); Transaction.Commit(); } catch (Exception Exec) { Logger.Log.Error(Exec, "ActionLogAttribute"); Transaction.Rollback(); } base.OnActionExecuted(actionExecutedContext); } }
public IResourceServiceOutcome Process( IPyroRequestUri RequestUri, ISearchParameterGeneric SearchParameterGeneric, Resource Resource) { IResourceServiceOutcome ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome(); var IssueList = new List <OperationOutcome.IssueComponent>(); ISearchParameterService SearchService = ISearchParameterServiceFactory.CreateSearchParameterService(); ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(SearchParameterGeneric); if (SearchParametersServiceOutcome.FhirOperationOutcome != null) { ResourceServiceOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome; ResourceServiceOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode; ResourceServiceOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format; return(ResourceServiceOutcome); } if (Resource is Parameters Parameters) { if (Parameters.Parameter != null && Parameters.Parameter.Count > 0) { if (Parameters.Parameter[0].Name.ToLower() == _ParameterName) { if (Parameters.Parameter[0].Resource != null) { if (Parameters.Parameter[0].Resource is QuestionnaireResponse QuestionnaireResponse) { if (QuestionnaireResponse.Meta == null) { QuestionnaireResponse.Meta = new Meta(); } if (QuestionnaireResponse.Meta.Tag == null) { QuestionnaireResponse.Meta.Tag = new List <Coding>(); } QuestionnaireResponse.Meta.Tag.Add(new Coding("https://pyrohealth.net/fhir/CodeSystem/connectathon-answer", "hidden")); if (QuestionnaireResponse.Id == null || string.IsNullOrWhiteSpace(QuestionnaireResponse.Id)) { IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.QuestionnaireResponse.GetLiteral()}"); ResourceServiceOutcome = this.IResourceServices.Post(QuestionnaireResponse, RequestMeta); } else { IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.QuestionnaireResponse.GetLiteral()}/{QuestionnaireResponse.Id}"); ResourceServiceOutcome = this.IResourceServices.Put(QuestionnaireResponse.Id, QuestionnaireResponse, RequestMeta); } if (ResourceServiceOutcome.SuccessfulTransaction) { Parameters ParametersResult = new Parameters(); ParametersResult.Parameter = new List <Parameters.ParameterComponent>(); var Param = new Parameters.ParameterComponent(); Param.Name = "You answers have been submitted."; ParametersResult.Parameter.Add(Param); var Param2 = new Parameters.ParameterComponent(); Param2.Name = FHIRAllTypes.QuestionnaireResponse.GetLiteral(); Param2.Resource = ResourceServiceOutcome.ResourceResult; ParametersResult.Parameter.Add(Param2); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.OK; ResourceServiceOutcome.ResourceResult = ParametersResult; ResourceServiceOutcome.OperationType = Enum.RestEnum.CrudOperationType.Update; ResourceServiceOutcome.SuccessfulTransaction = true; IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.QuestionnaireResponse.GetLiteral()}/{_PrimaryQuestionnaireResponseAnswerResourceId}"); var Answers = this.IResourceServices.GetRead("AngusA1", RequestMeta); QuestionnaireResults QuestionnaireResults = QuestionnaireResponseChecker.Check(Answers.ResourceResult as QuestionnaireResponse, QuestionnaireResponse); } else { Parameters ParametersResult = new Parameters(); ParametersResult.Parameter = new List <Parameters.ParameterComponent>(); var Param = new Parameters.ParameterComponent(); Param.Name = "Oh no, there was an error is submitting your answers."; ParametersResult.Parameter.Add(Param); var Param2 = new Parameters.ParameterComponent(); Param2.Name = FHIRAllTypes.OperationOutcome.GetLiteral(); Param2.Resource = ResourceServiceOutcome.ResourceResult; ParametersResult.Parameter.Add(Param2); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.ResourceResult = ParametersResult; ResourceServiceOutcome.OperationType = Enum.RestEnum.CrudOperationType.Update; ResourceServiceOutcome.SuccessfulTransaction = false; } } else { IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one parameter with the 'Name' element equal to '{_ParameterName}' where the Resource element is set to a {FHIRAllTypes.QuestionnaireResponse.GetLiteral()} FHIR Resource. The server found here a Resource of type {Parameters.Parameter[0].Resource.ResourceType}.")); } } else { IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one Parameter with the Name element equal to '{_ParameterName}' where the Resource element is set to a {FHIRAllTypes.QuestionnaireResponse.GetLiteral()} FHIR Resource. The server found no {FHIRAllTypes.QuestionnaireResponse.GetLiteral()} Resource")); } } else { IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one Parameter with the Name element equal to '{_ParameterName}'.")); } } else { IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one Parameter element.")); } } else { IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects a FHIR {FHIRAllTypes.Parameters.GetLiteral()} resource as the call body.")); } if (IssueList.Count > 0) { var Op = Common.Tools.FhirOperationOutcomeSupport.Generate(IssueList); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.ResourceResult = Op; ResourceServiceOutcome.OperationType = Enum.RestEnum.CrudOperationType.Update; ResourceServiceOutcome.SuccessfulTransaction = false; return(ResourceServiceOutcome); } else { return(ResourceServiceOutcome); } }