microshed-testing icon indicating copy to clipboard operation
microshed-testing copied to clipboard

Would like the ability to calculate a base path from a JAX-RS Application type in a specific package, unrelated to @RESTClient type

Open scottkurz opened this issue 5 years ago • 4 comments
trafficstars

I'd like to be able to use:

@RESTClient
public static StarterResource appService;

but to use an Application from some other package.

import javax.ws.rs.core.Application;

@ApplicationPath("/api")
public class StarterApplication extends Application {

At the moment, MST will start from the Resource class and look for an Application in the same package, (understandably not wanting to scan the whole classloader tree).

Interested to hear ideas here on how this could fit into MST config or extension.

This basic mapping strikes me as maybe one that could have come up in other JAX-RS-related contexts, but admit I haven't done much resource to see if there's something already to build off of (completely separate from MST).

scottkurz avatar Oct 10 '20 01:10 scottkurz

hi @scottkurz, I'm not quite clear on what you're referring to as an "application from some other package"?

Do you mean that you have a resource class like com.foo.StarterResource and the JAX-RS Application class is from a different package like org.bar.MyApplication?

aguibert avatar Oct 12 '20 16:10 aguibert

hi @scottkurz, I'm not quite clear on what you're referring to as an "application from some other package"?

Do you mean that you have a resource class like com.foo.StarterResource and the JAX-RS Application class is from a different package like org.bar.MyApplication?

That's right. I was referring to the introspection done by RestClientBuilder.locateApplicationPath()

scottkurz avatar Oct 12 '20 16:10 scottkurz

Ok, I understand the scenario now thanks. A few questions now:

  1. What packages were being used in your case?
  2. Did you get a clear error message when this didn't work? Or did it take a while to figure out that the package scanning wasn't working?

Currently a heuristic is used where the first 3 packages of the resource class will be scanned. So suppose you had com.foo.app.fourth.fifth.sixth.MyResource. We would scan for an Application in the com.foo.app.* package domain. I chose this because usually the first 3 packages are in the format <COM|ORG|etc>.<COMPANY_NAME>.<PROJECT_NAME>. Would relaxing this a bit to the first 2 packages (i.e. scan com.foo.*) solve the problem in your case?

Ultimately the auto-package scanning is a heuristic, so currently the backup way is to use RestClientBuilder. Would it be helpful if we added an optional applicationPath attribute to the @RESTClient annotation? Using the original example you could do something like:

@RESTClient(applicationPath = "/api") // since @ApplicationPath cannot be auto-detected from pkg scanning
public static StarterResource appService;

or, we could roll the entire path into a single (more generic) annotation attribute:

@RESTClient(path = "/api/starter")
public static StarterResource appService;

aguibert avatar Oct 12 '20 21:10 aguibert

I would say the error msg was reasonably clear. It didn't completely jump out at me but wasn't hard to see looking over it a couple times:

2822 DEBUG org.microshed.testing.jupiter.MicroShedTestExtension - Regsitered JSONB ObjectMapper for REST Assured 2841 DEBUG org.microshed.testing.jaxrs.RestClientBuilder - no classes implementing Application found in pkg: dev.odo.sample 2841 INFO org.microshed.testing.jaxrs.RestClientBuilder - No classes implementing 'javax.ws.rs.core.Application' found on classpath to set as context root for class dev.odo.sample.SampleResource. Defaulting context root to '/' 2939 INFO org.microshed.testing.jaxrs.RestClientBuilder - Building rest client for class dev.odo.sample.SampleResource with base path: http://asi3-5fbcf8d6b8-t28d9:9080/ and providers: [class org.microshed.testing.jaxrs.JsonBProvider] 3311 DEBUG org.microshed.testing.jupiter.MicroShedTestExtension - Injected rest client for public static dev.odo.sample.SampleResource dev.odo.sample.EndpointIT.appService 3332 INFO dev.odo.sample.EndpointIT - In test method: testAppResponse [INFO] [WARNING ] SRVE0190E: File not found: /resource

My use case has the Application "pre-generated" from the application stack starter (at https://github.com/OpenLiberty/application-stack-starters). This is kind of primitive compared to many starters since the package name isn't customizable. So I always get dev.odo.starter.StarterApplication as my Application but I might want to develop my resources in another package name, e.g. I use dev.odo.sample.SampleResource here.

I'm just looking for something simple-looking and transparent to use with the starter, for people to learn without frustration in simple, getting started apps. Just for this use case it doesn't seem worth engineering too complex a solution.

It seems like:

@RESTClient(applicationPath = "/api") // since @ApplicationPath cannot be auto-detected from pkg scanning
public static StarterResource appService;

could be a simple solution which in a simple sample would be easy to understand to see how the client/server paths align.

scottkurz avatar Oct 12 '20 22:10 scottkurz