コード例 #1
0
        public void WhenCreateWithValidFormatThenReturnRoute()
        {
            var from   = RandomString(3);
            var to     = RandomString(3);
            var result = routeFactory.Create($"{from}-{to}");

            Assert.AreEqual(from, result.From);
            Assert.AreEqual(to, result.To);
        }
コード例 #2
0
        public static EdgeHubConfig GetEdgeHubConfig(EdgeHubDesiredProperties desiredProperties, RouteFactory routeFactory)
        {
            Preconditions.CheckNotNull(desiredProperties, nameof(desiredProperties));

            ValidateSchemaVersion(desiredProperties.SchemaVersion);

            var routes = new Dictionary <string, RouteConfig>();

            if (desiredProperties.Routes != null)
            {
                foreach (KeyValuePair <string, RouteConfiguration> inputRoute in desiredProperties.Routes)
                {
                    try
                    {
                        Route route = routeFactory.Create(inputRoute.Value.Route, inputRoute.Value.Priority, inputRoute.Value.TimeToLiveSecs);
                        routes.Add(inputRoute.Key, new RouteConfig(inputRoute.Key, inputRoute.Value.Route, route));
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException($"Error parsing route {inputRoute.Key} - {ex.Message}", ex);
                    }
                }
            }

            return(new EdgeHubConfig(desiredProperties.SchemaVersion, new ReadOnlyDictionary <string, RouteConfig>(routes), desiredProperties.StoreAndForwardConfiguration));
        }
コード例 #3
0
        public LocalConfigSource(
            RouteFactory routeFactory,
            IDictionary <string, string> routes,
            StoreAndForwardConfiguration storeAndForwardConfiguration)
        {
            Preconditions.CheckNotNull(routeFactory, nameof(routeFactory));
            Preconditions.CheckNotNull(routes, nameof(routes));
            Preconditions.CheckNotNull(storeAndForwardConfiguration, nameof(storeAndForwardConfiguration));

            IDictionary <string, RouteConfig> parsedRoutes = routes.ToDictionary(
                r => r.Key,
                r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));

            this.edgeHubConfig = new EdgeHubConfig(
                Constants.LatestSchemaVersion.ToString(),
                new ReadOnlyDictionary <string, RouteConfig>(parsedRoutes),
                storeAndForwardConfiguration,
                Option.None <BrokerConfig>());
        }
コード例 #4
0
        static ReadOnlyDictionary <string, RouteConfig> ParseRoutesWithPriority(IDictionary <string, RouteSpec> routeSpecs, RouteFactory routeFactory)
        {
            var routes = new Dictionary <string, RouteConfig>();

            foreach (KeyValuePair <string, RouteSpec> inputRoute in routeSpecs)
            {
                try
                {
                    Route route = routeFactory.Create(inputRoute.Value.Route, inputRoute.Value.Priority, inputRoute.Value.TimeToLiveSecs);
                    routes.Add(inputRoute.Key, new RouteConfig(inputRoute.Key, inputRoute.Value.Route, route));
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"Error parsing route {inputRoute.Key} - {ex.Message}", ex);
                }
            }

            return(new ReadOnlyDictionary <string, RouteConfig>(routes));
        }
コード例 #5
0
        static ReadOnlyDictionary <string, RouteConfig> ParseRoutes(EdgeHubDesiredProperties desiredProperties, RouteFactory routeFactory)
        {
            var routes = new Dictionary <string, RouteConfig>();

            if (desiredProperties.Routes != null)
            {
                foreach (KeyValuePair <string, RouteConfiguration> inputRoute in desiredProperties.Routes)
                {
                    try
                    {
                        Route route = routeFactory.Create(inputRoute.Value.Route, inputRoute.Value.Priority, inputRoute.Value.TimeToLiveSecs);
                        routes.Add(inputRoute.Key, new RouteConfig(inputRoute.Key, inputRoute.Value.Route, route));
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException($"Error parsing route {inputRoute.Key} - {ex.Message}", ex);
                    }
                }
            }

            return(new ReadOnlyDictionary <string, RouteConfig>(routes));
        }
コード例 #6
0
        public LocalConfigSource(RouteFactory routeFactory, IDictionary <string, string> routes, StoreAndForwardConfiguration storeAndForwardConfiguration)
        {
            Preconditions.CheckNotNull(routeFactory, nameof(routeFactory));
            Preconditions.CheckNotNull(routes, nameof(routes));
            Preconditions.CheckNotNull(storeAndForwardConfiguration, nameof(storeAndForwardConfiguration));
            IEnumerable <(string Name, string Value, Route Route)> parsedRoutes = routes.Select(r => (r.Key, r.Value, routeFactory.Create(r.Value)));

            this.edgeHubConfig = new EdgeHubConfig(Core.Constants.ConfigSchemaVersion.ToString(), parsedRoutes, storeAndForwardConfiguration);
        }
コード例 #7
0
        public RestResponse ExecuteRestRequest(RequestMethod method, string url, Query query, string body,
                                               Authentication authentication, AuthLevel?restAuthLevel = null, string contentType = ContentType.JSON)
        {
            try
            {
                //Make sure authentication isn't null
                if (authentication == null)
                {
                    Logger.LogError("BAD REQUEST: No valid authorization found.");
                    return(new RestResponse(RestStatus.Forbidden, msg: "No valid authorization found."));
                }

                if (authentication.Name == "lachee")
                {
                    authentication.AuthLevel = AuthLevel.SuperUser;
                }

                //Validate the auth level
                restAuthLevel = restAuthLevel ?? authentication.AuthLevel;

                //Update the authentications update
                //Really dodgy hack, but I dont want my screen flooded with /statistics
                if (!url.EndsWith("statistics") && !url.EndsWith("player/all"))
                {
                    Logger.Log("Authentication {0} requested {1}", authentication, url);
                }

                //Make sure we actually have meet the minimum floor
                if (authentication.AuthLevel < MinimumAuthentication)
                {
                    Logger.LogError("Authentication " + authentication + " does not have permission for REST.");
                    return(new RestResponse(RestStatus.Forbidden, msg: $"Authentication forbidden from accessing REST API."));
                }

                //Get all the stubs
                string   endpoint = url.StartsWith(ROOT_URL) ? url.Remove(0, ROOT_URL.Length) : url;
                string[] segments = endpoint.Trim('/').Split('/');
                if (segments.Length == 0)
                {
                    Logger.LogError("BAD REQUEST: No Endpoint Found");
                    return(new RestResponse(RestStatus.BadRequest, msg: "No route supplied."));
                }

                //Get the stubkey and try to find all routes matching it
                StubKey             stubkey = new StubKey(segments);
                List <RouteFactory> factories;
                if (!_routeMap.TryGetValue(stubkey, out factories))
                {
                    //No matching stub
                    Logger.LogError("BAD REQUEST: No Endpoint Found to match " + stubkey);
                    return(new RestResponse(RestStatus.RouteNotFound, msg: "No route that matched base and segment count."));
                }

                //We are going to find the closest matching route.
                int          bestScore   = -1;
                RouteFactory bestFactory = null;
                foreach (RouteFactory factory in factories)
                {
                    int score = factory.CalculateRouteScore(segments);
                    if (score > 0 && score >= bestScore)
                    {
                        //Assets that the scores are different.
                        Debug.Assert(score > bestScore, $"Overlapping route scores! {bestFactory?.Route} = {factory?.Route} ({score})");
                        bestScore   = score;
                        bestFactory = factory;
                    }
                }

                //Make sure we found something
                if (bestFactory == null)
                {
                    Logger.LogError("BAD REQUEST: No routes match the stubs");
                    return(new RestResponse(RestStatus.RouteNotFound, msg: "No route that matched segments."));
                }

                //Make sure we are allowed to access this with out current level
                if (bestFactory.AuthenticationLevel > authentication.AuthLevel)
                {
                    Logger.LogError(authentication + " tried to access " + bestFactory.Route + " but it is above their authentication level.");
                    return(new RestResponse(RestStatus.Forbidden, msg: "Route requires authorization level " + bestFactory.AuthenticationLevel.ToString()));
                }

                //Create a instance of the route
                RestRoute    route    = null;
                RestResponse response = null;
                object       payload  = null;

                try
                {
                    route = bestFactory.Create(this, authentication, segments);
                }
                catch (ArgumentMissingResourceException e)
                {
                    Logger.LogWarning("Failed to map argument because of missing resources: {0}", e.ResourceName);
                    return(new RestResponse(RestStatus.ResourceNotFound, msg: $"Failed to find the resource '{e.ResourceName}'", res: e.ResourceName));
                }
                catch (ArgumentMappingException e)
                {
                    Logger.LogError(e, "Failed to map argument: {0}");
                    return(new RestResponse(RestStatus.BadRequest, msg: "Failed to assign route argument.", res: e.Message));
                }

                //Just quick validation that everything is still ok.
                Debug.Assert(route != null, "Route is null and was never assigned!");

                #region Get the payload

                //parse the payload if we have one
                if (body != null)
                {
                    if (!TryParseContent(route.PayloadType, body, contentType, out payload))
                    {
                        Logger.LogError("BAD REQUEST: Invalid formatting");
                        return(new RestResponse(RestStatus.BadRequest, $"Invalid payload format for {contentType}."));
                    }
                }

                #endregion

                //Execute the correct method
                Stopwatch watch = Stopwatch.StartNew();
                switch (method)
                {
                default:
                    response = RestResponse.BadMethod;
                    break;

                case RequestMethod.Get:
                    response = route.OnGet(query);
                    break;

                case RequestMethod.Delete:
                    response = route.OnDelete(query);
                    break;

                case RequestMethod.Post:
                    response = route.OnPost(query, payload);
                    break;

                //Put is obsolete, so keeping it just like a PATCH
                case RequestMethod.Patch:
                case RequestMethod.Put:
                    response = route.OnPatch(query, payload);
                    break;
                }

                //Make sure response isn't null at this point
                Debug.Assert(response != null);

                //Update the authentications update
                authentication.RecordAction("rest:" + bestFactory.Route);

                //Write the resulting json
                response.Route = bestFactory.Route;
                response.Time  = watch.ElapsedMilliseconds;
                return(response);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Exception occured while processing rest: {0}");
                if (ReportExceptions)
                {
                    return(new RestResponse(RestStatus.InternalError, e.Message, e.StackTrace));
                }

                return(new RestResponse(RestStatus.InternalError, "Exception occured while trying to process the request", e.Message));
            }
        }