private async Task <Uri> GetListeningAddressForWebUxSvc(RoutingContextBase routingContext, Uri inTenantAsFabricAppSvcName) { ResolvedServicePartition resolvedPartition = null; // find if we have previously saved results var actualkey = string.Format(Cache_Key_Format, MatcherTreeId, inTenantAsFabricAppSvcName.ToString()); var Resolver = routingContext.Resolver; if (Resolver.State.StateEntries.ContainsKey(actualkey)) { resolvedPartition = Resolver.State.StateEntries[actualkey] as ResolvedServicePartition; } // get Address from Service Fabric // we are expecting services to have one singlton partition FabricClient fc = new FabricClient(); resolvedPartition = await fc.ServiceManager.ResolveServicePartitionAsync(inTenantAsFabricAppSvcName, resolvedPartition); // cache resolved service partition. routingContext.Resolver.State.StateEntries[actualkey] = resolvedPartition; // get the address Service Fabric returns json with all address (we are expecting just one entry named http) var jsonAddress = JObject.Parse(resolvedPartition.GetEndpoint().Address); var svcListeningAddress = (string)jsonAddress["Endpoints"]["http"]; return(new Uri(svcListeningAddress)); }
public async override Task <bool> MatchAsync(RoutingContextBase routingContext, string sAddress, IDictionary <string, object> Context, Stream Body) { if (string.IsNullOrEmpty(HeaderName)) { throw new ArgumentNullException("HeaderName"); } if (null == HeaderValues) { throw new ArgumentNullException("HeaderValues"); } // don't validate against empty string, because user may want to add // an empty header value var anyNull = HeaderValues.Where(v => null == v); if (0 != anyNull.Count()) { throw new ArgumentNullException("header values contains one or more null values"); } if (false == await base.MatchAsync(routingContext, sAddress, Context, Body)) { return(false); } var httpCtx = routingContext as HttpRoutingContext; if (httpCtx.Headers.ContainsKey(HeaderName)) { httpCtx.Headers[HeaderName] = HeaderValues; } else { httpCtx.Headers.Add(HeaderName, HeaderValues); } return(true); }
public override async Task <bool> MatchAsync(RoutingContextBase routingContext, string sAddress, IDictionary <string, object> Context, Stream Body) { if (null == TargetMethod) { throw new ArgumentNullException("TargetMethod"); } if (false == await base.MatchAsync(routingContext, sAddress, Context, Body)) { return(false); } var httpCtx = routingContext as HttpRoutingContext; httpCtx.Method = this.TargetMethod; return(true); }
public async override Task <bool> MatchAsync(RoutingContextBase routingContext, string sAddress, IDictionary <string, object> Context, Stream Body) { if (string.IsNullOrEmpty(HeaderName)) { throw new ArgumentNullException("HeaderName"); } if (false == await base.MatchAsync(routingContext, sAddress, Context, Body)) { return(false); } var httpCtx = routingContext as HttpRoutingContext; httpCtx.Headers.Remove(HeaderName); return(true); }
public override async Task <bool> MatchAsync(RoutingContextBase routingContext, string sAddress, IDictionary <string, object> Context, Stream Body) { if (null == Scheme) { throw new ArgumentNullException("Scheme"); } if (false == await base.MatchAsync(routingContext, sAddress, Context, Body)) { return(false); } var httpCtx = routingContext as HttpRoutingContext; httpCtx.Scheme = Scheme; httpCtx.OverrideScheme = true; return(true); }
public override async Task <bool> MatchAsync(RoutingContextBase routingContext, string sAddress, IDictionary <string, object> Context, Stream Body) { // validate that the in Ctx actually has owin if (null == (Context["owin.RequestScheme"] as string)) { throw new InvalidOperationException("Context does not contain Owin"); } if (false == await base.MatchAsync(routingContext, sAddress, Context, Body)) { return(false); } var httpCtx = routingContext as HttpRoutingContext; // copy http method var OwinMethodString = Context["owin.RequestMethod"] as string; httpCtx.Method = new HttpMethod(OwinMethodString); // copy headers var OwinRequestHeader = Context["owin.RequestHeaders"] as IDictionary <string, string[]>; foreach (var header in OwinRequestHeader) { if (!ignoreHeaders.Contains(header.Key)) { httpCtx.Headers.Add(header.Key, header.Value); } } return(true); }
public async override Task <bool> MatchAsync(RoutingContextBase routingContext, string sAddress, IDictionary <string, object> Context, Stream Body) { if (false == await base.MatchAsync(routingContext, sAddress, Context, Body)) { return(false); } /* * incoming requests are at <tenantname>.<some host with/without port>.com/<path> * note: * in this case tenant mapping is statically defined in this clsas * in a typical production you probably have this as a map in external service or a store * note: * in this case i am routing to single service with single instane, but yours might be different, same logic apply * Logic: * 1- get request path * 2- get tenante name * 3- use the tenante name to specific app intsance and WebUXSvc listening url from Service Fabric * generate a new url as the following: * <service fabric service listening url including path>/<incoming path + query string> * */ var httpCtx = routingContext as HttpRoutingContext; var inUri = new Uri(sAddress); var inPathQueryString = inUri.PathAndQuery; // trim first / if (inPathQueryString.Length > 0 && inPathQueryString[0] == '/') { inPathQueryString = inPathQueryString.Substring(1); } // Service Fabric Application Name Uri is case senstive var inTenantName = inUri.DnsSafeHost.Split('.')[0].ToLowerInvariant(); var mappedAppName = GetMapedAppNameForTenant(inTenantName); var inTenantAsFabricAppSvcName = new Uri(string.Concat("fabric:/", mappedAppName, "/", SvcName)); var outUri = await GetListeningAddressForWebUxSvc(routingContext, inTenantAsFabricAppSvcName); // get service host name from listening address (either nodename or nodename:port var outHostName = string.Concat(outUri.Host, !outUri.IsDefaultPort ? string.Concat(":", outUri.Port.ToString()) : string.Empty); // setup routing context routingContext.TargetHostAddressList.Clear(); routingContext.TargetHostAddressList.Add(outHostName); routingContext.RouteExecuteType = ContextRoutingType.Single; // so if you generated long listening addresses from your replicas this should work // get listening address which might be something like http://node:port/path/ // append to it orignal path of the request. httpCtx.OverridePath = true; httpCtx.Path = string.Concat(outUri.AbsolutePath, inPathQueryString); return(true); }
public override Task <ContextExecuteModeBase> ExecuteStrategyAsync(int CallCount, RoutingContextBase re, AggregateException ae) { if (string.IsNullOrEmpty(TargetHostAddress)) { throw new InvalidOperationException("Target host is null or empty"); } // apply strategy var httpCtx = re as HttpRoutingContext; if (null == httpCtx) { throw new InvalidOperationException("Route to host only supports Http Routing Contexts"); } // clear all address httpCtx.TargetHostAddressList.Clear(); // route to my host httpCtx.TargetHostAddressList.Add(TargetHostAddress); httpCtx.RouteExecuteType = ContextRoutingType.Single; return(Task.FromResult((ContextExecuteModeBase) new RetryMode())); }