public void Constructor_InitializesWithDefaults()
        {
            var opts = new ThreadDumpEndpointOptions();

            Assert.Null(opts.Enabled);
            Assert.Equal("dump", opts.Id);
        }
        public void Constructor_BindsConfigurationCorrectly()
        {
            var appsettings = new Dictionary <string, string>()
            {
                ["management:endpoints:enabled"]         = "false",
                ["management:endpoints:loggers:enabled"] = "false",
                ["management:endpoints:dump:enabled"]    = "true",
                ["management:endpoints:cloudfoundry:validatecertificates"] = "true",
                ["management:endpoints:cloudfoundry:enabled"] = "true"
            };
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            configurationBuilder.AddInMemoryCollection(appsettings);
            var config = configurationBuilder.Build();

            var opts      = new ThreadDumpEndpointOptions(config);
            var cloudOpts = new CloudFoundryEndpointOptions(config);
            var ep        = new ThreadDumpEndpoint(opts, new ThreadDumper(opts));

            Assert.True(cloudOpts.Enabled);
            Assert.Equal(string.Empty, cloudOpts.Id);
            Assert.Equal(string.Empty, cloudOpts.Path);
            Assert.True(cloudOpts.ValidateCertificates);

            Assert.True(opts.Enabled);
            Assert.Equal("dump", opts.Id);
            Assert.Equal("dump", opts.Path);

            Assert.True(ep.Enabled);
        }
        /// <summary>
        /// Add Thread Dump actuator endpoint to OWIN Pipeline
        /// </summary>
        /// <param name="builder">OWIN <see cref="IAppBuilder" /></param>
        /// <param name="config"><see cref="IConfiguration"/> of application for configuring thread dump endpoint</param>
        /// <param name="loggerFactory">For logging within the middleware</param>
        /// <param name="version">MediaTypeVersion for endpoint response</param>
        /// <returns>OWIN <see cref="IAppBuilder" /> with Thread Dump Endpoint added</returns>
        public static IAppBuilder UseThreadDumpActuator(this IAppBuilder builder, IConfiguration config, ILoggerFactory loggerFactory, MediaTypeVersion version)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            var options = new ThreadDumpEndpointOptions(config);

            if (version == MediaTypeVersion.V2 && options.Id == "dump")
            {
                options.Id = "threaddump";
            }

            var mgmtOptions = ManagementOptions.Get(config);

            foreach (var mgmt in mgmtOptions)
            {
                mgmt.EndpointOptions.Add(options);
            }

            var threadDumper = new ThreadDumper(options, loggerFactory?.CreateLogger <ThreadDumper>());

            return(builder.UseThreadDumpActuator(options, threadDumper, loggerFactory, version));
        }
Ejemplo n.º 4
0
        public void ThreadDumpEndpointMiddleware_PathAndVerbMatching_ReturnsExpected()
        {
            var actOptions = new ActuatorManagementOptions()
            {
                Path     = "/",
                Exposure = new Exposure {
                    Include = new List <string> {
                        "*"
                    }
                }
            };

            var opts = new ThreadDumpEndpointOptions();

            actOptions.EndpointOptions.Add(opts);
            ThreadDumper obs    = new ThreadDumper(opts);
            var          ep     = new ThreadDumpEndpoint(opts, obs);
            var          middle = new ThreadDumpEndpointMiddleware(null, ep, new List <IManagementOptions> {
                actOptions
            });

            Assert.True(middle.RequestVerbAndPathMatch("GET", "/dump"));
            Assert.False(middle.RequestVerbAndPathMatch("PUT", "/dump"));
            Assert.False(middle.RequestVerbAndPathMatch("GET", "/badpath"));
        }
Ejemplo n.º 5
0
        public static void UseThreadDumpActuator(IConfiguration configuration, MediaTypeVersion version, IThreadDumper threadDumper = null, ILoggerFactory loggerFactory = null)
        {
            var options = new ThreadDumpEndpointOptions(configuration);

            if (version == MediaTypeVersion.V2 && options.Id == "dump")
            {
                options.Id = "threaddump";
            }

            _mgmtOptions.RegisterEndpointOptions(configuration, options);
            threadDumper = threadDumper ?? new ThreadDumper(options);
            IActuatorHandler handler;

            switch (version)
            {
            case MediaTypeVersion.V1:
                var ep = new ThreadDumpEndpoint(options, threadDumper, CreateLogger <ThreadDumpEndpoint>(loggerFactory));
                handler = new ThreadDumpHandler(ep, SecurityServices, _mgmtOptions, CreateLogger <ThreadDumpHandler>(loggerFactory));
                break;

            default:
                var ep2 = new ThreadDumpEndpoint_v2(options, threadDumper, CreateLogger <ThreadDumpEndpoint_v2>(loggerFactory));
                handler = new ThreadDumpHandler_v2(ep2, SecurityServices, _mgmtOptions, CreateLogger <ThreadDumpHandler_v2>(loggerFactory));
                break;
            }

            ConfiguredHandlers.Add(handler);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Adds the services used by the Thread Dump actuator
        /// </summary>
        /// <param name="services">Reference to the service collection</param>
        /// <param name="configuration">Reference to the configuration system</param>
        /// <param name="version">The media version to use</param>
        /// <returns>A reference to the service collection</returns>
        public static IServiceCollection AddThreadDumpActuatorServices(this IServiceCollection services, IConfiguration configuration, MediaTypeVersion version)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var options = new ThreadDumpEndpointOptions(configuration);

            if (version == MediaTypeVersion.V1)
            {
                services.TryAddSingleton <ThreadDumpEndpoint>();
            }
            else
            {
                if (options.Id == "dump")
                {
                    options.Id = "threaddump";
                }

                services.TryAddSingleton <ThreadDumpEndpoint_v2>();
            }

            services.TryAddSingleton <IThreadDumpOptions>(options);
            services.TryAddSingleton <IThreadDumper, ThreadDumper>();
            services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IEndpointOptions), options));

            return(services);
        }
        public void UseThreadDumpActuator_ThrowsIfDumperNull()
        {
            IAppBuilder builder   = new AppBuilder();
            var         config    = new ConfigurationBuilder().Build();
            var         options   = new ThreadDumpEndpointOptions(config);
            var         exception = Assert.Throws <ArgumentNullException>(() => builder.UseThreadDumpActuator(options, null));

            Assert.Equal("threadDumper", exception.ParamName);
        }
Ejemplo n.º 8
0
        public void RoutesByPathAndVerb()
        {
            var options = new ThreadDumpEndpointOptions();

            Assert.True(options.ExactMatch);
            Assert.Equal("/actuator/dump", options.GetContextPath(new ActuatorManagementOptions()));
            Assert.Equal("/cloudfoundryapplication/dump", options.GetContextPath(new CloudFoundryManagementOptions()));
            Assert.Null(options.AllowedVerbs);
        }
Ejemplo n.º 9
0
        public void ThreadDumpEndpointMiddleware_PathAndVerbMatching_ReturnsExpected()
        {
            var          opts        = new ThreadDumpEndpointOptions();
            var          mgmtOptions = TestHelpers.GetManagementOptions(opts);
            ThreadDumper obs         = new ThreadDumper(opts);
            var          ep          = new ThreadDumpEndpoint(opts, obs);
            var          middle      = new EndpointOwinMiddleware <List <ThreadInfo> >(null, ep, mgmtOptions);

            Assert.True(middle.RequestVerbAndPathMatch("GET", "/cloudfoundryapplication/dump"));
            Assert.False(middle.RequestVerbAndPathMatch("PUT", "/cloudfoundryapplication/dump"));
            Assert.False(middle.RequestVerbAndPathMatch("GET", "/cloudfoundryapplication/badpath"));
        }
Ejemplo n.º 10
0
        public static void RegisterThreadDumpActuator(this ContainerBuilder container, IConfiguration config, MediaTypeVersion version)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            container.RegisterType <ThreadDumper>().As <IThreadDumper>().SingleInstance();
            container.Register(c =>
            {
                var options = new ThreadDumpEndpointOptions(config);
                if (options.Id == "dump" && version == MediaTypeVersion.V2)
                {
                    options.Id = "threaddump";
                }
                var mgmtOptions = c.Resolve <IEnumerable <IManagementOptions> >();
                foreach (var mgmt in mgmtOptions)
                {
                    mgmt.EndpointOptions.Add(options);
                }
                return(options);
            }).As <IThreadDumpOptions>().IfNotRegistered(typeof(IThreadDumpOptions));

            if (version == MediaTypeVersion.V1)
            {
                container.RegisterType <ThreadDumpEndpoint>().As <IEndpoint <List <ThreadInfo> > >().SingleInstance();

                container.RegisterType <EndpointOwinMiddleware <List <ThreadInfo> > >().SingleInstance();
            }
            else
            {
                container.RegisterType <ThreadDumpEndpoint_v2>().As <IEndpoint <ThreadDumpResult> >().SingleInstance();

                container.RegisterType <EndpointOwinMiddleware <ThreadDumpResult> >().SingleInstance();
            }
        }
Ejemplo n.º 11
0
        public async void HandleThreadDumpRequestAsync_ReturnsExpected()
        {
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                var opts  = new ThreadDumpEndpointOptions();
                var mopts = TestHelper.GetManagementOptions(opts);

                ThreadDumper obs     = new ThreadDumper(opts);
                var          ep      = new ThreadDumpEndpoint(opts, obs);
                var          middle  = new ThreadDumpEndpointMiddleware(null, ep, mopts);
                var          context = CreateRequest("GET", "/dump");
                await middle.HandleThreadDumpRequestAsync(context);

                context.Response.Body.Seek(0, SeekOrigin.Begin);
                StreamReader rdr  = new StreamReader(context.Response.Body);
                string       json = await rdr.ReadToEndAsync();

                Assert.StartsWith("[", json);
                Assert.EndsWith("]", json);
            }
        }
Ejemplo n.º 12
0
        public async void ThreadDumpInvoke_ReturnsExpected()
        {
            // arrange
            var opts        = new ThreadDumpEndpointOptions();
            var mgmtOptions = TestHelpers.GetManagementOptions(opts);
            var middle      = new EndpointOwinMiddleware <List <ThreadInfo> >(null, new ThreadDumpEndpoint(opts, new ThreadDumper(opts)), mgmtOptions);
            var context     = OwinTestHelpers.CreateRequest("GET", "/cloudfoundryapplication/dump");

            // act
            var json = await middle.InvokeAndReadResponse(context);

            // assert (that it looks kinda like what we expect... ?)
            Assert.StartsWith("[", json);
            Assert.Contains("blockedCount", json);
            Assert.Contains("blockedTime", json);
            Assert.Contains("lockedMonitors", json);
            Assert.Contains("lockedSynchronizers", json);
            Assert.Contains("lockInfo", json);
            Assert.Contains("stackTrace", json);
            Assert.EndsWith("]", json);
        }
Ejemplo n.º 13
0
        public async void HandleThreadDumpRequestAsync_ReturnsExpected()
        {
            if (Platform.IsWindows)
            {
                var opts = new ThreadDumpEndpointOptions();

                var mgmtOptions = new ActuatorManagementOptions();
                mgmtOptions.EndpointOptions.Add(opts);

                ThreadDumper obs     = new ThreadDumper(opts);
                var          ep      = new ThreadDumpEndpoint(opts, obs);
                var          middle  = new ThreadDumpEndpointMiddleware(null, ep, mgmtOptions);
                var          context = CreateRequest("GET", "/dump");
                await middle.HandleThreadDumpRequestAsync(context);

                context.Response.Body.Seek(0, SeekOrigin.Begin);
                var rdr  = new StreamReader(context.Response.Body);
                var json = await rdr.ReadToEndAsync();

                Assert.StartsWith("[", json);
                Assert.EndsWith("]", json);
            }
        }