Skip to content

Add ability to define custom paths in actuator endpoints #10339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nicolaferraro opened this issue Sep 19, 2017 · 15 comments
Closed

Add ability to define custom paths in actuator endpoints #10339

nicolaferraro opened this issue Sep 19, 2017 · 15 comments

Comments

@nicolaferraro
Copy link

The new actuator abstraction allows to define dynamic endpoints using the @Selector annotation, but it doesn't offer any help when you want to define e.g. multiple types of operation on the same resource.

For example, we (Apache Camel) have some actuator endpoints in v. 1.5.x that define write operations on the following paths:

/{id}/suspend
/{id}/resume
/{id}/reset
... and many others

Where {id} is a route id on a specific actuator endpoint.

If we want to replicate the same behavior on v2.x we need to define a method like:

@WriteOperation
public Object doSomething(@Selector String routeId, @Selector String action) {
  if (...) {
    // here switch on the action to call another method
  }
}

Looking at the code that determines the path, this is the best I can do to replicate the same behavior that was present in 1.5.x.

Can this be improved before RC?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 19, 2017
@wilkinsona
Copy link
Member

My gut feeling is that what you had in 1.5.x wasn't really an endpoint and was really a MVC controller in disguise. We've deliberately constrained the programming model in 2.0 so that it's no longer possible to create this sort of endpoint. This allows us to easily map operations to MVC, WebFlux, Jersey and JMX.

In the case of your endpoints in 1.5, how were you dealing with the JMX side of things?

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Sep 19, 2017
@nicolaferraro
Copy link
Author

We have an internal binding to JMX, so we were not using actuator for that. We were using the EndpointMvcAdapter to map operations to web endpoints using actuator.

I see that the method name is used in the JMX binding to distinguish between operations, in fact, for a single @Endpoint <-> MBean you can define multiple @WriteOperation <-> @ManagedOperation.

But the method name is ignored in the web binding, so the following Endpoint:

@WriteOperation
public Object action1() {
  // something
}

@WriteOperation
public Object action2() {
  // something
}

... has a JMX binding in Spring-boot 2 but not a web binding, since both operations have the same path.
I might be wrong since I'm not able to test it in this moment.

So, there should be some way to declare multiple @WriteOperation / @ReadOperation in the same class without having to write a generic method as in my first comment.

A possible solution may be to use the method name or an attribute of @Write/ReadOperation to determine the full path. And it should be also possible to define a web endpoint without sub-path.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 19, 2017
@wilkinsona
Copy link
Member

wilkinsona commented Sep 19, 2017

The endpoint you've shown is illegal as two operations will have the same request predicate. It should fail at runtime for that reason.

What you've described (using EndpointMvcAdapter for a custom web endpoint and something else entirely for the JMX side of things) is exactly the type of usage that we deliberately want to avoid in 2.0 as it's not really an endpoint. What you had was really a Spring MVC controller pretending to be an endpoint. If you need to features of a Spring MVC controller, then you should write a Spring MVC controller (and deal with WebFlux and Jersey as well if they are of interest to Camel users).

Other than a few exceptions (such as controlling the HTTP response code) everything in the endpoint infrastructure has to be applicable to both web endpoints and JMX endpoints. I'm happy to continue discussing this and seeing if there's anything we can do to help, but anything we do will have to be within those constraints.

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Sep 19, 2017
@spencergibb
Copy link
Member

It's still useful for the security side. See #10264.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 19, 2017
@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Sep 19, 2017
@wilkinsona
Copy link
Member

@spencergibb There's quite a lot of discussion above your comment so I'm not sure what "it" you are referring to. Can you explain in a little more detail please?

@spencergibb
Copy link
Member

Yeah, sorry. "It" being the @ConditionalOnEndpointEnabled.

@wilkinsona
Copy link
Member

@spencergibb I can't see any other mention of the condition in this issue. Did you mean to comment elsewhere? If not, can we please try to keep this issue focussed on the topic raised by @nicolaferraro which is already rather broad.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 19, 2017
@nicolaferraro
Copy link
Author

Well, the problem I'm raising has little to do with rest or JMX mapping. I'd like to see if there's room for improvement for the current definition of actuator endpoints.

Given the current implementation, if I want to create a "controlled object" with 4 operations named "start", "stop", "pause" and "resume", I have the following options:

  • Define a @Endpoint with a single @WriteOperation receiving a String parameter annotated with @Selector, then put a switch on the string to check if it's "start", "stop", "pause" or "resume" and call another method
  • Define 4 @Endpoint's classes, each one with a single @WriteOperation. I can use the same prefix in the id to signal that these 4 endpoints are related

The first solution is ok for me, I was just trying to suggest something better for this use case (i.e. allow to write multiple methods/operations on the same bean/endpoint without having to play with string switch).

@wilkinsona
Copy link
Member

I wouldn't model that as four different operations. IMO, that's a single operation for writing the controlled object's state. In a web API you'd make a POST request that includes the resources desired state. For example to start the object, you'd post STARTED and to pause the object you'd post PAUSED. I'd use an enum to model the states.

If what I've described above can't be modelled with the current endpoint infrastructure then I'd be interested in exploring if we can fix that. If you want to do something that's more web-specific and uses more of Spring MVC's features then you should write a Spring MVC controller.

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Sep 19, 2017
@dsyer
Copy link
Member

dsyer commented Sep 19, 2017

As I understand it the current model allows you to accept a single argument of type String or enum. So that might be fine for the lifecycle use case above. It doesn't help with anything more generic though. It would help us a lot if we could POST a Map (also completely generic and easy to map to JSON or JMX). Dispatching within an endpoint is fine (so a single entry point), as long as the parameters are more flexible.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 19, 2017
@wilkinsona
Copy link
Member

You can POST multiple arguments. Anything without a @Selector is expected to be found in a JSON request body with the name of the method parameter mapping to a key in the JSON. @dsyer do you have a use case where the keys in a JSON request body can't be predicted and you just need the whole thing?

also completely generic and easy to map to JSON or JMX

I'm not sure that a map is particularly JMX-friendly, not with JConsole anyway

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Sep 19, 2017
@dsyer
Copy link
Member

dsyer commented Sep 19, 2017

Let's say you want to add some k-v pairs to a PropertySource in the Environment. With the current design, my understanding is I'd have to use a @WriteOperation with 2 args. one for the key and one for the value, and then call it several times. It's what we have in JMX in Spring Cloud where we need it already actually, but it's not very efficient. Feels like batching them together would have been better. However, I guess I take the point about JConsole. I don't think it allows you to do input parameters that aren't primitive or String.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 19, 2017
@spencergibb
Copy link
Member

Also see #10257

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Sep 22, 2017
@spring-projects-issues
Copy link
Collaborator

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Sep 29, 2017
@spring-projects-issues
Copy link
Collaborator

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

@spring-projects-issues spring-projects-issues removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged labels Oct 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants